/**************************************************************
 * 
 * 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 SC_VALIDAT_HXX
#define SC_VALIDAT_HXX

#include "conditio.hxx"
#include <com/sun/star/sheet/TableValidationVisibility.hpp>
#include "scdllapi.h"

namespace ValidListType = ::com::sun::star::sheet::TableValidationVisibility;

class ScPatternAttr;
class ScTokenArray;
class TypedScStrCollection;

enum ScValidationMode
{
	SC_VALID_ANY,
	SC_VALID_WHOLE,
	SC_VALID_DECIMAL,
	SC_VALID_DATE,
	SC_VALID_TIME,
	SC_VALID_TEXTLEN,
	SC_VALID_LIST,
	SC_VALID_CUSTOM
};

enum ScValidErrorStyle
{
	SC_VALERR_STOP,
	SC_VALERR_WARNING,
	SC_VALERR_INFO,
	SC_VALERR_MACRO
};

//
//	Eintrag fuer Gueltigkeit (es gibt nur eine Bedingung)
//

class SC_DLLPUBLIC ScValidationData : public ScConditionEntry
{
	sal_uInt32			nKey;				// Index in Attributen

	ScValidationMode	eDataMode;
	sal_Bool				bShowInput;
	sal_Bool				bShowError;
	ScValidErrorStyle	eErrorStyle;
    sal_Int16           mnListType;         // selection list type: none, unsorted, sorted.
	String				aInputTitle;
	String				aInputMessage;
	String				aErrorTitle;
	String				aErrorMessage;

	sal_Bool				bIsUsed;			// temporaer beim Speichern

	sal_Bool			DoMacro( const ScAddress& rPos, const String& rInput,
								ScFormulaCell* pCell, Window* pParent ) const;

	sal_Bool			DoScript( const ScAddress& rPos, const String& rInput,
								ScFormulaCell* pCell, Window* pParent ) const;

    using ScConditionEntry::operator==;

public:
			ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
								const String& rExpr1, const String& rExpr2,
								ScDocument* pDocument, const ScAddress& rPos,
                                const String& rExprNmsp1 = EMPTY_STRING, const String& rExprNmsp2 = EMPTY_STRING,
                                formula::FormulaGrammar::Grammar eGrammar1 = formula::FormulaGrammar::GRAM_DEFAULT,
                                formula::FormulaGrammar::Grammar eGrammar2 = formula::FormulaGrammar::GRAM_DEFAULT );
			ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
								const ScTokenArray* pArr1, const ScTokenArray* pArr2,
								ScDocument* pDocument, const ScAddress& rPos );
			ScValidationData( const ScValidationData& r );
			ScValidationData( ScDocument* pDocument, const ScValidationData& r );
	virtual	~ScValidationData();

	ScValidationData* Clone() const		// echte Kopie
					{ return new ScValidationData( GetDocument(), *this ); }
	ScValidationData* Clone(ScDocument* pNew) const
					{ return new ScValidationData( pNew, *this ); }

	void			ResetInput();
	void			ResetError();
	void			SetInput( const String& rTitle, const String& rMsg );
	void			SetError( const String& rTitle, const String& rMsg,
								ScValidErrorStyle eStyle );

	sal_Bool			GetInput( String& rTitle, String& rMsg ) const
						{ rTitle = aInputTitle; rMsg = aInputMessage; return bShowInput; }
	sal_Bool			GetErrMsg( String& rTitle, String& rMsg, ScValidErrorStyle& rStyle ) const;

	sal_Bool			HasErrMsg() const		{ return bShowError; }

	ScValidationMode GetDataMode() const	{ return eDataMode; }

    inline sal_Int16 GetListType() const                { return mnListType; }
    inline void     SetListType( sal_Int16 nListType )  { mnListType = nListType; }

    /** Returns true, if the validation cell will show a selection list.
        @descr  Use this instead of GetListType() which returns the raw property
        regardless of the validation type. */
    bool            HasSelectionList() const;
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only, if this is a list validation and IsShowList() is enabled.
        @param rStrings  (out-param) The string list to fill with list validation entires.
        @return  true = rStrings has been filled with at least one entry. */
    bool            FillSelectionList( TypedScStrCollection& rStrings, const ScAddress& rPos ) const;

					//	mit String: bei Eingabe, mit Zelle: fuer Detektiv / RC_FORCED
	sal_Bool			IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
									const ScAddress& rPos ) const;
	sal_Bool			IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const;

					// sal_True -> Abbruch
	sal_Bool			DoError( Window* pParent, const String& rInput, const ScAddress& rPos ) const;
	void			DoCalcError( ScFormulaCell* pCell ) const;

	sal_Bool			IsEmpty() const;
	sal_uInt32		GetKey() const			{ return nKey; }
	void			SetKey(sal_uInt32 nNew)	{ nKey = nNew; }	// nur wenn nicht eingefuegt!

	void			SetUsed(sal_Bool bSet)		{ bIsUsed = bSet; }
	sal_Bool			IsUsed() const			{ return bIsUsed; }

	sal_Bool			EqualEntries( const ScValidationData& r ) const;	// fuer Undo

	//	sortiert (per PTRARR) nach Index
	//	operator== nur fuer die Sortierung
	sal_Bool operator ==( const ScValidationData& r ) const	{ return nKey == r.nKey; }
	sal_Bool operator < ( const ScValidationData& r ) const	{ return nKey <  r.nKey; }

private:
    /** Tries to fill the passed collection with list validation entries.
        @descr  Fills the list only if it is non-NULL,
        @param pStrings  (out-param) Optionally NULL, string list to fill with list validation entires.
        @param pCell     can be NULL if it is not necessary to which element in the list is selected.
        @param rPos      the base address for relative references.
        @param rTokArr   Formula token array.
        @param rMatch    (out-param) the index of the first item that matched, -1 if nothing matched.
        @return  true = Cell range found, rRange is valid, or an error entry stuffed into the list if pCell==NULL. */
    bool            GetSelectionFromFormula( TypedScStrCollection* pStrings,
                                             ScBaseCell* pCell, const ScAddress& rPos,
                                             const ScTokenArray& rTokArr, int& rMatch ) const;

    /** Tests, if pCell is equal to what the passed token array represents. */
    bool            IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const;

    /** Tests, if contents of pCell occur in cell range referenced by own formula, or in a string list. */
    bool            IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const;
};

//
//	Liste der Bedingungen:
//

typedef ScValidationData* ScValidationDataPtr;

SV_DECL_PTRARR_SORT(ScValidationEntries_Impl, ScValidationDataPtr,
                        SC_COND_GROW, SC_COND_GROW)

class ScValidationDataList : public ScValidationEntries_Impl
{
public:
		ScValidationDataList() {}
		ScValidationDataList(const ScValidationDataList& rList);
		ScValidationDataList(ScDocument* pNewDoc, const ScValidationDataList& rList);
		~ScValidationDataList() {}

	void	InsertNew( ScValidationData* pNew )
				{ if (!Insert(pNew)) delete pNew; }

	ScValidationData* GetData( sal_uInt32 nKey );

	void	CompileXML();
	void	UpdateReference( UpdateRefMode eUpdateRefMode,
								const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
    void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );

    /** Temporarily during save, returns RefManager's decision whether ALL 
     *  references are marked now. */
    bool    MarkUsedExternalReferences() const;

	sal_Bool	operator==( const ScValidationDataList& r ) const;		// fuer Ref-Undo
};

#endif

