/* -*- 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.
 *
 ************************************************************************/
#ifndef _SHELLIO_HXX
#define _SHELLIO_HXX

#include <tools/datetime.hxx>
#include <tools/ref.hxx>
#include <sot/formats.hxx>

#include <docfac.hxx>	// SwDocFac
#include <tools/debug.hxx>
class SvStream;
namespace binfilter {
class SvStorage;
class SvStorageStreamRef;
class SvPtrarr;
class SfxItemPool;
class SfxItemSet;
class SvStrings;
class SvStringsSortDtor;
class SvxMacroTableDtor;

// einige Forward - Deklarationen
class SfxFactoryFilterContainer;
class SfxFilter;
class SfxMedium;
class SvxFontItem;

class Sw3Io;
class SwCntntNode;
class SwCrsrShell;
class SwDoc;
class SwPaM;
struct SwPosition;
struct Writer_Impl;

// ab so vielen chars wird ein mit einem ASCII/W4W-Reader eingelesener
// Absatz zwangsweise umgebrochen. Muss immer groesser als 200 sein !!!
#define MAX_ASCII_PARA 10000


class SwAsciiOptions
{
    String sFont;
    rtl_TextEncoding eCharSet;
    USHORT nLanguage;
    LineEnd eCRLF_Flag;

public:

    const String& GetFontName() const { return sFont; }
    void SetFontName( const String& rFont ) { sFont = rFont; }

    rtl_TextEncoding GetCharSet() const { return eCharSet; }
    void SetCharSet( rtl_TextEncoding nVal ) { eCharSet = nVal; }

    USHORT GetLanguage() const { return nLanguage; }
    void SetLanguage( USHORT nVal ) { nLanguage = nVal; }

    LineEnd GetParaFlags() const { return eCRLF_Flag; }
    void SetParaFlags( LineEnd eVal ) { eCRLF_Flag = eVal; }

    void Reset()
    {
        sFont.Erase();
        eCRLF_Flag = GetSystemLineEnd();
        eCharSet = ::gsl_getSystemTextEncoding();
        nLanguage = 0;
    }
    // for the automatic conversion (mail/news/...)
    void ReadUserData( const String& );

    SwAsciiOptions() { Reset(); }
};

/**************** SwReader/Reader ************************/
// Basisklasse der moeglichen Optionen fuer einen speziellen Reader
class Reader;
// Ruft den Reader mit seinen Optionen, Dokument, Cursor etc.
class SwReader;
// SwRead ist der Pointer auf die Read-Optionen-Basisklasse
typedef Reader *SwRead;

class SwgReaderOption
{
    SwAsciiOptions aASCIIOpts;
    union
    {
        BOOL bFmtsOnly;
        struct
        {
            BOOL bFrmFmts: 1;
            BOOL bPageDescs: 1;
            BOOL bTxtFmts: 1;
            BOOL bNumRules: 1;
            BOOL bMerge:1;
        }  Fmts;
    } What;

public:
    void ResetAllFmtsOnly() { What.bFmtsOnly = 0; }
    void SetAllFmtsOnly() { What.bFmtsOnly = (BOOL)0xff; }
    BOOL IsFmtsOnly() const { return What.bFmtsOnly; }

    BOOL IsFrmFmts() const { return What.Fmts.bFrmFmts; }
    void SetFrmFmts( const BOOL bNew) { What.Fmts.bFrmFmts = bNew; }

    BOOL IsPageDescs() const { return What.Fmts.bPageDescs; }
    void SetPageDescs( const BOOL bNew) { What.Fmts.bPageDescs = bNew; }

    BOOL IsTxtFmts() const { return What.Fmts.bTxtFmts; }
    void SetTxtFmts( const BOOL bNew) { What.Fmts.bTxtFmts = bNew; }

    BOOL IsNumRules() const { return What.Fmts.bNumRules; }
    void SetNumRules( const BOOL bNew) { What.Fmts.bNumRules = bNew; }

    BOOL IsMerge() const { return What.Fmts.bMerge; }
    void SetMerge( const BOOL bNew ) { What.Fmts.bMerge = bNew; }

    const SwAsciiOptions& GetASCIIOpts() const { return aASCIIOpts; }
    void SetASCIIOpts( const SwAsciiOptions& rOpts ) { aASCIIOpts = rOpts; }
    void ResetASCIIOpts() { aASCIIOpts.Reset(); }

    SwgReaderOption()
    {	ResetAllFmtsOnly(); aASCIIOpts.Reset(); }
};

class SwReader: public SwDocFac
{
    SvStream* pStrm;
    SvStorage* pStg;
    SfxMedium* pMedium;		// wer ein Medium haben will (W4W)

    SwPaM* pCrsr;
    String aFileName;

public:
    /*
     * Initiales Einlesen. Dokument wird erst beim Read(..) angelegt.
     * JP 25.04.95: oder falls es mitgegeben wird, in dieses.
     *				Sonderfall fuer Load mit Sw3Reader
     */
    SwReader( SvStorage&, const String& rFilename, SwDoc *pDoc = 0 );
    SwReader( SfxMedium&, const String& rFilename, SwDoc *pDoc = 0 );
    /*
     * In ein existierendes Dokument einlesen, Dokument und
     * Position im Dokument werden aus dem SwPaM uebernommen.
     */
    SwReader( SfxMedium&, const String& rFilename, SwPaM& );

    /*
     * Nur SwReader::Read(...) ist die Export-Schnittstelle!!!
     */
    BOOL NeedsPasswd( const Reader& );
    BOOL CheckPasswd( const String&, const Reader& );
    ULONG Read( const Reader& );

    // ask for glossaries
};



/*  */
/****************  SPEZIELLE Reader ************************/

// spezielle - Reader koennen beides sein !! (Excel, W4W, .. )
#define SW_STREAM_READER	1
#define SW_STORAGE_READER	2

class Reader
{
    friend class SwReader;
    SwDoc* pTemplate;
    String aTemplateNm;
    Date aDStamp;
    Time aTStamp;
    DateTime aChkDateTime;

protected:
    SvStream* pStrm;
    SvStorage* pStg;
    SfxMedium* pMedium;		// wer ein Medium haben will (W4W)

    SwgReaderOption aOpt;
    BOOL bInsertMode : 1;
    BOOL bTmplBrowseMode : 1;
    BOOL bReadUTF8: 1;		// Stream als UTF-8 interpretieren
    BOOL bBlockMode: 1;
    BOOL bOrganizerMode : 1;
    BOOL bHasAskTemplateName : 1;
    BOOL bIgnoreHTMLComments : 1;

    virtual String GetTemplateName() const;

public:
    Reader();
    virtual ~Reader();

    virtual int GetReaderType();
    SwgReaderOption& GetReaderOpt() { return aOpt; }

    virtual void SetFltName( const String& rFltNm );
    static void SetNoOutlineNum( SwDoc& rDoc );

    // den Item-Set eines Frm-Formats an das alte Format anpassen
    static void ResetFrmFmtAttrs( SfxItemSet &rFrmSet );

    // die Rahmen-/Grafik-/OLE-Vorlagen an das alte Format (ohne
    // Umrandung etc.) anpassen
    static void ResetFrmFmts( SwDoc& rDoc );

    // Die Filter-Vorlage laden, setzen und wieder freigeben
    SwDoc* GetTemplateDoc();
    BOOL SetTemplate( SwDoc& rDoc );
    void ClearTemplate();
    void SetTemplateName( const String& rDir );

    BOOL IsReadUTF8() const { return bReadUTF8; }
    void SetReadUTF8( BOOL bSet ) { bReadUTF8 = bSet; }

    BOOL IsBlockMode() const { return bBlockMode; }
    void SetBlockMode( BOOL bSet ) { bBlockMode = bSet; }

    BOOL IsOrganizerMode() const { return bOrganizerMode; }
    void SetOrganizerMode( BOOL bSet ) { bOrganizerMode = bSet; }

    BOOL IsIgnoreHTMLComments() const { return bIgnoreHTMLComments; }
    void SetIgnoreHTMLComments( BOOL bSet ) { bIgnoreHTMLComments = bSet; }


    // read the sections of the document, which is equal to the medium.
    // returns the count of it
private:
    virtual ULONG Read(SwDoc &,SwPaM &,const String &)=0;

    // alle die die Streams / Storages nicht geoeffnet brauchen,
    // muessen die Methode ueberladen (W4W!!)
    virtual int SetStrmStgPtr();
};



class AsciiReader: public Reader
{
    friend class SwReader;
    virtual ULONG Read( SwDoc &,SwPaM &,const String &){DBG_BF_ASSERT(0, "STRIP"); return 0;} //STRIP001 virtual ULONG Read( SwDoc &,SwPaM &,const String &);
public:
    AsciiReader(): Reader() {}
};

class SwgReader: public Reader
{
    virtual ULONG Read( SwDoc &,SwPaM &,const String &);
};

class StgReader : public Reader
{
    String aFltName;

protected:
    ULONG OpenMainStream( SvStorageStreamRef& rRef, USHORT& rBuffSize );

public:
    const String& GetFltName() { return aFltName; }
};


class Sw3Reader : public StgReader
{
    Sw3Io* pIO;
    virtual ULONG Read( SwDoc &,SwPaM &,const String &);
public:
    Sw3Reader() : pIO( 0 ) {}

          Sw3Io* GetSw3Io() 				{ return pIO; }
    const Sw3Io* GetSw3Io() const			{ return pIO; }
          void   SetSw3Io( Sw3Io* pIo ) 	{ pIO = pIo; }

    // read the sections of the document, which is equal to the medium.
    // returns the count of it
};

/*  */
////////////////////////////////////////////////////////////////////////////

// Der uebergebene Stream muss dynamisch angelegt werden und
// vor dem Loeschen der Instanz per Stream() angefordert
// und geloescht werden!

class SwImpBlocks;

class SwTextBlocks
{
    friend class Sw2TextBlocks;
    friend class Sw3IoImp;
    SwImpBlocks* pImp;
    ULONG 		 nErr;

public:
    void Flush(){}

    ULONG GetError() const { return nErr; }
};


extern void _InitFilter();
extern void _FinitFilter();
extern SwRead ReadRtf, ReadAscii, ReadSwg, ReadSw3, ReadHTML, ReadXML;

extern BOOL SetHTMLTemplate( SwDoc &rDoc ); //Fuer Vorlagen aus HTML.vor laden shellio.cxx


/*  */
/////////////////////////////////////////////////////////////////////////////

/*
 * Schreiben, Writer
 */


/* Basis-Klasse aller Writer */

class Writer : public SvRefBase
{
    SwAsciiOptions aAscOpts;

    void _AddFontItem( SfxItemPool& rPool, const SvxFontItem& rFont );
    void _AddFontItems( SfxItemPool& rPool, USHORT nWhichId );

protected:
    Writer_Impl* pImpl;

    SvStream* pStrm;
    SwPaM* pOrigPam;			// der letze zu bearbeitende Pam
    const String* pOrigFileName;

    void ResetWriter();
    BOOL CopyNextPam( SwPaM ** );

    void PutNumFmtFontsInAttrPool();
    void PutEditEngFontsInAttrPool( BOOL bIncl_CJK_CTL = TRUE );

    virtual ULONG WriteStream() = 0;

public:
    SwDoc* pDoc;
    SwPaM* pCurPam;
    BOOL bWriteAll : 1;
    BOOL bShowProgress : 1;
    BOOL bWriteClipboardDoc : 1;
    BOOL bWriteOnlyFirstTable : 1;
    BOOL bASCII_ParaAsCR : 1;
    BOOL bASCII_ParaAsBlanc : 1;
    BOOL bASCII_NoLastLineEnd : 1;
    BOOL bUCS2_WithStartChar : 1;

    BOOL bBlock : 1;
    BOOL bOrganizerMode : 1;

    Writer();
    virtual ~Writer();

            ULONG Write( SwPaM&, SvStream&,  const String* = 0 );
    virtual ULONG Write( SwPaM&, SvStorage&, const String* = 0 );

    virtual BOOL IsStgWriter() const;
    virtual BOOL IsSw3Writer() const;

    BOOL ShowProgress() const 					{ return bShowProgress; }
    void SetShowProgress( BOOL bFlag = FALSE )	{ bShowProgress = bFlag; }

    const String* GetOrigFileName() const 		{ return pOrigFileName; }

    const SwAsciiOptions& GetAsciiOptions() const { return aAscOpts; }
    void SetAsciiOptions( const SwAsciiOptions& rOpt ) { aAscOpts = rOpt; }

    // suche die naechste Bookmark-Position aus der Bookmark-Tabelle
    // build a bookmark table, which is sort by the node position. The
    // OtherPos of the bookmarks also inserted.
    // search alle Bookmarks in the range and return it in the Array
    // lege einen neuen PaM an der Position an
    SwPaM* NewSwPaM( SwDoc & rDoc, ULONG nStartIdx, ULONG nEndIdx ) const;

    // kopiere ggfs. eine lokale Datei ins Internet

    // Stream-spezifische Routinen, im Storage-Writer NICHT VERWENDEN!

    // Optimierung der Ausgabe auf den Stream.
SvStream& OutLong( SvStream& rStrm, long nVal );
SvStream& OutULong( SvStream& rStrm, ULONG nVal );

    // Hex-Zahl ausgeben, default ist 2.stellige Zahl
SvStream& OutHex( SvStream& rStrm, ULONG nHex, BYTE nLen = 2 );
    // 4-st. Hex-Zahl ausgeben
    // 8-st. Hex-Zahl ausgeben

inline SvStream& OutHex( USHORT nHex, BYTE nLen = 2 )      { return OutHex( Strm(), nHex, nLen ); }
inline SvStream& OutHex4( USHORT nHex )     { return OutHex( Strm(), nHex, 4 ); }
//STRIP001 	inline SvStream& OutHex8( ULONG nHex )      { return OutHex( Strm(), nHex, 8 ); }
inline SvStream& OutLong( long nVal )       { return OutLong( Strm(), nVal ); }
inline SvStream& OutULong( ULONG nVal )     { return OutULong( Strm(), nVal ); }

    void SetStrm( SvStream& rStrm ) { pStrm = &rStrm; }
#ifndef DBG_UTIL
    SvStream& Strm() { return *pStrm; }
#else
    SvStream& Strm();
#endif

    BOOL IsOrganizerMode() const { return bOrganizerMode; }
    void SetOrganizerMode( BOOL bSet ) { bOrganizerMode = bSet; }
};

#ifndef SW_DECL_WRITER_DEFINED
#define SW_DECL_WRITER_DEFINED
SV_DECL_REF(Writer)
#endif
SV_IMPL_REF(Writer)

// Basisklasse fuer alle Storage-Writer

class StgWriter : public Writer
{
protected:
    String aFltName;
    SvStorage* pStg;

    // Fehler beim Aufruf erzeugen
    virtual ULONG WriteStream(){DBG_BF_ASSERT(0, "STRIP"); return 0;} //STRIP001 virtual ULONG WriteStream();
    virtual ULONG WriteStorage() = 0;

public:
    StgWriter() : Writer(), pStg( 0 ) {}

    virtual ULONG Write( SwPaM&, SvStorage&, const String* = 0 );

    SvStorage& GetStorage() const		{ return *pStg; }
    const String& GetFltName() const	{ return aFltName; }
    void SetFltName( const String& r )	{ aFltName = r; }
};

class Sw3Writer : public StgWriter
{
    Sw3Io* pIO;
    BOOL bSaveAs : 1;

    virtual ULONG WriteStorage();

public:
    Sw3Writer() : pIO( 0 ), bSaveAs( FALSE ) {}

          Sw3Io* GetSw3Io() 				{ return pIO; }
    const Sw3Io* GetSw3Io() const			{ return pIO; }
    void SetSw3Io( Sw3Io* pIo, BOOL bSvAs = FALSE )
        { pIO = pIo; bSaveAs = bSvAs; }

};



// Schnittstellenklasse fuer den allgemeinen Zugriff auf die
// speziellen Writer

class SwWriter
{
    SvStream* pStrm;
    SvStorage* pStg;
    SfxMedium* pMedium;

    SwPaM* pOutPam;
    SwCrsrShell *pShell;
    SwDoc &rDoc;
    BOOL bWriteAll;

public:
    ULONG Write( WriterRef& rxWriter, const String* = 0);

    SwWriter( SvStream&, SwPaM &, BOOL bWriteAll = FALSE );

//	SwWriter( SvStorage&, SwCrsrShell &,BOOL bWriteAll = FALSE );
    SwWriter( SvStorage&, SwDoc & );
//	SwWriter( SvStorage&, SwPaM&, BOOL bWriteAll = FALSE );

//	SwWriter( SfxMedium&, SwPaM&, BOOL bWriteAll = FALSE );
};


/*  */
/////////////////////////////////////////////////////////////////////////////

void GetRTFWriter( const String&, WriterRef& );
void GetASCWriter( const String&, WriterRef& );
void GetSw3Writer( const String&, WriterRef& );
void GetXMLWriter( const String&, WriterRef& );

// Die folgende Klasse ist ein Wrappe fuer die Basic-I/O-Funktionen
// des Writer 3.0. Alles ist statisch. Alle u.a. Filternamen sind die
// Writer-internen Namen, d.h. die namen, die in INSTALL.INI vor dem
// Gleichheitszeichen stehen, z.b. SWG oder ASCII.

class SwIoSystem
{
public:
        // suche ueber den Filtertext den Filtereintrag
    static const SfxFilter* GetFilterOfFilterTxt( const String& rFilterNm,
                                const SfxFactoryFilterContainer* pCnt = 0 );
        // suche ueber den internen FormatNamen den Filtereintrag
    static const SfxFilter* GetFilterOfFormat( const String& rFormat,
                                const SfxFactoryFilterContainer* pCnt = 0 );

    // Feststellen des zu verwendenden Filters fuer die uebergebene
    // Datei. Der Filtername wird zurueckgeliefert. Konnte kein Filter
    // zurueckgeliefert werden, wird der Name des ASCII-Filters geliefert!
    static const SfxFilter* GetFileFilter( const String& rFileName,
                                            const String& rPrefFltName,
                                            SfxMedium* pMedium = 0 );

        // Feststellen ob das File in dem vorgegebenen Format vorliegt.
        // Z.z werden nur unsere eigene Filter unterstuetzt!!
    static FASTBOOL IsFileFilter( SfxMedium& rMedium, const String& rFmtName,
                                    const SfxFilter** ppFlt = 0 );

    static FASTBOOL IsValidStgFilter( SvStorage& , const SfxFilter& );

        static bool IsDetectableText(const sal_Char* pBuf, ULONG &rLen,
        CharSet *pCharSet=0, bool *pSwap=0, LineEnd *pLineEnd=0);
    static bool IsDetectableW4W(const String& rFileName);

    static const SfxFilter* GetTextFilter(const sal_Char* pBuf, ULONG nLen);
    // gebe einen bestimmten Reader zurueck
     static Reader* GetReader( const String& rFltName );
    // gebe einen bestimmten Writer zurueck
    static void GetWriter( const String& rFltName, WriterRef& xWrt );

    static const String GetSubStorageName( const SfxFilter& rFltr );
};


// ----------------------------------
// diese Filter sind immer vorhanden und koennen ueber die
// Formatnamen gesucht werden. Alle anderen Filter sind nur intern
// bekannt. Die UI-Seite benutzt die GetReader()/GetWriter() -Funktionen,
// um die speziellen zu erhalten.

extern sal_Char __FAR_DATA FILTER_SWG[];	// SWG-Filter
extern sal_Char __FAR_DATA FILTER_RTF[];	// RTF-Filter
extern sal_Char __FAR_DATA FILTER_TEXT[];	// Text-Filter mit Default-CodeSet
extern sal_Char __FAR_DATA FILTER_BAS[];	// StarBasic (identisch mit ANSI)
extern sal_Char __FAR_DATA FILTER_W4W[];	// W4W-Filter
extern sal_Char __FAR_DATA FILTER_WW8[];	// WinWord 97-Filter
extern sal_Char __FAR_DATA FILTER_SW3[];	// SW3-Storage Filter
extern sal_Char __FAR_DATA FILTER_SW4[];	// SW4-Storage Filter
extern sal_Char __FAR_DATA FILTER_SW4[];	// SW4-Storage Filter
extern sal_Char __FAR_DATA FILTER_SW5[];	// SW5-Storage Filter
extern sal_Char __FAR_DATA FILTER_SWGV[];	// SWG-Vorlagen Filter
extern sal_Char __FAR_DATA FILTER_SW3V[];	// SW3-Storage Vorlagen Filter
extern sal_Char __FAR_DATA FILTER_SW4V[];	// SW4-Storage Vorlagen Filter
extern sal_Char __FAR_DATA FILTER_SW5V[];	// SW5-Storage Vorlagen Filter
extern sal_Char __FAR_DATA FILTER_SWW4V[];	// SW/Web Storage Vorlagen Filter
extern sal_Char __FAR_DATA FILTER_SWW5V[];	// SW/Web Storage Vorlagen Filter
extern sal_Char __FAR_DATA FILTER_TEXT_DLG[];	// text filter with encoding dialog
extern sal_Char __FAR_DATA FILTER_XML[];	// XML filter
extern sal_Char __FAR_DATA FILTER_XMLV[];	// XML filter
extern sal_Char __FAR_DATA FILTER_XMLVW[];	// XML filter


} //namespace binfilter
#endif

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