/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"



//------------------------------------------------------------------------

#include "excrecds.hxx"

#include <map>
#include <filter/msfilter/countryid.hxx>

#include "scitems.hxx"
#include <editeng/eeitem.hxx>

#include <sfx2/objsh.hxx>

#include <editeng/editdata.hxx>
#include <editeng/editeng.hxx>
#include <editeng/editobj.hxx>
#include <editeng/editstat.hxx>

#include <editeng/flditem.hxx>
#include <editeng/flstitem.hxx>

#include <svx/algitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/brshitem.hxx>
#include <svx/pageitem.hxx>
#include <editeng/paperinf.hxx>
#include <editeng/sizeitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/escpitem.hxx>
#include <svl/intitem.hxx>
#include <svl/zforlist.hxx>
#include <svl/zformat.hxx>
#include <svtools/ctrltool.hxx>

#define _SVSTDARR_USHORTS
#include <svl/svstdarr.hxx>

#include <string.h>

#include "global.hxx"
#include "globstr.hrc"
#include "docpool.hxx"
#include "patattr.hxx"
#include "cell.hxx"
#include "document.hxx"
#include "scextopt.hxx"
#include "patattr.hxx"
#include "attrib.hxx"
#include "progress.hxx"
#include "dociter.hxx"
#include "rangenam.hxx"
#include "dbcolect.hxx"
#include "stlsheet.hxx"
#include "stlpool.hxx"
#include "editutil.hxx"
#include "formula/errorcodes.hxx"

#include "excdoc.hxx"
#include "xeescher.hxx"
#include "xeformula.hxx"
#include "xelink.hxx"
#include "xename.hxx"
#include "xecontent.hxx"

#include "xcl97rec.hxx"

using namespace ::oox;

using ::com::sun::star::uno::Sequence;
using ::rtl::OString;

//--------------------------------------------------------- class ExcDummy_00 -
const sal_uInt8		ExcDummy_00::pMyData[] = {
    0x5c, 0x00, 0x20, 0x00, 0x04, 'C',  'a',  'l',  'c',    // WRITEACCESS
	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
};
const sal_Size ExcDummy_00::nMyLen = sizeof( ExcDummy_00::pMyData );

//-------------------------------------------------------- class ExcDummy_04x -
const sal_uInt8		ExcDummy_040::pMyData[] = {
	0x40, 0x00, 0x02, 0x00, 0x00, 0x00,						// BACKUP
	0x8d, 0x00, 0x02, 0x00, 0x00, 0x00,						// HIDEOBJ
};
const sal_Size ExcDummy_040::nMyLen = sizeof( ExcDummy_040::pMyData );

const sal_uInt8		ExcDummy_041::pMyData[] = {
	0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,						// PRECISION
	0xda, 0x00, 0x02, 0x00, 0x00, 0x00						// BOOKBOOL
};
const sal_Size ExcDummy_041::nMyLen = sizeof( ExcDummy_041::pMyData );

//-------------------------------------------------------- class ExcDummy_02a -
const sal_uInt8      ExcDummy_02a::pMyData[] = {
	0x0d, 0x00, 0x02, 0x00, 0x01, 0x00,						// CALCMODE
	0x0c, 0x00, 0x02, 0x00, 0x64, 0x00,						// CALCCOUNT
	0x0f, 0x00, 0x02, 0x00, 0x01, 0x00,						// REFMODE
	0x11, 0x00, 0x02, 0x00, 0x00, 0x00,						// ITERATION
	0x10, 0x00, 0x08, 0x00, 0xfc, 0xa9, 0xf1, 0xd2, 0x4d,	// DELTA
	0x62, 0x50, 0x3f,
    0x5f, 0x00, 0x02, 0x00, 0x01, 0x00                      // SAVERECALC
};
const sal_Size ExcDummy_02a::nMyLen = sizeof( ExcDummy_02a::pMyData );

//----------------------------------------------------------- class ExcRecord -

void ExcRecord::Save( XclExpStream& rStrm )
{
    SetRecHeader( GetNum(), GetLen() );
    XclExpRecord::Save( rStrm );
}

void ExcRecord::SaveCont( XclExpStream& /*rStrm*/ )
{
}

void ExcRecord::WriteBody( XclExpStream& rStrm )
{
    SaveCont( rStrm );
}


//--------------------------------------------------------- class ExcEmptyRec -

void ExcEmptyRec::Save( XclExpStream& /*rStrm*/ )
{
}


sal_uInt16 ExcEmptyRec::GetNum() const
{
	return 0;
}


sal_Size ExcEmptyRec::GetLen() const
{
	return 0;
}



//------------------------------------------------------- class ExcRecordList -

ExcRecordList::~ExcRecordList()
{
	for( ExcRecord* pRec = First(); pRec; pRec = Next() )
		delete pRec;
}


void ExcRecordList::Save( XclExpStream& rStrm )
{
	for( ExcRecord* pRec = First(); pRec; pRec = Next() )
		pRec->Save( rStrm );
}



//--------------------------------------------------------- class ExcDummyRec -

void ExcDummyRec::Save( XclExpStream& rStrm )
{
    rStrm.Write( GetData(), GetLen() );        // raw write mode
}


sal_uInt16 ExcDummyRec::GetNum( void ) const
{
	return 0x0000;
}



//------------------------------------------------------- class ExcBoolRecord -

void ExcBoolRecord::SaveCont( XclExpStream& rStrm )
{
	rStrm << (sal_uInt16)(bVal ? 0x0001 : 0x0000);
}


sal_Size ExcBoolRecord::GetLen( void ) const
{
	return 2;
}




//--------------------------------------------------------- class ExcBof_Base -

ExcBof_Base::ExcBof_Base() :
	nRupBuild( 0x096C ),	// copied from Excel
	nRupYear( 0x07C9 )		// copied from Excel
{
}



//-------------------------------------------------------------- class ExcBof -

ExcBof::ExcBof( void )
{
	nDocType = 0x0010;
	nVers = 0x0500;
}


void ExcBof::SaveCont( XclExpStream& rStrm )
{
	rStrm << nVers << nDocType << nRupBuild << nRupYear;
}


sal_uInt16 ExcBof::GetNum( void ) const
{
	return 0x0809;
}


sal_Size ExcBof::GetLen( void ) const
{
	return 8;
}



//------------------------------------------------------------- class ExcBofW -

ExcBofW::ExcBofW( void )
{
	nDocType = 0x0005;
	nVers = 0x0500;
}


void ExcBofW::SaveCont( XclExpStream& rStrm )
{
	rStrm << nVers << nDocType << nRupBuild << nRupYear;
}



sal_uInt16 ExcBofW::GetNum( void ) const
{
	return 0x0809;
}



sal_Size ExcBofW::GetLen( void ) const
{
	return 8;
}



//-------------------------------------------------------------- class ExcEof -

sal_uInt16 ExcEof::GetNum( void ) const
{
	return 0x000A;
}


sal_Size ExcEof::GetLen( void ) const
{
	return 0;
}



//--------------------------------------------------------- class ExcDummy_00 -

sal_Size ExcDummy_00::GetLen( void ) const
{
	return nMyLen;
}


const sal_uInt8* ExcDummy_00::GetData( void ) const
{
	return pMyData;
}



//-------------------------------------------------------- class ExcDummy_04x -

sal_Size ExcDummy_040::GetLen( void ) const
{
	return nMyLen;
}


const sal_uInt8* ExcDummy_040::GetData( void ) const
{
	return pMyData;
}




sal_Size ExcDummy_041::GetLen( void ) const
{
	return nMyLen;
}


const sal_uInt8* ExcDummy_041::GetData( void ) const
{
	return pMyData;
}



//------------------------------------------------------------- class Exc1904 -

Exc1904::Exc1904( ScDocument& rDoc )
{
	Date* pDate = rDoc.GetFormatTable()->GetNullDate();
	bVal = pDate ? (*pDate == Date( 1, 1, 1904 )) : sal_False;
}


sal_uInt16 Exc1904::GetNum( void ) const
{
	return 0x0022;
}


void Exc1904::SaveXml( XclExpXmlStream& rStrm )
{
    rStrm.WriteAttributes(
            XML_date1904, XclXmlUtils::ToPsz( bVal ),
            FSEND );
}



//------------------------------------------------------ class ExcBundlesheet -

ExcBundlesheetBase::ExcBundlesheetBase( RootData& rRootData, SCTAB nTabNum ) :
    nStrPos( STREAM_SEEK_TO_END ),
	nOwnPos( STREAM_SEEK_TO_END ),
    nGrbit( rRootData.pER->GetTabInfo().IsVisibleTab( nTabNum ) ? 0x0000 : 0x0001 ),
    nTab( nTabNum )
{
}


ExcBundlesheetBase::ExcBundlesheetBase() :
    nStrPos( STREAM_SEEK_TO_END ),
	nOwnPos( STREAM_SEEK_TO_END ),
    nGrbit( 0x0000 ),
    nTab( SCTAB_GLOBAL )
{
}


void ExcBundlesheetBase::UpdateStreamPos( XclExpStream& rStrm )
{
    rStrm.SetSvStreamPos( nOwnPos );
    rStrm.DisableEncryption();
	rStrm << static_cast<sal_uInt32>(nStrPos);
    rStrm.EnableEncryption();
}


sal_uInt16 ExcBundlesheetBase::GetNum( void ) const
{
	return 0x0085;
}




ExcBundlesheet::ExcBundlesheet( RootData& rRootData, SCTAB _nTab ) :
	ExcBundlesheetBase( rRootData, _nTab )
{
    String sTabName = rRootData.pER->GetTabInfo().GetScTabName( _nTab );
	DBG_ASSERT( sTabName.Len() < 256, "ExcBundlesheet::ExcBundlesheet - table name too long" );
    aName = ByteString( sTabName, rRootData.pER->GetTextEncoding() );
}


void ExcBundlesheet::SaveCont( XclExpStream& rStrm )
{
    nOwnPos = rStrm.GetSvStreamPos();
	rStrm	<< (sal_uInt32)	0x00000000				// dummy (stream position of the sheet)
			<< nGrbit;
	rStrm.WriteByteString( aName );				// 8 bit length, max 255 chars
}


sal_Size ExcBundlesheet::GetLen() const
{
	return 7 + Min( aName.Len(), (xub_StrLen) 255 );
}


//--------------------------------------------------------- class ExcDummy_02 -

sal_Size ExcDummy_02a::GetLen( void ) const
{
	return nMyLen;
}

const sal_uInt8* ExcDummy_02a::GetData( void ) const
{
	return pMyData;
}
//--------------------------------------------------------- class ExcDummy_02 -

XclExpCountry::XclExpCountry( const XclExpRoot& rRoot ) :
    XclExpRecord( EXC_ID_COUNTRY, 4 )
{
    /*  #i31530# set document country as UI country too -
        needed for correct behaviour of number formats. */
    mnUICountry = mnDocCountry = static_cast< sal_uInt16 >(
        ::msfilter::ConvertLanguageToCountry( rRoot.GetDocLanguage() ) );
}

void XclExpCountry::WriteBody( XclExpStream& rStrm )
{
    rStrm << mnUICountry << mnDocCountry;
}

// XclExpWsbool ===============================================================

XclExpWsbool::XclExpWsbool( bool bFitToPages, SCTAB nScTab, XclExpFilterManager* pManager )
    : XclExpUInt16Record( EXC_ID_WSBOOL, EXC_WSBOOL_DEFAULTFLAGS )
    , mnScTab( nScTab )
    , mpManager( pManager )
{
    if( bFitToPages )
        SetValue( GetValue() | EXC_WSBOOL_FITTOPAGE );
}

void XclExpWsbool::SaveXml( XclExpXmlStream& rStrm )
{
    sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
    rWorksheet->startElement( XML_sheetPr,
            // OOXTODO: XML_syncHorizontal,
            // OOXTODO: XML_syncVertical,
            // OOXTODO: XML_syncRef,
            // OOXTODO: XML_transitionEvaluation,
            // OOXTODO: XML_transitionEntry,
            // OOXTODO: XML_published,
            // OOXTODO: XML_codeName,
            XML_filterMode, mpManager ? XclXmlUtils::ToPsz( mpManager->HasFilterMode( mnScTab ) ) : NULL,
            // OOXTODO: XML_enableFormatConditionsCalculation,
            FSEND );
    // OOXTODO: elements XML_tabColor, XML_outlinePr
    rWorksheet->singleElement( XML_pageSetUpPr,
            // OOXTODO: XML_autoPageBreaks,
            XML_fitToPage,  XclXmlUtils::ToPsz( GetValue() & EXC_WSBOOL_FITTOPAGE ),
            FSEND );
    rWorksheet->endElement( XML_sheetPr );
}


// XclExpWindowProtection ===============================================================

XclExpWindowProtection::XclExpWindowProtection(bool bValue) :
	XclExpBoolRecord(EXC_ID_WINDOWPROTECT, bValue)
{
}

void XclExpWindowProtection::SaveXml( XclExpXmlStream& rStrm )
{
    rStrm.WriteAttributes(
            XML_lockWindows, XclXmlUtils::ToPsz( GetBool() ),
            FSEND );
}

// XclExpDocProtection ===============================================================

XclExpProtection::XclExpProtection(bool bValue) :
	XclExpBoolRecord(EXC_ID_PROTECT, bValue)
{
}

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

XclExpPassHash::XclExpPassHash(const Sequence<sal_Int8>& aHash) :
    XclExpRecord(EXC_ID_PASSWORD, 2),
    mnHash(0x0000)
{
    if (aHash.getLength() >= 2)
    {
        mnHash  = ((aHash[0] << 8) & 0xFFFF);
        mnHash |= (aHash[1] & 0xFF);
    }
}

XclExpPassHash::~XclExpPassHash()
{
}

void XclExpPassHash::WriteBody(XclExpStream& rStrm)
{
    rStrm << mnHash;
}

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

XclExpFiltermode::XclExpFiltermode() :
    XclExpEmptyRecord( EXC_ID_FILTERMODE )
{
}

// ----------------------------------------------------------------------------

XclExpAutofilterinfo::XclExpAutofilterinfo( const ScAddress& rStartPos, SCCOL nScCol ) :
    XclExpUInt16Record( EXC_ID_AUTOFILTERINFO, static_cast< sal_uInt16 >( nScCol ) ),
    maStartPos( rStartPos )
{
}

// ----------------------------------------------------------------------------

ExcFilterCondition::ExcFilterCondition() :
		nType( EXC_AFTYPE_NOTUSED ),
		nOper( EXC_AFOPER_EQUAL ),
		fVal( 0.0 ),
		pText( NULL )
{
}

ExcFilterCondition::~ExcFilterCondition()
{
	if( pText )
		delete pText;
}

sal_Size ExcFilterCondition::GetTextBytes() const
{
    return pText ? (1 + pText->GetBufferSize()) : 0;
}

void ExcFilterCondition::SetCondition( sal_uInt8 nTp, sal_uInt8 nOp, double fV, String* pT )
{
	nType = nTp;
	nOper = nOp;
	fVal = fV;

    delete pText;
    pText = pT ? new XclExpString( *pT, EXC_STR_8BITLENGTH ) : NULL;
}

void ExcFilterCondition::Save( XclExpStream& rStrm )
{
	rStrm << nType << nOper;
	switch( nType )
	{
		case EXC_AFTYPE_DOUBLE:
			rStrm << fVal;
		break;
		case EXC_AFTYPE_STRING:
			DBG_ASSERT( pText, "ExcFilterCondition::Save() -- pText is NULL!" );
            rStrm << (sal_uInt32)0 << (sal_uInt8) pText->Len() << (sal_uInt16)0 << (sal_uInt8)0;
		break;
		case EXC_AFTYPE_BOOLERR:
			rStrm << (sal_uInt8)0 << (sal_uInt8)((fVal != 0) ? 1 : 0) << (sal_uInt32)0 << (sal_uInt16)0;
		break;
		default:
			rStrm << (sal_uInt32)0 << (sal_uInt32)0;
	}
}

static const char* lcl_GetOperator( sal_uInt8 nOper )
{
    switch( nOper )
    {
        case EXC_AFOPER_EQUAL:          return "equal";
        case EXC_AFOPER_GREATER:        return "greaterThan";
        case EXC_AFOPER_GREATEREQUAL:   return "greaterThanOrEqual";
        case EXC_AFOPER_LESS:           return "lessThan";
        case EXC_AFOPER_LESSEQUAL:      return "lessThanOrEqual";
        case EXC_AFOPER_NOTEQUAL:       return "notEqual";
        case EXC_AFOPER_NONE:
        default:                        return "**none**";
    }
}

static OString lcl_GetValue( sal_uInt8 nType, double fVal, XclExpString* pStr )
{
    switch( nType )
    {
        case EXC_AFTYPE_STRING:     return XclXmlUtils::ToOString( *pStr );
        case EXC_AFTYPE_DOUBLE:     return OString::valueOf( fVal );
        case EXC_AFTYPE_BOOLERR:    return OString::valueOf( (sal_Int32) ( fVal != 0 ? 1 : 0 ) );
        default:                    return OString();
    }
}

void ExcFilterCondition::SaveXml( XclExpXmlStream& rStrm )
{
    if( IsEmpty() )
        return;

    rStrm.GetCurrentStream()->singleElement( XML_customFilter,
            XML_operator,   lcl_GetOperator( nOper ),
            XML_val,        lcl_GetValue( nType, fVal, pText ).getStr(),
            FSEND );
}

void ExcFilterCondition::SaveText( XclExpStream& rStrm )
{
	if( nType == EXC_AFTYPE_STRING )
	{
		DBG_ASSERT( pText, "ExcFilterCondition::SaveText() -- pText is NULL!" );
        pText->WriteFlagField( rStrm );
		pText->WriteBuffer( rStrm );
	}
}

// ----------------------------------------------------------------------------

XclExpAutofilter::XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC ) :
    XclExpRecord( EXC_ID_AUTOFILTER, 24 ),
    XclExpRoot( rRoot ),
    nCol( nC ),
    nFlags( 0 )
{
}

sal_Bool XclExpAutofilter::AddCondition( ScQueryConnect eConn, sal_uInt8 nType, sal_uInt8 nOp,
									double fVal, String* pText, sal_Bool bSimple )
{
	if( !aCond[ 1 ].IsEmpty() )
		return sal_False;

	sal_uInt16 nInd = aCond[ 0 ].IsEmpty() ? 0 : 1;

	if( nInd == 1 )
		nFlags |= (eConn == SC_OR) ? EXC_AFFLAG_OR : EXC_AFFLAG_AND;
	if( bSimple )
		nFlags |= (nInd == 0) ? EXC_AFFLAG_SIMPLE1 : EXC_AFFLAG_SIMPLE2;

	aCond[ nInd ].SetCondition( nType, nOp, fVal, pText );

    AddRecSize( aCond[ nInd ].GetTextBytes() );

	return sal_True;
}

sal_Bool XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )
{
	sal_Bool	bConflict = sal_False;
	String	sText;

	if( rEntry.pStr )
    {
        sText.Assign( *rEntry.pStr );
        switch( rEntry.eOp )
        {
            case SC_CONTAINS:
            case SC_DOES_NOT_CONTAIN:
            {
                sText.InsertAscii( "*" , 0 );
                sText.AppendAscii( "*" );
            }
            break;
            case SC_BEGINS_WITH:
            case SC_DOES_NOT_BEGIN_WITH:
                sText.AppendAscii( "*" );
            break;
            case SC_ENDS_WITH:
            case SC_DOES_NOT_END_WITH:
                sText.InsertAscii( "*" , 0 );
            break;
            default:
            {
                //nothing
            }
        }
    }

    sal_Bool bLen = sText.Len() > 0;

	// empty/nonempty fields
	if( !bLen && (rEntry.nVal == SC_EMPTYFIELDS) )
		bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_EMPTY, EXC_AFOPER_NONE, 0.0, NULL, sal_True );
	else if( !bLen && (rEntry.nVal == SC_NONEMPTYFIELDS) )
		bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_NOTEMPTY, EXC_AFOPER_NONE, 0.0, NULL, sal_True );
	// other conditions
	else
	{
		double	fVal	= 0.0;
		sal_uInt32	nIndex	= 0;
        sal_Bool    bIsNum  = bLen ? GetFormatter().IsNumberFormat( sText, nIndex, fVal ) : sal_True;
		String*	pText	= bIsNum ? NULL : &sText;

		// top10 flags
		sal_uInt16 nNewFlags = 0x0000;
		switch( rEntry.eOp )
		{
			case SC_TOPVAL:
				nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10TOP);
			break;
			case SC_BOTVAL:
				nNewFlags = EXC_AFFLAG_TOP10;
			break;
			case SC_TOPPERC:
				nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10TOP | EXC_AFFLAG_TOP10PERC);
			break;
			case SC_BOTPERC:
				nNewFlags = (EXC_AFFLAG_TOP10 | EXC_AFFLAG_TOP10PERC);
			break;
            default:;
		}
        sal_Bool bNewTop10 = ::get_flag( nNewFlags, EXC_AFFLAG_TOP10 );

		bConflict = HasTop10() && bNewTop10;
		if( !bConflict )
		{
			if( bNewTop10 )
			{
				if( fVal < 0 )		fVal = 0;
				if( fVal >= 501 )	fVal = 500;
				nFlags |= (nNewFlags | (sal_uInt16)(fVal) << 7);
			}
			// normal condition
			else
			{
				sal_uInt8 nType = bIsNum ? EXC_AFTYPE_DOUBLE : EXC_AFTYPE_STRING;
				sal_uInt8 nOper = EXC_AFOPER_NONE;

				switch( rEntry.eOp )
				{
					case SC_EQUAL:			nOper = EXC_AFOPER_EQUAL;			break;
					case SC_LESS:			nOper = EXC_AFOPER_LESS;			break;
					case SC_GREATER:		nOper = EXC_AFOPER_GREATER;			break;
					case SC_LESS_EQUAL:		nOper = EXC_AFOPER_LESSEQUAL;		break;
					case SC_GREATER_EQUAL:	nOper = EXC_AFOPER_GREATEREQUAL;	break;
					case SC_NOT_EQUAL:		nOper = EXC_AFOPER_NOTEQUAL;		break;
                    case SC_CONTAINS:
                    case SC_BEGINS_WITH:
                    case SC_ENDS_WITH:
                                            nOper = EXC_AFOPER_EQUAL;           break;
                    case SC_DOES_NOT_CONTAIN:
                    case SC_DOES_NOT_BEGIN_WITH:
                    case SC_DOES_NOT_END_WITH:
                                            nOper = EXC_AFOPER_NOTEQUAL;        break;
                    default:;
				}
				bConflict = !AddCondition( rEntry.eConnect, nType, nOper, fVal, pText );
			}
		}
	}
	return bConflict;
}

void XclExpAutofilter::WriteBody( XclExpStream& rStrm )
{
	rStrm << nCol << nFlags;
	aCond[ 0 ].Save( rStrm );
	aCond[ 1 ].Save( rStrm );
	aCond[ 0 ].SaveText( rStrm );
	aCond[ 1 ].SaveText( rStrm );
}

void XclExpAutofilter::SaveXml( XclExpXmlStream& rStrm )
{
    if( !HasCondition() )
        return;

    sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();

    rWorksheet->startElement( XML_filterColumn,
            XML_colId,          OString::valueOf( (sal_Int32) nCol ).getStr(),
            // OOXTODO: XML_hiddenButton,   AutoFilter12 fHideArrow?
            // OOXTODO: XML_showButton,
            FSEND );

    if( HasTop10() )
    {
        rWorksheet->singleElement( XML_top10,
                XML_top,        XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10TOP ) ),
                XML_percent,    XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10PERC ) ),
                XML_val,        OString::valueOf( (sal_Int32) (nFlags >> 7 ) ).getStr(),
                // OOXTODO: XML_filterVal,
                FSEND );
    }

    rWorksheet->startElement( XML_customFilters,
            XML_and,    XclXmlUtils::ToPsz( (nFlags & EXC_AFFLAG_ANDORMASK) == EXC_AFFLAG_AND ),
            FSEND );
    aCond[ 0 ].SaveXml( rStrm );
    aCond[ 1 ].SaveXml( rStrm );
    rWorksheet->endElement( XML_customFilters );
    // OOXTODO: XLM_colorFilter, XML_dynamicFilter,
    // XML_extLst, XML_filters, XML_iconFilter, XML_top10
    rWorksheet->endElement( XML_filterColumn );
}

// ----------------------------------------------------------------------------

ExcAutoFilterRecs::ExcAutoFilterRecs( const XclExpRoot& rRoot, SCTAB nTab ) :
    XclExpRoot( rRoot ),
    pFilterMode( NULL ),
    pFilterInfo( NULL )
{
    ScDBCollection& rDBColl = GetDatabaseRanges();
    XclExpNameManager& rNameMgr = GetNameManager();

	// search for first DB-range with filter
	sal_uInt16		nIndex	= 0;
	sal_Bool		bFound	= sal_False;
	sal_Bool		bAdvanced = sal_False;
	ScDBData*	pData	= NULL;
	ScRange		aAdvRange;
	while( (nIndex < rDBColl.GetCount()) && !bFound )
	{
		pData = rDBColl[ nIndex ];
		if( pData )
		{
            ScRange aRange;
			pData->GetArea( aRange );
			bAdvanced = pData->GetAdvancedQuerySource( aAdvRange );
			bFound = (aRange.aStart.Tab() == nTab) &&
				(pData->HasQueryParam() || pData->HasAutoFilter() || bAdvanced);
		}
		if( !bFound )
			nIndex++;
	}

	if( pData && bFound )
	{
		ScQueryParam	aParam;
		pData->GetQueryParam( aParam );

		ScRange	aRange( aParam.nCol1, aParam.nRow1, aParam.nTab,
						aParam.nCol2, aParam.nRow2, aParam.nTab );
		SCCOL	nColCnt = aParam.nCol2 - aParam.nCol1 + 1;

        maRef = aRange;

        // #i2394# #100489# built-in defined names must be sorted by containing sheet name
        rNameMgr.InsertBuiltInName( EXC_BUILTIN_FILTERDATABASE, aRange );

		// advanced filter
		if( bAdvanced )
		{
			// filter criteria, excel allows only same table
			if( aAdvRange.aStart.Tab() == nTab )
                rNameMgr.InsertBuiltInName( EXC_BUILTIN_CRITERIA, aAdvRange );

			// filter destination range, excel allows only same table
			if( !aParam.bInplace )
			{
				ScRange aDestRange( aParam.nDestCol, aParam.nDestRow, aParam.nDestTab );
				aDestRange.aEnd.IncCol( nColCnt - 1 );
				if( aDestRange.aStart.Tab() == nTab )
                    rNameMgr.InsertBuiltInName( EXC_BUILTIN_EXTRACT, aDestRange );
			}

            pFilterMode = new XclExpFiltermode;
		}
		// AutoFilter
		else
		{
			sal_Bool	bConflict	= sal_False;
			sal_Bool	bContLoop	= sal_True;
			sal_Bool	bHasOr		= sal_False;
			SCCOLROW nFirstField = aParam.GetEntry( 0 ).nField;

			// create AUTOFILTER records for filtered columns
			for( SCSIZE nEntry = 0; !bConflict && bContLoop && (nEntry < aParam.GetEntryCount()); nEntry++ )
			{
				const ScQueryEntry& rEntry	= aParam.GetEntry( nEntry );

				bContLoop = rEntry.bDoQuery;
				if( bContLoop )
				{
                    XclExpAutofilter* pFilter = GetByCol( static_cast<SCCOL>(rEntry.nField) - aRange.aStart.Col() );

					if( nEntry > 0 )
						bHasOr |= (rEntry.eConnect == SC_OR);

					bConflict = (nEntry > 1) && bHasOr;
					if( !bConflict )
						bConflict = (nEntry == 1) && (rEntry.eConnect == SC_OR) &&
									(nFirstField != rEntry.nField);
					if( !bConflict )
                        bConflict = pFilter->AddEntry( rEntry );
				}
			}

			// additional tests for conflicts
            for( size_t nPos = 0, nSize = maFilterList.GetSize(); !bConflict && (nPos < nSize); ++nPos )
            {
                XclExpAutofilterRef xFilter = maFilterList.GetRecord( nPos );
                bConflict = xFilter->HasCondition() && xFilter->HasTop10();
            }

			if( bConflict )
                maFilterList.RemoveAllRecords();

            if( !maFilterList.IsEmpty() )
                pFilterMode = new XclExpFiltermode;
            pFilterInfo = new XclExpAutofilterinfo( aRange.aStart, nColCnt );
		}
	}
}

ExcAutoFilterRecs::~ExcAutoFilterRecs()
{
    delete pFilterMode;
    delete pFilterInfo;
}

XclExpAutofilter* ExcAutoFilterRecs::GetByCol( SCCOL nCol )
{
    XclExpAutofilterRef xFilter;
    for( size_t nPos = 0, nSize = maFilterList.GetSize(); nPos < nSize; ++nPos )
    {
        xFilter = maFilterList.GetRecord( nPos );
        if( xFilter->GetCol() == static_cast<sal_uInt16>(nCol) )
            return xFilter.get();
    }
    xFilter.reset( new XclExpAutofilter( GetRoot(), static_cast<sal_uInt16>(nCol) ) );
    maFilterList.AppendRecord( xFilter );
    return xFilter.get();
}

sal_Bool ExcAutoFilterRecs::IsFiltered( SCCOL nCol )
{
    for( size_t nPos = 0, nSize = maFilterList.GetSize(); nPos < nSize; ++nPos )
        if( maFilterList.GetRecord( nPos )->GetCol() == static_cast<sal_uInt16>(nCol) )
			return sal_True;
	return sal_False;
}

void ExcAutoFilterRecs::AddObjRecs()
{
    if( pFilterInfo )
    {
        ScAddress aAddr( pFilterInfo->GetStartPos() );
        for( SCCOL nObj = 0, nCount = pFilterInfo->GetColCount(); nObj < nCount; nObj++ )
        {
            XclObj* pObjRec = new XclObjDropDown( GetObjectManager(), aAddr, IsFiltered( nObj ) );
            GetObjectManager().AddObj( pObjRec );
            aAddr.IncCol( 1 );
        }
    }
}

void ExcAutoFilterRecs::Save( XclExpStream& rStrm )
{
	if( pFilterMode )
		pFilterMode->Save( rStrm );
	if( pFilterInfo )
		pFilterInfo->Save( rStrm );
    maFilterList.Save( rStrm );
}

void ExcAutoFilterRecs::SaveXml( XclExpXmlStream& rStrm )
{
    if( maFilterList.IsEmpty() )
        return;

    sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
    rWorksheet->startElement( XML_autoFilter,
            XML_ref,    XclXmlUtils::ToOString( maRef ).getStr(),
            FSEND );
    // OOXTODO: XML_extLst, XML_sortState
    maFilterList.SaveXml( rStrm );
    rWorksheet->endElement( XML_autoFilter );
}

bool ExcAutoFilterRecs::HasFilterMode() const
{
    return pFilterMode != NULL;
}

// ----------------------------------------------------------------------------

XclExpFilterManager::XclExpFilterManager( const XclExpRoot& rRoot ) :
    XclExpRoot( rRoot )
{
}

void XclExpFilterManager::InitTabFilter( SCTAB nScTab )
{
    maFilterMap[ nScTab ].reset( new ExcAutoFilterRecs( GetRoot(), nScTab ) );
}

XclExpRecordRef XclExpFilterManager::CreateRecord( SCTAB nScTab )
{
    XclExpTabFilterRef xRec;
    XclExpTabFilterMap::iterator aIt = maFilterMap.find( nScTab );
    if( aIt != maFilterMap.end() )
    {
        xRec = aIt->second;
        xRec->AddObjRecs();
    }
    return xRec;
}

bool XclExpFilterManager::HasFilterMode( SCTAB nScTab )
{
    XclExpTabFilterRef xRec;
    XclExpTabFilterMap::iterator aIt = maFilterMap.find( nScTab );
    if( aIt != maFilterMap.end() )
    {
        return aIt->second->HasFilterMode();
    }
    return false;
}

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

