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

// System - Includes ---------------------------------------------------------



// INCLUDE -------------------------------------------------------------------
#include <sfx2/dispatch.hxx>

#include "uiitems.hxx"
#include "rangenam.hxx"
#include "dbcolect.hxx"
#include "reffact.hxx"
#include "viewdata.hxx"
#include "document.hxx"
#include "docsh.hxx"
#include "scresid.hxx"

#include "foptmgr.hxx"

#include "globstr.hrc"
#include "filter.hrc"

#define _SFILTDLG_CXX
#include "filtdlg.hxx"
#undef _SFILTDLG_CXX
#include <vcl/msgbox.hxx>

// DEFINE --------------------------------------------------------------------

#define ERRORBOX(rid) ErrorBox( this, WinBits( WB_OK|WB_DEF_OK),\
				 	   			ScGlobal::GetRscString(rid) ).Execute()


//============================================================================
//	class ScSpecialFilterDialog

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

ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
										const SfxItemSet&	rArgSet )

	:	ScAnyRefDlg	( pB, pCW, pParent, RID_SCDLG_SPEC_FILTER ),
		//
		aFtFilterArea	( this, ScResId( FT_CRITERIA_AREA ) ),
		aLbFilterArea	( this, ScResId( LB_CRITERIA_AREA ) ),
        aEdFilterArea   ( this, this, ScResId( ED_CRITERIA_AREA ) ),
		aRbFilterArea	( this, ScResId( RB_CRITERIA_AREA ), &aEdFilterArea, this ),
		//
        aFlOptions      ( this, ScResId( FL_OPTIONS ) ),
		_INIT_COMMON_FILTER_RSCOBJS
        aBtnOk          ( this, ScResId( BTN_OK ) ),
        aBtnCancel      ( this, ScResId( BTN_CANCEL ) ),
        aBtnHelp        ( this, ScResId( BTN_HELP ) ),
        aBtnMore        ( this, ScResId( BTN_MORE ) ),
		//
		pOptionsMgr		( NULL ),
		nWhichQuery		( rArgSet.GetPool()->GetWhich( SID_QUERY ) ),
		theQueryData	( ((const ScQueryItem&)
						   rArgSet.Get( nWhichQuery )).GetQueryData() ),
		pOutItem		( NULL ),
		pViewData		( NULL ),
		pDoc			( NULL ),
		pRefInputEdit	( NULL ),
		bRefInputMode	( sal_False ),
		pTimer			( NULL )
{
	Init( rArgSet );
	aEdFilterArea.GrabFocus();

	FreeResource();

	// Hack: RefInput-Kontrolle
	pTimer = new Timer;
	pTimer->SetTimeout( 50 ); // 50ms warten
	pTimer->SetTimeoutHdl( LINK( this, ScSpecialFilterDlg, TimeOutHdl ) );
	pTimer->Start();

	aLbCopyArea.SetAccessibleName(aBtnCopyResult.GetText());
	aEdCopyArea.SetAccessibleName(aBtnCopyResult.GetText());
	aLbCopyArea.SetAccessibleRelationLabeledBy(&aBtnCopyResult);
	aEdCopyArea.SetAccessibleRelationLabeledBy(&aBtnCopyResult);
}


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

__EXPORT ScSpecialFilterDlg::~ScSpecialFilterDlg()
{
	sal_uInt16 nEntries = aLbFilterArea.GetEntryCount();
	sal_uInt16 i;

	for ( i=1; i<nEntries; i++ )
		delete (String*)aLbFilterArea.GetEntryData( i );

	delete pOptionsMgr;

	if ( pOutItem )
		delete pOutItem;

	// Hack: RefInput-Kontrolle
	pTimer->Stop();
	delete pTimer;
}


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

void __EXPORT ScSpecialFilterDlg::Init( const SfxItemSet& rArgSet )
{
	const ScQueryItem& rQueryItem = (const ScQueryItem&)
									rArgSet.Get( nWhichQuery );

	aBtnOk.SetClickHdl			( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
	aBtnCancel.SetClickHdl		( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
	aLbFilterArea.SetSelectHdl	( LINK( this, ScSpecialFilterDlg, FilterAreaSelHdl ) );
	aEdFilterArea.SetModifyHdl	( LINK( this, ScSpecialFilterDlg, FilterAreaModHdl ) );

	pViewData 	= rQueryItem.GetViewData();
	pDoc	  	= pViewData ? pViewData->GetDocument()  : NULL;

	aEdFilterArea.SetText( EMPTY_STRING );		// may be overwritten below

	if ( pViewData && pDoc )
	{
		if(pDoc->GetChangeTrack()!=NULL) aBtnCopyResult.Disable();

		ScRangeName*	pRangeNames	= pDoc->GetRangeName();
		const sal_uInt16	nCount 		= pRangeNames ? pRangeNames->GetCount() : 0;

		/*
		 * Aus den RangeNames des Dokumentes werden nun die
		 * gemerkt, bei denen es sich um Filter-Bereiche handelt
		 */

		aLbFilterArea.Clear();
		aLbFilterArea.InsertEntry( aStrUndefined, 0 );

		if ( nCount > 0 )
		{
			String		 aString;
			ScRangeData* pData = NULL;
			sal_uInt16		 nInsert = 0;

			for ( sal_uInt16 i=0; i<nCount; i++ )
			{
				pData = (ScRangeData*)(pRangeNames->At( i ));
				if ( pData )
				{
					if ( pData->HasType( RT_CRITERIA ) )
					{
						pData->GetName( aString );
						nInsert = aLbFilterArea.InsertEntry( aString );
						pData->GetSymbol( aString );
						aLbFilterArea.SetEntryData( nInsert,
													new String( aString ) );
					}
				}
			}
		}

		//	is there a stored source range?

		ScRange aAdvSource;
		if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
		{
			String aRefStr;
			aAdvSource.Format( aRefStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
			aEdFilterArea.SetRefString( aRefStr );
		}
	}

	aLbFilterArea.SelectEntryPos( 0 );

	// Optionen initialisieren lassen:

	pOptionsMgr	 = new ScFilterOptionsMgr(
							this,
							pViewData,
							theQueryData,
							aBtnMore,
							aBtnCase,
							aBtnRegExp,
							aBtnHeader,
							aBtnUnique,
							aBtnCopyResult,
							aBtnDestPers,
							aLbCopyArea,
							aEdCopyArea,
							aRbCopyArea,
							aFtDbAreaLabel,
							aFtDbArea,
                            aFlOptions,
							aStrNoName,
							aStrUndefined );

	//	#35206# Spezialfilter braucht immer Spaltenkoepfe
	aBtnHeader.Check(sal_True);
	aBtnHeader.Disable();

	// Modal-Modus einschalten
//	SetDispatcherLock( sal_True );
	//@BugID 54702 Enablen/Disablen nur noch in Basisklasse
	//SFX_APPWINDOW->Disable(sal_False);		//! allgemeine Methode im ScAnyRefDlg
}


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

sal_Bool __EXPORT ScSpecialFilterDlg::Close()
{
    if (pViewData)
        pViewData->GetDocShell()->CancelAutoDBRange();

	return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
}


//----------------------------------------------------------------------------
// Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
// neue Selektion im Referenz-Edit angezeigt wird.

void ScSpecialFilterDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
{
	if ( bRefInputMode && pRefInputEdit )		// Nur moeglich, wenn im Referenz-Editmodus
	{
		if ( rRef.aStart != rRef.aEnd )
			RefInputStart( pRefInputEdit );

		String aRefStr;
        const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention();

		if ( pRefInputEdit == &aEdCopyArea)
			rRef.aStart.Format( aRefStr, SCA_ABS_3D, pDocP, eConv );
		else if ( pRefInputEdit == &aEdFilterArea)
			rRef.Format( aRefStr, SCR_ABS_3D, pDocP, eConv );

		pRefInputEdit->SetRefString( aRefStr );
	}
}


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

void ScSpecialFilterDlg::SetActive()
{
	if ( bRefInputMode )
	{
		if ( pRefInputEdit == &aEdCopyArea )
		{
			aEdCopyArea.GrabFocus();
			if ( aEdCopyArea.GetModifyHdl().IsSet() )
				((Link&)aEdCopyArea.GetModifyHdl()).Call( &aEdCopyArea );
		}
		else if ( pRefInputEdit == &aEdFilterArea )
		{
			aEdFilterArea.GrabFocus();
			FilterAreaModHdl( &aEdFilterArea );
		}
	}
	else
		GrabFocus();

	RefInputDone();
}


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

ScQueryItem* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam& rParam,
												const ScRange& rSource )
{
	if ( pOutItem ) DELETEZ( pOutItem );
	pOutItem = new ScQueryItem( nWhichQuery, &rParam );
	pOutItem->SetAdvancedQuerySource( &rSource );

	return pOutItem;
}


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

sal_Bool ScSpecialFilterDlg::IsRefInputMode() const
{
	return bRefInputMode;
}


//----------------------------------------------------------------------------
// Handler:
// ========

IMPL_LINK( ScSpecialFilterDlg, EndDlgHdl, Button*, pBtn )
{
	DBG_ASSERT( pDoc && pViewData, "Document or ViewData not found. :-/" );

	if ( (pBtn == &aBtnOk) && pDoc && pViewData )
	{
		String			theCopyStr( aEdCopyArea.GetText() );
		String			theAreaStr( aEdFilterArea.GetText() );
		ScQueryParam	theOutParam( theQueryData );
		ScAddress		theAdrCopy;
		sal_Bool			bEditInputOk	= sal_True;
		sal_Bool			bQueryOk		= sal_False;
		ScRange			theFilterArea;
        const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();

		if ( aBtnCopyResult.IsChecked() )
		{
			xub_StrLen nColonPos = theCopyStr.Search( ':' );

			if ( STRING_NOTFOUND != nColonPos )
				theCopyStr.Erase( nColonPos );

			sal_uInt16 nResult = theAdrCopy.Parse( theCopyStr, pDoc, eConv );

			if ( SCA_VALID != (nResult & SCA_VALID) )
			{
				if ( !aBtnMore.GetState() )
					aBtnMore.SetState( sal_True );

				ERRORBOX( STR_INVALID_TABREF );
				aEdCopyArea.GrabFocus();
				bEditInputOk = sal_False;
			}
		}

		if ( bEditInputOk )
		{
			sal_uInt16 nResult = ScRange().Parse( theAreaStr, pDoc, eConv );

			if ( SCA_VALID != (nResult & SCA_VALID) )
			{
				ERRORBOX( STR_INVALID_TABREF );
				aEdFilterArea.GrabFocus();
				bEditInputOk = sal_False;
			}
		}

		if ( bEditInputOk )
		{
			/*
			 * Alle Edit-Felder enthalten gueltige Bereiche.
			 * Nun wird versucht aus dem Filterbereich
			 * ein ScQueryParam zu erzeugen:
			 */

			sal_uInt16	nResult = theFilterArea.Parse( theAreaStr, pDoc, eConv );

			if ( SCA_VALID == (nResult & SCA_VALID) )
			{
				ScAddress& rStart = theFilterArea.aStart;
				ScAddress& rEnd   = theFilterArea.aEnd;

				if ( aBtnCopyResult.IsChecked() )
				{
					theOutParam.bInplace	= sal_False;
					theOutParam.nDestTab	= theAdrCopy.Tab();
					theOutParam.nDestCol	= theAdrCopy.Col();
					theOutParam.nDestRow	= theAdrCopy.Row();
				}
				else
				{
					theOutParam.bInplace	= sal_True;
					theOutParam.nDestTab	= 0;
					theOutParam.nDestCol	= 0;
					theOutParam.nDestRow	= 0;
				}

				theOutParam.bHasHeader = aBtnHeader.IsChecked();
				theOutParam.bByRow	   = sal_True;
				theOutParam.bCaseSens  = aBtnCase.IsChecked();
				theOutParam.bRegExp	   = aBtnRegExp.IsChecked();
				theOutParam.bDuplicate = !aBtnUnique.IsChecked();
				theOutParam.bDestPers  = aBtnDestPers.IsChecked();

				bQueryOk =
					pDoc->CreateQueryParam( rStart.Col(),
											rStart.Row(),
											rEnd.Col(),
											rEnd.Row(),
											rStart.Tab(),
											theOutParam );

				//	an der DB-Collection koennen nur MAXQUERY Filter-Eintraege
				//	gespeichert werden

				if ( bQueryOk && theOutParam.GetEntryCount() > MAXQUERY &&
					 theOutParam.GetEntry(MAXQUERY).bDoQuery )
				{
					bQueryOk = sal_False;		// zu viele
											//!	andere Fehlermeldung ??
				}
			}
		}

		if ( bQueryOk )
		{
			SetDispatcherLock( sal_False );
			SwitchToDocument();
			GetBindings().GetDispatcher()->Execute( FID_FILTER_OK,
									  SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
									  GetOutputItem( theOutParam, theFilterArea ), 0L, 0L );
			Close();
		}
		else
		{
			ERRORBOX( STR_INVALID_QUERYAREA );
			aEdFilterArea.GrabFocus();
		}
	}
	else if ( pBtn == &aBtnCancel )
	{
		Close();
	}
	return 0;	
}


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

IMPL_LINK( ScSpecialFilterDlg, TimeOutHdl, Timer*, _pTimer )
{
    // alle 50ms nachschauen, ob RefInputMode noch stimmt

    if( (_pTimer == pTimer) && IsActive() )
    {
        if( aEdCopyArea.HasFocus() || aRbCopyArea.HasFocus() )
        {
            pRefInputEdit = &aEdCopyArea;
            bRefInputMode = sal_True;
        }
        else if( aEdFilterArea.HasFocus() || aRbFilterArea.HasFocus() )
        {
            pRefInputEdit = &aEdFilterArea;
            bRefInputMode = sal_True;
        }
        else if( bRefInputMode )
        {
            pRefInputEdit = NULL;
            bRefInputMode = sal_False;
        }
    }

    pTimer->Start();

	return 0;
}


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

IMPL_LINK( ScSpecialFilterDlg, FilterAreaSelHdl, ListBox*, pLb )
{
	if ( pLb == &aLbFilterArea )
	{
		String	aString;
		sal_uInt16	nSelPos = aLbFilterArea.GetSelectEntryPos();

		if ( nSelPos > 0 )
			aString = *(String*)aLbFilterArea.GetEntryData( nSelPos );

		aEdFilterArea.SetText( aString );
	}

	return 0;
}


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

IMPL_LINK( ScSpecialFilterDlg, FilterAreaModHdl, formula::RefEdit*, pEd )
{
	if ( pEd == &aEdFilterArea )
	{
		if ( pDoc && pViewData )
		{
			String	theCurAreaStr = pEd->GetText();
			sal_uInt16	nResult	= ScRange().Parse( theCurAreaStr, pDoc );

			if ( SCA_VALID == (nResult & SCA_VALID) )
			{
				String*	pStr	= NULL;
				sal_Bool	bFound	= sal_False;
				sal_uInt16	i		= 0;
				sal_uInt16	nCount	= aLbFilterArea.GetEntryCount();

				for ( i=1; i<nCount && !bFound; i++ )
				{
					pStr = (String*)aLbFilterArea.GetEntryData( i );
					bFound = (theCurAreaStr == *pStr);
				}

				if ( bFound )
					aLbFilterArea.SelectEntryPos( --i );
				else
					aLbFilterArea.SelectEntryPos( 0 );
			}
		}
		else
			aLbFilterArea.SelectEntryPos( 0 );
	}

	return 0;
}


