/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifdef _MSC_VER
#pragma hdrstop
#endif

#include <hintids.hxx>

#include <tools/stream.hxx>
#ifndef _SVSTDARR_HXX
#define _SVSTDARR_USHORTS
#endif

#include <pam.hxx>

#include <horiornt.hxx>

#include <doc.hxx>
#include <ndtxt.hxx>
#include <wrtasc.hxx>
#include <txtfld.hxx>
#include <fmtftn.hxx>
#include <fmtfld.hxx>
#include <fldbas.hxx>
#include <ftninfo.hxx>
namespace binfilter {

/*
 * Dieses File enthaelt alle Ausgabe-Funktionen des ASCII-Writers;
 * fuer alle Nodes, Attribute, Formate und Chars.
 */

class SwASC_AttrIter
{
    SwASCWriter& rWrt;
    const SwTxtNode& rNd;
    xub_StrLen nAktSwPos;

    xub_StrLen SearchNext( xub_StrLen nStartPos );

public:
    SwASC_AttrIter( SwASCWriter& rWrt, const SwTxtNode& rNd, xub_StrLen nStt );

    void NextPos()      { nAktSwPos = SearchNext( nAktSwPos + 1 ); }

    xub_StrLen WhereNext() const        { return nAktSwPos; }
    BOOL OutAttr( xub_StrLen nSwPos );
};


/*N*/ SwASC_AttrIter::SwASC_AttrIter( SwASCWriter& rWr, const SwTxtNode& rTxtNd,
/*N*/                               xub_StrLen nStt )
/*N*/   : rWrt( rWr ), rNd( rTxtNd ), nAktSwPos( 0 )
/*N*/ {
/*N*/   nAktSwPos = SearchNext( nStt + 1 );
/*N*/ }


/*N*/ xub_StrLen SwASC_AttrIter::SearchNext( xub_StrLen nStartPos )
/*N*/ {
/*N*/   register xub_StrLen nMinPos = STRING_MAXLEN;
/*N*/   const SwpHints* pTxtAttrs = rNd.GetpSwpHints();
/*N*/   if( pTxtAttrs )
/*N*/   {
/*?*/       register USHORT i;
/*?*/       register xub_StrLen nPos;
/*?*/       const xub_StrLen * pPos;
/*?*/
/*?*/ // kann noch optimiert werden, wenn ausgenutzt wird, dass die TxtAttrs
/*?*/ // nach der Anfangsposition geordnet sind. Dann muessten
/*?*/ // allerdings noch 2 Indices gemerkt werden
/*?*/       for( i = 0; i < pTxtAttrs->Count(); i++ )
/*?*/       {
/*?*/           const SwTxtAttr* pHt = (*pTxtAttrs)[i];
/*?*/           nPos = *pHt->GetStart();    // gibt erstes Attr-Zeichen
/*?*/           pPos = pHt->GetEnd();
/*?*/           if( !pPos )
/*?*/           {
/*?*/               if( nPos >= nStartPos && nPos <= nMinPos )
/*?*/                   nMinPos = nPos;
/*?*/
/*?*/               if( ( ++nPos ) >= nStartPos && nPos < nMinPos )
/*?*/                   nMinPos = nPos;
/*?*/           }
/*?*/       }
/*N*/   }
/*N*/   return nMinPos;
/*N*/ }


/*N*/ BOOL SwASC_AttrIter::OutAttr( xub_StrLen nSwPos )
/*N*/ {
/*N*/   BOOL bRet = FALSE;
/*N*/   const SwpHints* pTxtAttrs = rNd.GetpSwpHints();
/*N*/   if( pTxtAttrs )
/*N*/   {
/*?*/       register USHORT i;
/*?*/       for( i = 0; i < pTxtAttrs->Count(); i++ )
/*?*/       {
/*?*/           const SwTxtAttr* pHt = (*pTxtAttrs)[i];
/*?*/           const xub_StrLen * pEnd = pHt->GetEnd();
/*?*/           if( !pEnd && nSwPos == *pHt->GetStart() )
/*?*/           {
/*?*/               bRet = TRUE;
/*?*/               String sOut;
/*?*/               switch( pHt->Which() )
/*?*/               {
/*?*/               case RES_TXTATR_FIELD:
/*?*/                   sOut = ((SwTxtFld*)pHt)->GetFld().GetFld()->Expand();
/*?*/                   break;
/*?*/
/*?*/               case RES_TXTATR_HARDBLANK:
                        {DBG_BF_ASSERT(0, "STRIP");}
/*?*/                   break;
/*?*/
/*?*/               case RES_TXTATR_FTN:
/*?*/                   {
/*?*/                       const SwFmtFtn& rFtn = pHt->GetFtn();
/*?*/                       if( rFtn.GetNumStr().Len() )
/*?*/                           sOut = rFtn.GetNumStr();
/*?*/                       else if( rFtn.IsEndNote() )
/*?*/                           sOut = rWrt.pDoc->GetEndNoteInfo().aFmt.
/*?*/                                           GetNumStr( rFtn.GetNumber() );
/*?*/                       else
/*?*/                           sOut = rWrt.pDoc->GetFtnInfo().aFmt.
/*?*/                                           GetNumStr( rFtn.GetNumber() );
/*?*/                   }
/*?*/                   break;
/*?*/               }
/*?*/               if( sOut.Len() )
/*?*/                   rWrt.Strm().WriteUnicodeOrByteText( sOut );
/*?*/           }
/*?*/           else if( nSwPos < *pHt->GetStart() )
/*?*/               break;
/*?*/       }
/*N*/   }
/*N*/   return bRet;
/*N*/ }


//------------------------
/* Ausgabe der Nodes */
//------------------------

/*N*/ static Writer& OutASC_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
/*N*/ {
/*N*/   const SwTxtNode& rNd = (SwTxtNode&)rNode;
/*N*/
/*N*/   xub_StrLen nStrPos = rWrt.pCurPam->GetPoint()->nContent.GetIndex();
/*N*/   xub_StrLen nNodeEnde = rNd.Len(), nEnde = nNodeEnde;
/*N*/   BOOL bLastNd =  rWrt.pCurPam->GetPoint()->nNode == rWrt.pCurPam->GetMark()->nNode;
/*N*/   if( bLastNd )
/*N*/       nEnde = rWrt.pCurPam->GetMark()->nContent.GetIndex();
/*N*/
/*N*/   SwASC_AttrIter aAttrIter( (SwASCWriter&)rWrt, rNd, nStrPos );
/*N*/
/*N*/   if( !nStrPos )
/*N*/       rWrt.Strm().WriteUnicodeOrByteText( rNd.GetNumString() );
/*N*/
/*N*/   String aStr( rNd.GetTxt() );
/*N*/   if( rWrt.bASCII_ParaAsBlanc )
/*?*/       aStr.SearchAndReplaceAll( 0x0A, ' ' );
/*N*/
/*N*/   do {
/*N*/       xub_StrLen nNextAttr = aAttrIter.WhereNext();
/*N*/
/*N*/       if( nNextAttr > nEnde )
/*N*/           nNextAttr = nEnde;
/*N*/
/*N*/       if( !aAttrIter.OutAttr( nStrPos ))
/*N*/           rWrt.Strm().WriteUnicodeOrByteText(
/*N*/                               aStr.Copy( nStrPos, nNextAttr - nStrPos ));
/*N*/       nStrPos = nNextAttr;
/*N*/       aAttrIter.NextPos();
/*N*/   } while( nStrPos < nEnde );
/*N*/
/*N*/   if( !bLastNd ||
/*N*/       (( !rWrt.bWriteClipboardDoc && !rWrt.bASCII_NoLastLineEnd )
/*N*/           && !nStrPos && nEnde == nNodeEnde ))
/*?*/       rWrt.Strm().WriteUnicodeOrByteText( ((SwASCWriter&)rWrt).GetLineEnd());
/*N*/
/*N*/   return rWrt;
/*N*/ }

/*
 * lege hier jetzt die Tabellen fuer die ASCII-Funktions-Pointer auf
 * die Ausgabe-Funktionen an.
 * Es sind lokale Strukturen, die nur innerhalb der ASCII-DLL
 * bekannt sein muessen.
 */

SwNodeFnTab aASCNodeFnTab = {
/* RES_TXTNODE  */                   OutASC_SwTxtNode,
/* RES_GRFNODE  */                   0,
/* RES_OLENODE  */                   0
};

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
