/**************************************************************
 * 
 * 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 <sfx2/dispatch.hxx>

// INCLUDE -------------------------------------------------------------------

#include "tabvwsh.hxx"
#include "uiitems.hxx"
#include "dbcolect.hxx"
#include "rangenam.hxx"
#include "rangeutl.hxx"
#include "reffact.hxx"
#include "document.hxx"
#include "scresid.hxx"

#include "globstr.hrc"
#include "consdlg.hrc"

#define _CONSDLG_CXX
#include "consdlg.hxx"
#undef _CONSDLG_CXX
#include <vcl/msgbox.hxx>

#define INFOBOX(id) InfoBox(this, ScGlobal::GetRscString(id)).Execute()

//============================================================================
//	class ScAreaData

class ScAreaData
{
public:
	ScAreaData()  {}
	~ScAreaData() {}

	void Set( const String& rName, const String& rArea, sal_Bool bDb )
				{
					aStrName  = rName;
					aStrArea  = rArea;
					bIsDbArea = bDb;
				}

	String	aStrName;
	String	aStrArea;
	sal_Bool	bIsDbArea;
};


//============================================================================
//	class ScConsolidateDialog


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

	:	ScAnyRefDlg	( pB, pCW, pParent, RID_SCDLG_CONSOLIDATE ),
		//
		aFtFunc			( this, ScResId( FT_FUNC ) ),
		aLbFunc			( this, ScResId( LB_FUNC ) ),

		aFtConsAreas	( this, ScResId( FT_CONSAREAS ) ),
		aLbConsAreas	( this, ScResId( LB_CONSAREAS ) ),

		aLbDataArea		( this, ScResId( LB_DATA_AREA ) ),
		aFtDataArea		( this, ScResId( FT_DATA_AREA ) ),
        aEdDataArea     ( this, this, ScResId( ED_DATA_AREA ) ),
		aRbDataArea		( this, ScResId( RB_DATA_AREA ), &aEdDataArea, this ),

		aLbDestArea		( this, ScResId( LB_DEST_AREA ) ),
		aFtDestArea		( this, ScResId( FT_DEST_AREA ) ),
        aEdDestArea     ( this, this, ScResId( ED_DEST_AREA ) ),
		aRbDestArea		( this, ScResId( RB_DEST_AREA ), &aEdDestArea, this),

        aFlConsBy       ( this, ScResId( FL_CONSBY ) ),
		aBtnByRow		( this, ScResId( BTN_BYROW ) ),
		aBtnByCol		( this, ScResId( BTN_BYCOL) ),

        aFlSep          ( this, ScResId( FL_SEP ) ),
        aFlOptions      ( this, ScResId( FL_OPTIONS ) ),
		aBtnRefs		( this, ScResId( BTN_REFS ) ),

		aBtnOk			( this, ScResId( BTN_OK ) ),
		aBtnCancel		( this, ScResId( BTN_CANCEL ) ),
		aBtnHelp		( this, ScResId( BTN_HELP ) ),
		aBtnAdd			( this, ScResId( BTN_ADD ) ),
		aBtnRemove		( this, ScResId( BTN_REMOVE ) ),
		aBtnMore		( this, ScResId( BTN_MORE ) ),

		aStrUndefined	( ScResId( SCSTR_UNDEFINED ) ),
		//
		theConsData		( ((const ScConsolidateItem&)
						   rArgSet.Get( rArgSet.GetPool()->
											GetWhich( SID_CONSOLIDATE ) )
									  ).GetData() ),
		pViewData		( ((ScTabViewShell*)SfxViewShell::Current())->
								GetViewData() ),
		pDoc			( ((ScTabViewShell*)SfxViewShell::Current())->
								GetViewData()->GetDocument() ),
		pRangeUtil		( new ScRangeUtil ),
		pAreaData		( NULL ),
		nAreaDataCount	( 0 ),
		nWhichCons		( rArgSet.GetPool()->GetWhich( SID_CONSOLIDATE ) ),

		pRefInputEdit	( &aEdDataArea )
{
	Init();
	FreeResource();
}


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

__EXPORT ScConsolidateDlg::~ScConsolidateDlg()
{
	delete [] pAreaData;
	delete pRangeUtil;
}


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

void ScConsolidateDlg::Init()
{
	DBG_ASSERT( pViewData && pDoc && pRangeUtil, "Error in Ctor" );

	String aStr;
	sal_uInt16 i=0;

	aEdDataArea	.SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
	aEdDestArea	.SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
	aLbDataArea .SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
	aLbDestArea .SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
	aEdDataArea	.SetModifyHdl	( LINK( this, ScConsolidateDlg, ModifyHdl ) );
	aEdDestArea	.SetModifyHdl	( LINK( this, ScConsolidateDlg, ModifyHdl ) );
	aLbConsAreas.SetSelectHdl	( LINK( this, ScConsolidateDlg, SelectHdl ) );
	aLbDataArea .SetSelectHdl	( LINK( this, ScConsolidateDlg, SelectHdl ) );
	aLbDestArea .SetSelectHdl	( LINK( this, ScConsolidateDlg, SelectHdl ) );
	aBtnOk		.SetClickHdl	( LINK( this, ScConsolidateDlg, OkHdl ) );
	aBtnCancel	.SetClickHdl	( LINK( this, ScConsolidateDlg, ClickHdl ) );
	aBtnAdd		.SetClickHdl	( LINK( this, ScConsolidateDlg, ClickHdl ) );
	aBtnRemove	.SetClickHdl	( LINK( this, ScConsolidateDlg, ClickHdl ) );

    aBtnMore.AddWindow( &aFlConsBy );
	aBtnMore.AddWindow( &aBtnByRow );
	aBtnMore.AddWindow( &aBtnByCol );
    aBtnMore.AddWindow( &aFlSep );
    aBtnMore.AddWindow( &aFlOptions );
	aBtnMore.AddWindow( &aBtnRefs );

	aBtnAdd.Disable();
	aBtnRemove.Disable();

	aBtnByRow.Check( theConsData.bByRow );
	aBtnByCol.Check( theConsData.bByCol );
	aBtnRefs .Check( theConsData.bReferenceData );

	aLbFunc.SelectEntryPos( FuncToLbPos( theConsData.eFunction ) );

	// Einlesen der Konsolidierungsbereiche
	aLbConsAreas.Clear();
    const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
	for ( i=0; i<theConsData.nDataAreaCount; i++ )
	{
		const ScArea& rArea = *(theConsData.ppDataAreas[i] );
		if ( rArea.nTab < pDoc->GetTableCount() )
		{
            ScRange( rArea.nColStart, rArea.nRowStart, rArea.nTab,
                    rArea.nColEnd, rArea.nRowEnd, rArea.nTab ).Format( aStr,
                        SCR_ABS_3D, pDoc, eConv );
            aLbConsAreas.InsertEntry( aStr );
        }
    }

	if ( theConsData.nTab < pDoc->GetTableCount() )
    {
        ScAddress( theConsData.nCol, theConsData.nRow, theConsData.nTab
                ).Format( aStr, SCA_ABS_3D, pDoc, eConv );
        aEdDestArea.SetText( aStr );
    }
	else
		aEdDestArea.SetText( EMPTY_STRING );

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

	/*
	 * Aus den RangeNames und Datenbankbereichen werden sich
	 * in der Hilfsklasse ScAreaData die Bereichsnamen gemerkt,
	 * die in den ListBoxen erscheinen.
	 */

	ScRangeName*    pRangeNames  = pDoc->GetRangeName();
	ScDBCollection* pDbNames     = pDoc->GetDBCollection();
	const sal_uInt16    nRangeCount  = pRangeNames ? pRangeNames->GetCount() : 0;
	const sal_uInt16    nDbCount	 = pDbNames	   ? pDbNames   ->GetCount() : 0;

	nAreaDataCount = nRangeCount+nDbCount;
	pAreaData	   = NULL;

	if ( nAreaDataCount > 0 )
	{
		pAreaData = new ScAreaData[nAreaDataCount];

		String aStrName;
		String aStrArea;
		sal_uInt16 nAt = 0;
		ScRange aRange;
		ScAreaNameIterator aIter( pDoc );
		while ( aIter.Next( aStrName, aRange ) )
		{
			aRange.Format( aStrArea, SCA_ABS_3D, pDoc, eConv );
			pAreaData[nAt++].Set( aStrName, aStrArea, aIter.WasDBName() );
		}
	}

	FillAreaLists();
	ModifyHdl( &aEdDestArea );
	aLbDataArea.SelectEntryPos( 0 );
	aEdDataArea.SetText( EMPTY_STRING );
	aEdDataArea.GrabFocus();

    aFlSep.SetStyle( aFlSep.GetStyle() | WB_VERT );

	//@BugID 54702 Enablen/Disablen nur noch in Basisklasse
	//SFX_APPWINDOW->Enable();
}


//----------------------------------------------------------------------------
void ScConsolidateDlg::FillAreaLists()
{
	aLbDataArea.Clear();
	aLbDestArea.Clear();
	aLbDataArea.InsertEntry( aStrUndefined );
	aLbDestArea.InsertEntry( aStrUndefined );

	if ( pRangeUtil && pAreaData && (nAreaDataCount > 0) )
	{
		String aString;

		for ( sal_uInt16 i=0;
			  (i<nAreaDataCount) && (pAreaData[i].aStrName.Len()>0);
			  i++ )
		{
			aLbDataArea.InsertEntry( pAreaData[i].aStrName, i+1 );

//			if ( !pAreaData[i].bIsDbArea )
				aLbDestArea.InsertEntry( pAreaData[i].aStrName, i+1 );
		}
	}
}


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


void ScConsolidateDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
{
	if ( pRefInputEdit )
	{
		if ( rRef.aStart != rRef.aEnd )
			RefInputStart( pRefInputEdit );

		String		aStr;
		sal_uInt16	 	nFmt = SCR_ABS_3D;		 //!!! nCurTab fehlt noch
        const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention();

		if ( rRef.aStart.Tab() != rRef.aEnd.Tab() )
			nFmt |= SCA_TAB2_3D;

		if ( pRefInputEdit == &aEdDataArea)
            rRef.Format( aStr, nFmt, pDocP, eConv );
		else if ( pRefInputEdit == &aEdDestArea )
            rRef.aStart.Format( aStr, nFmt, pDocP, eConv );

		pRefInputEdit->SetRefString( aStr );
	}

	ModifyHdl( pRefInputEdit );
}


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

sal_Bool __EXPORT ScConsolidateDlg::Close()
{
	return DoClose( ScConsolidateDlgWrapper::GetChildWindowId() );
}


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

void ScConsolidateDlg::SetActive()
{
	if ( bDlgLostFocus )
	{
		bDlgLostFocus = sal_False;

		if ( pRefInputEdit )
		{
			pRefInputEdit->GrabFocus();
			ModifyHdl( pRefInputEdit );
		}
	}
	else
		GrabFocus();

	RefInputDone();
}


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

void __EXPORT ScConsolidateDlg::Deactivate()
{
	bDlgLostFocus = sal_True;
}


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

sal_Bool ScConsolidateDlg::VerifyEdit( formula::RefEdit* pEd )
{
	if ( !pRangeUtil || !pDoc || !pViewData ||
		 ((pEd != &aEdDataArea) && (pEd != &aEdDestArea)) )
		return sal_False;

	SCTAB	nTab	= pViewData->GetTabNo();
	sal_Bool	bEditOk = sal_False;
	String	theCompleteStr;
    const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();

	if ( pEd == &aEdDataArea )
	{
		bEditOk = pRangeUtil->IsAbsArea( pEd->GetText(), pDoc,
										 nTab, &theCompleteStr, NULL, NULL, eConv );
	}
	else if ( pEd == &aEdDestArea )
	{
		String aPosStr;

		pRangeUtil->CutPosString( pEd->GetText(), aPosStr );
		bEditOk = pRangeUtil->IsAbsPos( aPosStr, pDoc,
										nTab, &theCompleteStr, NULL, eConv );
	}

	if ( bEditOk )
		pEd->SetText( theCompleteStr );

	return bEditOk;
}


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

IMPL_LINK( ScConsolidateDlg, GetFocusHdl, Control*, pCtr )
{
	if ( pCtr ==(Control*)&aEdDataArea ||
		 pCtr ==(Control*)&aEdDestArea)
	{
		pRefInputEdit = (formula::RefEdit*)pCtr;
	}
	else if(pCtr ==(Control*)&aLbDataArea )
	{
		pRefInputEdit = &aEdDataArea;
	}
	else if(pCtr ==(Control*)&aLbDestArea )
	{
		pRefInputEdit = &aEdDestArea;
	}
	return 0;
}


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

IMPL_LINK( ScConsolidateDlg, OkHdl, void*, EMPTYARG )
{
	sal_uInt16 nDataAreaCount = aLbConsAreas.GetEntryCount();

	if ( nDataAreaCount > 0 )
	{
		ScRefAddress aDestAddress;
		SCTAB		nTab = pViewData->GetTabNo();
		String		aDestPosStr( aEdDestArea.GetText() );
        const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();

		if ( pRangeUtil->IsAbsPos( aDestPosStr, pDoc, nTab, NULL, &aDestAddress, eConv ) )
		{
			ScConsolidateParam	theOutParam( theConsData );
			ScArea**			ppDataAreas = new ScArea*[nDataAreaCount];
			ScArea*				pArea;
			sal_uInt16				i=0;

			for ( i=0; i<nDataAreaCount; i++ )
			{
				pArea = new ScArea;
				pRangeUtil->MakeArea( aLbConsAreas.GetEntry( i ),
									  *pArea, pDoc, nTab, eConv );
				ppDataAreas[i] = pArea;
			}

			theOutParam.nCol			= aDestAddress.Col();
			theOutParam.nRow			= aDestAddress.Row();
			theOutParam.nTab			= aDestAddress.Tab();
			theOutParam.eFunction		= LbPosToFunc( aLbFunc.GetSelectEntryPos() );
			theOutParam.bByCol			= aBtnByCol.IsChecked();
			theOutParam.bByRow			= aBtnByRow.IsChecked();
			theOutParam.bReferenceData	= aBtnRefs.IsChecked();
			theOutParam.SetAreas( ppDataAreas, nDataAreaCount );

			for ( i=0; i<nDataAreaCount; i++ )
				delete ppDataAreas[i];
			delete [] ppDataAreas;

			ScConsolidateItem aOutItem( nWhichCons, &theOutParam );

			SetDispatcherLock( sal_False );
			SwitchToDocument();
			GetBindings().GetDispatcher()->Execute( SID_CONSOLIDATE,
									  SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
									  &aOutItem, 0L, 0L );
			Close();
		}
		else
		{
			INFOBOX( STR_INVALID_TABREF );
			aEdDestArea.GrabFocus();
		}
	}
	else
		Close(); // keine Datenbereiche definiert -> Cancel
	return 0;
}


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

IMPL_LINK( ScConsolidateDlg, ClickHdl, PushButton*, pBtn )
{
	if ( pBtn == &aBtnCancel )
		Close();
	else if ( pBtn == &aBtnAdd )
	{
		if ( aEdDataArea.GetText().Len() > 0 )
		{
			String		aNewEntry( aEdDataArea.GetText() );
			ScArea**	ppAreas = NULL;
			sal_uInt16		nAreaCount = 0;
            const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();

			if ( pRangeUtil->IsAbsTabArea( aNewEntry, pDoc, &ppAreas, &nAreaCount, sal_True, eConv ) )
			{
				// IsAbsTabArea() legt ein Array von ScArea-Zeigern an,
				// welche ebenfalls dynamisch erzeugt wurden.
				// Diese Objekte muessen hier abgeraeumt werden.

				for ( sal_uInt16 i=0; i<nAreaCount; i++ )
				{
					String aNewArea;

					if ( ppAreas[i] )
					{
                        const ScArea& rArea = *(ppAreas[i]);
                        ScRange( rArea.nColStart, rArea.nRowStart, rArea.nTab,
                                rArea.nColEnd, rArea.nRowEnd, rArea.nTab
                                ).Format( aNewArea, SCR_ABS_3D, pDoc, eConv );

						if ( aLbConsAreas.GetEntryPos( aNewArea )
							 == LISTBOX_ENTRY_NOTFOUND )
						{
							aLbConsAreas.InsertEntry( aNewArea );
						}
						delete ppAreas[i];
					}
				}
				delete [] ppAreas;
			}
			else if ( VerifyEdit( &aEdDataArea ) )
			{
				String aNewArea( aEdDataArea.GetText() );

				if ( aLbConsAreas.GetEntryPos( aNewArea ) == LISTBOX_ENTRY_NOTFOUND )
					aLbConsAreas.InsertEntry( aNewArea );
				else
					INFOBOX( STR_AREA_ALREADY_INSERTED );
			}
			else
			{
				INFOBOX( STR_INVALID_TABREF );
				aEdDataArea.GrabFocus();
			}
		}
	}
	else if ( pBtn == &aBtnRemove )
	{
		while ( aLbConsAreas.GetSelectEntryCount() )
			aLbConsAreas.RemoveEntry( aLbConsAreas.GetSelectEntryPos() );
		aBtnRemove.Disable();
	}
	return 0;
}


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

IMPL_LINK( ScConsolidateDlg, SelectHdl, ListBox*, pLb )
{
	if ( pLb == &aLbConsAreas )
	{
		if ( aLbConsAreas.GetSelectEntryCount() > 0 )
			aBtnRemove.Enable();
		else
			aBtnRemove.Disable();
	}
	else if ( (pLb == &aLbDataArea) || (pLb == &aLbDestArea) )
	{
		Edit*	pEd = (pLb == &aLbDataArea) ? &aEdDataArea : &aEdDestArea;
		sal_uInt16	nSelPos = pLb->GetSelectEntryPos();

		if (    pRangeUtil
			&& (nSelPos > 0)
			&& (nAreaDataCount > 0)
			&& (pAreaData != NULL) )
		{
			if ( nSelPos <= nAreaDataCount )
			{
				String aString( pAreaData[nSelPos-1].aStrArea );

				if ( pLb == &aLbDestArea )
					pRangeUtil->CutPosString( aString, aString );

				pEd->SetText( aString );

				if ( pEd == &aEdDataArea )
					aBtnAdd.Enable();
			}
		}
		else
		{
			pEd->SetText( EMPTY_STRING );
			if ( pEd == &aEdDataArea )
				aBtnAdd.Enable();
		}
	}
	return 0;
}


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

IMPL_LINK( ScConsolidateDlg, ModifyHdl, formula::RefEdit*, pEd )
{
	if ( pEd == &aEdDataArea )
	{
		String aAreaStr( pEd->GetText() );
		if ( aAreaStr.Len() > 0 )
		{
			aBtnAdd.Enable();
		}
		else
			aBtnAdd.Disable();
	}
	else if ( pEd == &aEdDestArea )
	{
		aLbDestArea.SelectEntryPos(0);
	}
	return 0;
}


//----------------------------------------------------------------------------
// Verallgemeinern!!! :
// Resource der ListBox und diese beiden Umrechnungsmethoden gibt es
// auch noch in tpsubt bzw. ueberall, wo StarCalc-Funktionen
// auswaehlbar sind.

ScSubTotalFunc ScConsolidateDlg::LbPosToFunc( sal_uInt16 nPos )
{
	switch ( nPos )
	{
		case  2:	return SUBTOTAL_FUNC_AVE;
		case  6:	return SUBTOTAL_FUNC_CNT;
		case  1:	return SUBTOTAL_FUNC_CNT2;
		case  3:	return SUBTOTAL_FUNC_MAX;
		case  4:	return SUBTOTAL_FUNC_MIN;
		case  5:	return SUBTOTAL_FUNC_PROD;
		case  7:	return SUBTOTAL_FUNC_STD;
		case  8:	return SUBTOTAL_FUNC_STDP;
		case  9:	return SUBTOTAL_FUNC_VAR;
		case 10:	return SUBTOTAL_FUNC_VARP;
		case  0:
		default:
			return SUBTOTAL_FUNC_SUM;
	}
}


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

sal_uInt16 ScConsolidateDlg::FuncToLbPos( ScSubTotalFunc eFunc )
{
	switch ( eFunc )
	{
		case SUBTOTAL_FUNC_AVE:		return 2;
		case SUBTOTAL_FUNC_CNT:		return 6;
		case SUBTOTAL_FUNC_CNT2:	return 1;
		case SUBTOTAL_FUNC_MAX:		return 3;
		case SUBTOTAL_FUNC_MIN:		return 4;
		case SUBTOTAL_FUNC_PROD:	return 5;
		case SUBTOTAL_FUNC_STD:		return 7;
		case SUBTOTAL_FUNC_STDP:	return 8;
		case SUBTOTAL_FUNC_VAR:		return 9;
		case SUBTOTAL_FUNC_VARP:	return 10;
		case SUBTOTAL_FUNC_NONE:
		case SUBTOTAL_FUNC_SUM:
		default:
			return 0;
	}
}

