/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/


#ifndef SW_EXPFLD_HXX
#define SW_EXPFLD_HXX

#include <svl/svarray.hxx>
#include "swdllapi.h"
#include <fldbas.hxx>
#include <cellfml.hxx>

class SfxPoolItem;
class SwTxtNode;
class SwFrm;
struct SwPosition;
class SwTxtFld;
class SwDoc;
class SwFmtFld;
class _SetGetExpFlds;
class SwEditShell;

// Vorwaertsdeklaration: besorge den "Body-TextNode", fuer Exp.Fld in Fly's
//						Header/Footers/Footnodes
const SwTxtNode* GetBodyTxtNode( const SwDoc& pDoc, SwPosition& rPos,
								 const SwFrm& rFrm );
// Wandlung Address -> Adressen
void ReplacePoint(String& sTmpName, sal_Bool bWithCommandType = sal_False);

struct _SeqFldLstElem
{
	String sDlgEntry;
	sal_uInt16 nSeqNo;

	_SeqFldLstElem( const String& rStr, sal_uInt16 nNo )
		: sDlgEntry( rStr ), nSeqNo( nNo )
	{}
};
SV_DECL_PTRARR_DEL( _SwSeqFldList, _SeqFldLstElem*, 10, 10 )

class SW_DLLPUBLIC SwSeqFldList : public _SwSeqFldList
{
public:
	SwSeqFldList()	: _SwSeqFldList( 10, 10 ) {}

	sal_Bool InsertSort( _SeqFldLstElem* );
	sal_Bool SeekEntry( const _SeqFldLstElem& , sal_uInt16* pPos = 0 );
};

/*--------------------------------------------------------------------
	Beschreibung: Ausdruck
 --------------------------------------------------------------------*/

class SwGetExpFieldType : public SwValueFieldType
{
public:
		SwGetExpFieldType(SwDoc* pDoc);
		virtual SwFieldType*    Copy() const;

		// ueberlagert, weil das Get-Field nicht veraendert werden kann
		// und dann auch nicht aktualisiert werden muss. Aktualisierung
		// erfolgt beim Aendern von Set-Werten !
protected:
   virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew );
};

/*--------------------------------------------------------------------
	Beschreibung: GetExperession
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwGetExpField : public SwFormulaField
{
	String 			sExpand;
	sal_Bool 			bIsInBodyTxt;
	sal_uInt16			nSubType;

    bool            bLateInitialization; // #i82544# 

    virtual String              Expand() const;
    virtual SwField*            Copy() const;

public:
	SwGetExpField( SwGetExpFieldType*, const String& rFormel,
				   sal_uInt16 nSubType = nsSwGetSetExpType::GSE_EXPR, sal_uLong nFmt = 0);

	virtual void 				SetValue( const double& rVal );
	virtual void				SetLanguage(sal_uInt16 nLng);

	inline const String& 		GetExpStr() const;
	inline void  				ChgExpStr(const String& rExpand);

	// wird von der Formatierung abgefragt
	inline sal_Bool 				IsInBodyTxt() const;
	// wird von UpdateExpFlds gesetzt (dort ist die Node-Position bekannt)
	inline void 				ChgBodyTxtFlag( sal_Bool bIsInBody );
	// fuer Felder in Header/Footer/Footnotes/Flys:
	// (wird nur von der Formatierung aufgerufen!!)
	void 						ChangeExpansion( const SwFrm&, const SwTxtFld& );

    virtual String      GetFieldName() const;

	// Die Formel aendern
	virtual String				GetPar2() const;
	virtual void				SetPar2(const String& rStr);

	virtual sal_uInt16				GetSubType() const;
	virtual void				SetSubType(sal_uInt16 nType);
    virtual sal_Bool        QueryValue( com::sun::star::uno::Any& rVal, sal_uInt16 nWhich ) const;
    virtual sal_Bool        PutValue( const com::sun::star::uno::Any& rVal, sal_uInt16 nWhich );

	static sal_uInt16 		GetReferenceTextPos( const SwFmtFld& rFmt, SwDoc& rDoc);
    // #i82544# 
    void				SetLateInitialization() { bLateInitialization = true;}
};

inline void SwGetExpField::ChgExpStr(const String& rExpand)
	{ sExpand = rExpand;}

inline const String& SwGetExpField::GetExpStr() const
	{ return sExpand; 	}

// wird von der Formatierung abgefragt
inline sal_Bool SwGetExpField::IsInBodyTxt() const
	{ return bIsInBodyTxt; }

// wird von UpdateExpFlds gesetzt (dort ist die Node-Position bekannt)
inline void SwGetExpField::ChgBodyTxtFlag( sal_Bool bIsInBody )
	{ bIsInBodyTxt = bIsInBody; }


/*--------------------------------------------------------------------
	Beschreibung: Ausdruck setzen
 --------------------------------------------------------------------*/

class SwSetExpField;

class SW_DLLPUBLIC SwSetExpFieldType : public SwValueFieldType
{
	String 		sName;
	const SwNode* pOutlChgNd;
	String		sDelim;
	sal_uInt16 		nType;
	sal_uInt8		nLevel;
	sal_Bool		bDeleted;

protected:
   virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew );

public:
	SwSetExpFieldType( SwDoc* pDoc, const String& rName,
						sal_uInt16 nType = nsSwGetSetExpType::GSE_EXPR );
	virtual SwFieldType*    Copy() const;
	virtual const String&	GetName() const;

	inline void				SetType(sal_uInt16 nTyp);
	inline sal_uInt16			GetType() const;

	void					SetSeqFormat(sal_uLong nFormat);
	sal_uLong					GetSeqFormat();

	sal_Bool					IsDeleted() const 		{ return bDeleted; }
	void					SetDeleted( sal_Bool b )	{ bDeleted = b; }

	// ueberlagert, weil das Set-Field selbst dafuer sorgt, das
	// es aktualisiert wird.
	inline const String& 	GetSetRefName() const;

	sal_uInt16 SetSeqRefNo( SwSetExpField& rFld );

	sal_uInt16 GetSeqFldList( SwSeqFldList& rList );
	String MakeSeqName( sal_uInt16 nSeqNo );

	// Seqencefelder ggfs. Kapitelweise numerieren
//	sal_Unicode GetDelimiter() const 		{ return cDelim; }
//	void SetDelimiter( sal_Unicode c ) 		{ cDelim = c; }
	const String& GetDelimiter() const 		{ return sDelim; }
	void SetDelimiter( const String& s ) 	{ sDelim = s; }
	sal_uInt8 GetOutlineLvl() const 				{ return nLevel; }
	void SetOutlineLvl( sal_uInt8 n ) 			{ nLevel = n; }
	void SetChapter( SwSetExpField& rFld, const SwNode& rNd );
	// Member nur fuers SwDoc::UpdateExpFld - wird nur waehrend der Laufzeit
	// von SequencefeldTypen benoetigt!!!
	const SwNode* GetOutlineChgNd() const	{ return pOutlChgNd; }
	void SetOutlineChgNd( const SwNode* p )	{ pOutlChgNd = p; }

    virtual sal_Bool        QueryValue( com::sun::star::uno::Any& rVal, sal_uInt16 nWhich ) const;
    virtual sal_Bool        PutValue( const com::sun::star::uno::Any& rVal, sal_uInt16 nWhich );
};

inline void SwSetExpFieldType::SetType( sal_uInt16 nTyp )
{
		nType = nTyp;
		EnableFormat( !(nType & (nsSwGetSetExpType::GSE_SEQ|nsSwGetSetExpType::GSE_STRING)));
}

inline sal_uInt16 SwSetExpFieldType::GetType() const
	{ return nType;	  }

inline const String& SwSetExpFieldType::GetSetRefName() const
	{ return sName; }


/*--------------------------------------------------------------------
	Beschreibung: Ausdruck
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwSetExpField : public SwFormulaField
{
	String 			sExpand;
	String			aPText;
	String			aSeqText;
	sal_Bool			bInput;
	sal_uInt16 			nSeqNo;
	sal_uInt16			nSubType;

    virtual String              Expand() const;
    virtual SwField*            Copy() const;

public:
	SwSetExpField(SwSetExpFieldType*, const String& rFormel, sal_uLong nFmt = 0);

	virtual void 				SetValue( const double& rVal );

	inline const String& 		GetExpStr() const;

	inline void 				ChgExpStr( const String& rExpand );

	inline void  				SetPromptText(const String& rStr);
	inline const 				String& GetPromptText() const;

	inline void  				SetInputFlag(sal_Bool bInp);
	inline sal_Bool					GetInputFlag() const;

    virtual String              GetFieldName() const;

	virtual sal_uInt16				GetSubType() const;
	virtual void				SetSubType(sal_uInt16 nType);

	inline sal_Bool 				IsSequenceFld() const;

	// fuer SequenceFelder - logische Nummer
	inline void					SetSeqNumber( sal_uInt16 n )	{ nSeqNo = n; }
	inline sal_uInt16				GetSeqNumber() const		{ return nSeqNo; }

	// Der Name nur erfragen
	virtual const String&		GetPar1() 	const;

	// Die Formel
	virtual String				GetPar2() 	const;
	virtual void				SetPar2(const String& rStr);
    virtual sal_Bool        QueryValue( com::sun::star::uno::Any& rVal, sal_uInt16 nWhich ) const;
    virtual sal_Bool        PutValue( const com::sun::star::uno::Any& rVal, sal_uInt16 nWhich );
};

inline const String& SwSetExpField::GetExpStr() const
	{ return sExpand; 		}

inline void SwSetExpField::ChgExpStr( const String& rExpand )
	{ sExpand = rExpand; 	}

inline void  SwSetExpField::SetPromptText(const String& rStr)
	{ aPText = rStr;  		}

inline const String& SwSetExpField::GetPromptText() const
	{ return aPText;  		}

inline void SwSetExpField::SetInputFlag(sal_Bool bInp)
	{ bInput = bInp; }

inline sal_Bool	SwSetExpField::GetInputFlag() const
	{ return bInput; }

inline sal_Bool SwSetExpField::IsSequenceFld() const
	{ return 0 != (nsSwGetSetExpType::GSE_SEQ & ((SwSetExpFieldType*)GetTyp())->GetType()); }

/*--------------------------------------------------------------------
	Beschreibung: Eingabe im Text/Variable setzen
 --------------------------------------------------------------------*/

class SwInputFieldType : public SwFieldType
{
	SwDoc* pDoc;
public:
	SwInputFieldType( SwDoc* pDoc );

	virtual SwFieldType* Copy() const;

	SwDoc* GetDoc() const { return pDoc; }
};

/*--------------------------------------------------------------------
	Beschreibung: Eingabefeld
 --------------------------------------------------------------------*/

class SW_DLLPUBLIC SwInputField : public SwField
{
	String  aContent;
	String	aPText;
    String  aHelp;
    String  aToolTip;
	sal_uInt16  nSubType;

    virtual String          Expand() const;
    virtual SwField*        Copy() const;

public:
	// Direkte Eingabe ueber Dialog alten Wert loeschen
	SwInputField(SwInputFieldType*, const String& rContent ,
				 const String& rPrompt, sal_uInt16 nSubType = 0,
				 sal_uLong nFmt = 0);

    virtual String          GetFieldName() const;

	// Content
	virtual const String&	GetPar1() const;
	virtual void			SetPar1(const String& rStr);

	// aPromptText
	virtual String			GetPar2() const;
	virtual void			SetPar2(const String& rStr);

    virtual String          GetHelp() const;
    virtual void            SetHelp(const String & rStr);

    virtual String          GetToolTip() const;
    virtual void            SetToolTip(const String & rStr);

    virtual sal_Bool            isFormField() const;

	virtual sal_uInt16			GetSubType() const;
	virtual void			SetSubType(sal_uInt16 nSub);
    virtual sal_Bool        QueryValue( com::sun::star::uno::Any& rVal, sal_uInt16 nWhich ) const;
    virtual sal_Bool        PutValue( const com::sun::star::uno::Any& rVal, sal_uInt16 nWhich );
};

/*--------------------------------------------------------------------
    Description: Sorted list of input fields and DropDown fields
 --------------------------------------------------------------------*/

class SwInputFieldList
{
public:
	SwInputFieldList( SwEditShell* pShell, sal_Bool bBuildTmpLst = sal_False );
	~SwInputFieldList();

	sal_uInt16		Count() const;
	SwField*    GetField(sal_uInt16 nId);

	void		GotoFieldPos(sal_uInt16 nId);
	void		PushCrsr();
	void	 	PopCrsr();

	// vergleiche TmpLst mit akt Feldern. Alle neue kommen in die SortLst
	// damit sie geupdatet werden koennen. Returnt die Anzahl.
	// (Fuer Textbausteine: nur seine Input-Felder aktualisieren)
	sal_uInt16		BuildSortLst();

	// Alle unselektierten Felder aus Liste entfernen
	void		RemoveUnselectedFlds();

private:
	SwEditShell*	pSh;
	_SetGetExpFlds*	pSrtLst;
	SvPtrarr		aTmpLst;
};

/*--------------------------------------------------------------------
	Beschreibung: Tabellen-Formelfeld
				  (Implementierung steht in tblcalc.cxx)
 --------------------------------------------------------------------*/

class SwTblFieldType : public SwValueFieldType
{
public:
	SwTblFieldType(SwDoc* pDocPtr);
	virtual SwFieldType* Copy() const;
};


// MSC will den hier nicht
//typedef void (SwField:: *FnScanFormel)( const SwTable&, String&,
//									 String&, String* = 0, void* = 0 );


class SwTblField : public SwValueField, public SwTableFormula
{
	String 		sExpand;
	sal_uInt16		nSubType;

    virtual String      Expand() const;
    virtual SwField*    Copy() const;

	// suche den TextNode, in dem das Feld steht
	virtual const SwNode* GetNodeOfFormula() const;

    String GetCommand();

public:
	SwTblField( SwTblFieldType*, const String& rFormel,
				sal_uInt16 nSubType = 0, sal_uLong nFmt = 0);

	virtual void 		SetValue( const double& rVal );
	virtual sal_uInt16		GetSubType() const;
	virtual void		SetSubType(sal_uInt16 nType);

	const String& 		GetExpStr() const 				{ return sExpand; }
	void 				ChgExpStr(const String& rStr) 	{ sExpand = rStr; }

	// berechne sich selbst
	void 				CalcField( SwTblCalcPara& rCalcPara );

    virtual String      GetFieldName() const;

	// Die Formel
	virtual String		GetPar2() 	const;
	virtual void		SetPar2(const String& rStr);
    virtual sal_Bool        QueryValue( com::sun::star::uno::Any& rVal, sal_uInt16 nWhich ) const;
    virtual sal_Bool        PutValue( const com::sun::star::uno::Any& rVal, sal_uInt16 nWhich );
};


#endif // SW_EXPFLD_HXX
