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

#include "address.hxx"
#include <tools/solar.h>
#include "global.hxx"
#include "scdllapi.h"
#include "queryparam.hxx"

#include <memory>

#include <set>

class ScDocument;
class ScBaseCell;
class ScPatternAttr;
class ScAttrArray;
class ScAttrIterator;
class ScRange;

class ScDocumentIterator				// alle nichtleeren Zellen durchgehen
{
private:
	ScDocument*				pDoc;
	SCTAB					nStartTab;
	SCTAB					nEndTab;

	const ScPatternAttr*	pDefPattern;

	SCCOL					nCol;
	SCROW					nRow;
	SCTAB					nTab;
	ScBaseCell*				pCell;
	const ScPatternAttr*	pPattern;


	SCSIZE					nColPos;
	SCSIZE					nAttrPos;

	sal_Bool					GetThis();
	sal_Bool					GetThisCol();

public:
			ScDocumentIterator( ScDocument* pDocument, SCTAB nStartTable, SCTAB nEndTable );
			~ScDocumentIterator();

	sal_Bool					GetFirst();
	sal_Bool					GetNext();

	ScBaseCell*				GetCell();
	const ScPatternAttr*	GetPattern();
	void					GetPos( SCCOL& rCol, SCROW& rRow, SCTAB& rTab );
};

class ScValueIterator            // alle Zahlenwerte in einem Bereich durchgehen
{
private:
	double			fNextValue;
	ScDocument*		pDoc;
	const ScAttrArray*	pAttrArray;
	sal_uLong			nNumFormat;		// fuer CalcAsShown
	sal_uLong			nNumFmtIndex;
	SCCOL			nStartCol;
	SCROW			nStartRow;
	SCTAB			nStartTab;
	SCCOL			nEndCol;
	SCROW			nEndRow;
	SCTAB			nEndTab;
	SCCOL 			nCol;
	SCROW			nRow;
	SCTAB			nTab;
	SCSIZE			nColRow;
	SCROW			nNextRow;
	SCROW			nAttrEndRow;
	short			nNumFmtType;
	sal_Bool			bNumValid;
	sal_Bool			bSubTotal;
	sal_Bool			bNextValid;
	sal_Bool			bCalcAsShown;
	sal_Bool			bTextAsZero;

	sal_Bool			GetThis(double& rValue, sal_uInt16& rErr);
public:
//UNUSED2008-05  ScValueIterator(ScDocument* pDocument,
//UNUSED2008-05                  SCCOL nSCol, SCROW nSRow, SCTAB nSTab,
//UNUSED2008-05                  SCCOL nECol, SCROW nERow, SCTAB nETab,
//UNUSED2008-05                  sal_Bool bSTotal = sal_False, sal_Bool bTextAsZero = sal_False);

					ScValueIterator(ScDocument* pDocument,
									const ScRange& rRange, sal_Bool bSTotal = sal_False,
									sal_Bool bTextAsZero = sal_False );
	void			GetCurNumFmtInfo( short& nType, sal_uLong& nIndex );
    /// Does NOT reset rValue if no value found!
	sal_Bool			GetFirst(double& rValue, sal_uInt16& rErr);
    /// Does NOT reset rValue if no value found!
	sal_Bool			GetNext(double& rValue, sal_uInt16& rErr)
					{
						return bNextValid ? ( bNextValid = sal_False, rValue = fNextValue,
												rErr = 0, nRow = nNextRow,
												++nColRow, bNumValid = sal_False, sal_True )
										  : ( ++nRow, GetThis(rValue, rErr) );
					}
};

// ============================================================================

class ScDBQueryDataIterator
{
public:
    struct Value
    {
        ::rtl::OUString maString;
        double          mfValue;
        sal_uInt16      mnError;
        bool            mbIsNumber;

        Value();
    };

private:
    static SCROW        GetRowByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow);
    static ScBaseCell*  GetCellByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow);
    static ScAttrArray* GetAttrArrayByCol(ScDocument& rDoc, SCTAB nTab, SCCOL nCol);
    static bool         IsQueryValid(ScDocument& rDoc, const ScQueryParam& rParam, SCTAB nTab, SCROW nRow, ScBaseCell* pCell);
    static SCSIZE       SearchColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCROW nRow, SCCOL nCol);

    class DataAccess
    {
    public:
        DataAccess(const ScDBQueryDataIterator* pParent);
        virtual ~DataAccess() = 0;
        virtual bool getCurrent(Value& rValue) = 0;
        virtual bool getFirst(Value& rValue) = 0;
        virtual bool getNext(Value& rValue) = 0;
    protected:
        const ScDBQueryDataIterator* mpParent;
    };

    class DataAccessInternal : public DataAccess
    {
    public:
        DataAccessInternal(const ScDBQueryDataIterator* pParent, ScDBQueryParamInternal* pParam, ScDocument* pDoc);
        virtual ~DataAccessInternal();
        virtual bool getCurrent(Value& rValue);
        virtual bool getFirst(Value& rValue);
        virtual bool getNext(Value& rValue);

    private:
        ScDBQueryParamInternal* mpParam;
        ScDocument*         mpDoc;
        const ScAttrArray*  pAttrArray;
        sal_uLong               nNumFormat;     // for CalcAsShown
        sal_uLong               nNumFmtIndex;
        SCCOL               nCol;
        SCROW               nRow;
        SCSIZE              nColRow;
        SCROW               nAttrEndRow;
        SCTAB               nTab;
        short               nNumFmtType;
        bool                bCalcAsShown;
    };

    class DataAccessMatrix : public DataAccess
    {
    public:
        DataAccessMatrix(const ScDBQueryDataIterator* pParent, ScDBQueryParamMatrix* pParam);
        virtual ~DataAccessMatrix();
        virtual bool getCurrent(Value& rValue);
        virtual bool getFirst(Value& rValue);
        virtual bool getNext(Value& rValue);

    private:
        bool isValidQuery(SCROW mnRow, const ScMatrix& rMat) const;

        ScDBQueryParamMatrix* mpParam;
        SCROW mnCurRow;
        SCROW mnRows;
        SCCOL mnCols;
    };

    ::std::auto_ptr<ScDBQueryParamBase> mpParam;
    ::std::auto_ptr<DataAccess>         mpData;

public:
                    ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam);
    /// Does NOT reset rValue if no value found!
    bool            GetFirst(Value& rValue);
    /// Does NOT reset rValue if no value found!
    bool            GetNext(Value& rValue);
};

// ============================================================================

class ScCellIterator            // alle Zellen in einem Bereich durchgehen
{								// bei SubTotal aber keine ausgeblendeten und
private:						// SubTotalZeilen
	ScDocument*		pDoc;
	SCCOL			nStartCol;
	SCROW			nStartRow;
	SCTAB			nStartTab;
	SCCOL			nEndCol;
	SCROW			nEndRow;
	SCTAB			nEndTab;
	SCCOL 			nCol;
	SCROW			nRow;
	SCTAB			nTab;
	SCSIZE			nColRow;
	sal_Bool			bSubTotal;

	ScBaseCell*		GetThis();
public:
					ScCellIterator(ScDocument* pDocument,
								   SCCOL nSCol, SCROW nSRow, SCTAB nSTab,
								   SCCOL nECol, SCROW nERow, SCTAB nETab,
								   sal_Bool bSTotal = sal_False);
					ScCellIterator(ScDocument* pDocument,
								   const ScRange& rRange, sal_Bool bSTotal = sal_False);
	ScBaseCell*		GetFirst();
	ScBaseCell*		GetNext();
    SCCOL           GetCol() const { return nCol; }
    SCROW           GetRow() const { return nRow; }
    SCTAB           GetTab() const { return nTab; }
    ScAddress       GetPos() const { return ScAddress( nCol, nRow, nTab ); }
};

class ScQueryCellIterator           // alle nichtleeren Zellen in einem Bereich
{									// durchgehen
    enum StopOnMismatchBits
    {
        nStopOnMismatchDisabled = 0x00,
        nStopOnMismatchEnabled  = 0x01,
        nStopOnMismatchOccured  = 0x02,
        nStopOnMismatchExecuted = nStopOnMismatchEnabled | nStopOnMismatchOccured
    };

    enum TestEqualConditionBits
    {
        nTestEqualConditionDisabled = 0x00,
        nTestEqualConditionEnabled  = 0x01,
        nTestEqualConditionMatched  = 0x02,
        nTestEqualConditionFulfilled = nTestEqualConditionEnabled | nTestEqualConditionMatched
    };

private:
	ScQueryParam	aParam;
	ScDocument*		pDoc;
	const ScAttrArray*	pAttrArray;
	sal_uLong			nNumFormat;
	SCTAB			nTab;
	SCCOL 			nCol;
	SCROW			nRow;
	SCSIZE			nColRow;
	SCROW			nAttrEndRow;
    sal_uInt8            nStopOnMismatch;
    sal_uInt8            nTestEqualCondition;
	sal_Bool			bAdvanceQuery;
    sal_Bool            bIgnoreMismatchOnLeadingStrings;

	ScBaseCell*		GetThis();

                    /* Only works if no regular expression is involved, only
                       searches for rows in one column, and only the first
                       query entry is considered with simple conditions
                       SC_LESS_EQUAL (sorted ascending) or SC_GREATER_EQUAL
                       (sorted descending). Check these things before
                       invocation! Delivers a starting point, continue with
                       GetThis() and GetNext() afterwards. Introduced for
                       FindEqualOrSortedLastInRange()
                     */
    ScBaseCell*     BinarySearch();

public:
					ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
										const ScQueryParam& aParam, sal_Bool bMod = sal_True);
										// fuer bMod = sal_False muss der QueryParam
										// weiter aufgefuellt sein (bIsString)
	ScBaseCell*		GetFirst();
	ScBaseCell*		GetNext();
	SCCOL           GetCol() { return nCol; }
	SCROW           GetRow() { return nRow; }

					// setzt alle Entry.nField einen weiter, wenn Spalte
					// wechselt, fuer ScInterpreter ScHLookup()
	void			SetAdvanceQueryParamEntryField( sal_Bool bVal )
						{ bAdvanceQuery = bVal; }
	void			AdvanceQueryParamEntryField();

                    /** If set, iterator stops on first non-matching cell
                        content. May be used in SC_LESS_EQUAL queries where a
                        cell range is assumed to be sorted; stops on first
                        value being greater than the queried value and
                        GetFirst()/GetNext() return NULL. StoppedOnMismatch()
                        returns sal_True then.
                        However, the iterator's conditions are not set to end
                        all queries, GetCol() and GetRow() return values for
                        the non-matching cell, further GetNext() calls may be
                        executed. */
    void            SetStopOnMismatch( sal_Bool bVal )
                        {
                            nStopOnMismatch = sal::static_int_cast<sal_uInt8>(bVal ? nStopOnMismatchEnabled :
                                nStopOnMismatchDisabled);
                        }
    sal_Bool            StoppedOnMismatch() const
                        { return nStopOnMismatch == nStopOnMismatchExecuted; }

                    /** If set, an additional test for SC_EQUAL condition is
                        executed in ScTable::ValidQuery() if SC_LESS_EQUAL or
                        SC_GREATER_EQUAL conditions are to be tested. May be
                        used where a cell range is assumed to be sorted to stop
                        if an equal match is found. */
    void            SetTestEqualCondition( sal_Bool bVal )
                        {
                            nTestEqualCondition = sal::static_int_cast<sal_uInt8>(bVal ?
                                nTestEqualConditionEnabled :
                                nTestEqualConditionDisabled);
                        }
    sal_Bool            IsEqualConditionFulfilled() const
                        { return nTestEqualCondition == nTestEqualConditionFulfilled; }

                    /** In a range assumed to be sorted find either the last of
                        a sequence of equal entries or the last being less than
                        (or greater than) the queried value. Used by the
                        interpreter for [HV]?LOOKUP() and MATCH(). Column and
                        row position of the found entry are returned, otherwise
                        invalid.

                        @param bSearchForEqualAfterMismatch
                            Continue searching for an equal entry even if the
                            last entry matching the range was found, in case
                            the data is not sorted. Is always done if regular
                            expressions are involved.

                        @param bIgnoreMismatchOnLeadingStrings
                            Normally strings are sorted behind numerical
                            values. If this parameter is sal_True, the search does
                            not stop when encountering a string and does not
                            assume that no values follow anymore.
                            If querying for a string a mismatch on the first
                            entry, e.g. column header, is ignored.

                        @ATTENTION! StopOnMismatch, TestEqualCondition and
                        the internal IgnoreMismatchOnLeadingStrings and query
                        params are in an undefined state upon return! The
                        iterator is not usable anymore except for obtaining the
                        number format!
                      */
    sal_Bool            FindEqualOrSortedLastInRange( SCCOL& nFoundCol,
                        SCROW& nFoundRow, sal_Bool bSearchForEqualAfterMismatch = sal_False,
                        sal_Bool bIgnoreMismatchOnLeadingStrings = sal_True );
};

class ScDocAttrIterator				// alle Attribut-Bereiche
{
private:
	ScDocument*		pDoc;
	SCTAB			nTab;
	SCCOL			nEndCol;
	SCROW			nStartRow;
	SCROW			nEndRow;
	SCCOL			nCol;
	ScAttrIterator*	pColIter;

public:
					ScDocAttrIterator(ScDocument* pDocument, SCTAB nTable,
									SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
					~ScDocAttrIterator();

	const ScPatternAttr*	GetNext( SCCOL& rCol, SCROW& rRow1, SCROW& rRow2 );
};

class ScAttrRectIterator			// alle Attribut-Bereiche, auch Bereiche ueber mehrere Spalten
{
private:
	ScDocument*		pDoc;
	SCTAB			nTab;
	SCCOL			nEndCol;
	SCROW			nStartRow;
	SCROW			nEndRow;
	SCCOL			nIterStartCol;
	SCCOL			nIterEndCol;
	ScAttrIterator*	pColIter;

public:
					ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
									SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
					~ScAttrRectIterator();

	void 					DataChanged();
	const ScPatternAttr*	GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow1, SCROW& rRow2 );
};

class ScHorizontalCellIterator		// alle nichtleeren Zellen in einem Bereich
{									// zeilenweise durchgehen
private:
	ScDocument*		pDoc;
	SCTAB			nTab;
	SCCOL			nStartCol;
	SCCOL			nEndCol;
	SCROW			nStartRow;
	SCROW			nEndRow;
	SCROW*			pNextRows;
	SCSIZE*			pNextIndices;
	SCCOL			nCol;
	SCROW			nRow;
	sal_Bool			bMore;

public:
					ScHorizontalCellIterator(ScDocument* pDocument, SCTAB nTable,
									SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
					~ScHorizontalCellIterator();

	ScBaseCell*		GetNext( SCCOL& rCol, SCROW& rRow );
	sal_Bool			ReturnNext( SCCOL& rCol, SCROW& rRow );
    /// Set a(nother) sheet and (re)init.
    void            SetTab( SCTAB nTab );

private:
	void			Advance();
};


/** Row-wise value iterator. */
class ScHorizontalValueIterator
{
private:
    ScDocument               *pDoc;
    const ScAttrArray        *pAttrArray;
    ScHorizontalCellIterator *pCellIter;
    sal_uLong                 nNumFormat;     // for CalcAsShown
    sal_uLong                 nNumFmtIndex;
    SCTAB                     nEndTab;
    SCCOL                     nCurCol;
    SCROW                     nCurRow;
    SCTAB                     nCurTab;
    SCROW                     nAttrEndRow;
    short                     nNumFmtType;
    bool                      bNumValid;
    bool                      bSubTotal;
    bool                      bCalcAsShown;
    bool                      bTextAsZero;

public:

                    ScHorizontalValueIterator( ScDocument* pDocument,
                                               const ScRange& rRange,
                                               bool bSTotal = false,
                                               bool bTextAsZero = false );
                    ~ScHorizontalValueIterator();
    void            GetCurNumFmtInfo( short& nType, sal_uLong& nIndex );
    /// Does NOT reset rValue if no value found!
    bool            GetNext( double& rValue, sal_uInt16& rErr );
};


//
//	gibt alle Bereiche mit nicht-Default-Formatierung zurueck (horizontal)
//

class ScHorizontalAttrIterator
{
private:
	ScDocument* 			pDoc;
	SCTAB					nTab;
	SCCOL					nStartCol;
	SCROW					nStartRow;
	SCCOL					nEndCol;
	SCROW					nEndRow;

	SCROW*					pNextEnd;
	SCSIZE*					pIndices;
	const ScPatternAttr**	ppPatterns;
	SCCOL					nCol;
	SCROW					nRow;
	sal_Bool					bRowEmpty;

public:
			ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB nTable,
									SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
			~ScHorizontalAttrIterator();

	const ScPatternAttr*	GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow );
};

//
//	gibt nichtleere Zellen und Bereiche mit Formatierung zurueck (horizontal)
//

class SC_DLLPUBLIC ScUsedAreaIterator
{
private:
	ScHorizontalCellIterator	aCellIter;
	ScHorizontalAttrIterator	aAttrIter;

	SCCOL					nNextCol;
	SCROW					nNextRow;

	SCCOL					nCellCol;
	SCROW					nCellRow;
	const ScBaseCell*		pCell;
	SCCOL					nAttrCol1;
	SCCOL					nAttrCol2;
	SCROW					nAttrRow;
	const ScPatternAttr*	pPattern;

	SCCOL					nFoundStartCol;			// Ergebnisse nach GetNext
	SCCOL					nFoundEndCol;
	SCROW					nFoundRow;
	const ScPatternAttr*	pFoundPattern;
	const ScBaseCell*		pFoundCell;

public:
			ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
								SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
			~ScUsedAreaIterator();

	sal_Bool	GetNext();

	SCCOL					GetStartCol() const		{ return nFoundStartCol; }
	SCCOL					GetEndCol() const		{ return nFoundEndCol; }
	SCROW					GetRow() const			{ return nFoundRow; }
	const ScPatternAttr*	GetPattern() const		{ return pFoundPattern; }
	const ScBaseCell*		GetCell() const			{ return pFoundCell; }
};

// ============================================================================

class ScRowBreakIterator
{
public:
    static SCROW NOT_FOUND;

    explicit ScRowBreakIterator(::std::set<SCROW>& rBreaks);
    SCROW first();
    SCROW next();
 
private:
    ::std::set<SCROW>& mrBreaks;
    ::std::set<SCROW>::const_iterator maItr;
    ::std::set<SCROW>::const_iterator maEnd;
};

#endif


