/**************************************************************
 * 
 * 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_sw.hxx"
#ifdef SW_DLLIMPLEMENTATION
#undef SW_DLLIMPLEMENTATION
#endif


#include <swmodule.hxx>
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#include <wrtsh.hxx>
#ifndef _GLOBALS_HRC
#include <globals.hrc>
#endif
#include <dbfld.hxx>
#ifndef _FLDTDLG_HXX
#include <fldtdlg.hxx>
#endif
#include <numrule.hxx>

#ifndef _FLDTDLG_HRC
#include <fldtdlg.hrc>
#endif
#ifndef _FLDUI_HRC
#include <fldui.hrc>
#endif
#ifndef _FLDDB_HXX
#include <flddb.hxx>
#endif
#include <dbconfig.hxx>
#ifndef _DBMGR_HXX
#include <dbmgr.hxx>
#endif

#define USER_DATA_VERSION_1 	"1"
#define USER_DATA_VERSION USER_DATA_VERSION_1
/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

SwFldDBPage::SwFldDBPage(Window* pParent, const SfxItemSet& rCoreSet ) :
	SwFldPage( pParent, SW_RES( TP_FLD_DB ), rCoreSet ),
	aTypeFT		(this, SW_RES(FT_DBTYPE)),
	aTypeLB		(this, SW_RES(LB_DBTYPE)),
	aSelectionFT(this, SW_RES(FT_DBSELECTION)),
    aDatabaseTLB(this, SW_RES(TLB_DBLIST), 0, aEmptyStr, sal_False),
    aAddDBFT(this,      SW_RES(FT_ADDDB)),
    aAddDBPB(this,      SW_RES(PB_ADDDB)),
	aConditionFT(this, SW_RES(FT_DBCONDITION)),
	aConditionED(this, SW_RES(ED_DBCONDITION)),
	aValueFT	(this, SW_RES(FT_DBSETNUMBER)),
	aValueED	(this, SW_RES(ED_DBSETNUMBER)),
	aDBFormatRB	(this, SW_RES(RB_DBOWNFORMAT)),
	aNewFormatRB(this, SW_RES(RB_DBFORMAT)),
	aNumFormatLB(this, SW_RES(LB_DBNUMFORMAT)),
	aFormatLB	(this, SW_RES(LB_DBFORMAT)),
    aFormatFL   (this, SW_RES(FL_DBFORMAT)),
    aFormatVertFL   (this, SW_RES(FL_DBFORMAT_VERT))
{
	FreeResource();

	aOldNumSelectHdl = aNumFormatLB.GetSelectHdl();

	aNumFormatLB.SetSelectHdl(LINK(this, SwFldDBPage, NumSelectHdl));
	aDatabaseTLB.SetSelectHdl(LINK(this, SwFldDBPage, TreeSelectHdl));
	aDatabaseTLB.SetDoubleClickHdl(LINK(this, SwFldDBPage, InsertHdl));

	aValueED.SetModifyHdl(LINK(this, SwFldDBPage, ModifyHdl));
    aAddDBPB.SetClickHdl(LINK(this, SwFldDBPage, AddDBHdl));
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

__EXPORT SwFldDBPage::~SwFldDBPage()
{
}

/*--------------------------------------------------------------------
	Beschreibung: TabPage initialisieren
 --------------------------------------------------------------------*/

void __EXPORT SwFldDBPage::Reset(const SfxItemSet&)
{
	Init();	// Allgemeine initialisierung

	aTypeLB.SetUpdateMode(sal_False);
	sal_uInt16 nOldPos = aTypeLB.GetSelectEntryPos();
	sOldDBName = aDatabaseTLB.GetDBName(sOldTableName, sOldColumnName);

	aTypeLB.Clear();

	sal_uInt16 nPos, nTypeId, i;

	if (!IsFldEdit())
	{
		// TypeListBox initialisieren
		const SwFldGroupRgn& rRg = GetFldMgr().GetGroupRange(IsFldDlgHtmlMode(), GetGroup());

		for(i = rRg.nStart; i < rRg.nEnd; ++i)
		{
			nTypeId = GetFldMgr().GetTypeId(i);
			nPos = aTypeLB.InsertEntry(GetFldMgr().GetTypeStr(i));
            aTypeLB.SetEntryData(nPos, reinterpret_cast<void*>(nTypeId));
		}
	}
	else
	{
		nTypeId = GetCurField()->GetTypeId();
		nPos = aTypeLB.InsertEntry(GetFldMgr().GetTypeStr(GetFldMgr().GetPos(nTypeId)));
        aTypeLB.SetEntryData(nPos, reinterpret_cast<void*>(nTypeId));
	}

	// alte Pos selektieren
	if (GetTypeSel() != LISTBOX_ENTRY_NOTFOUND)
		aTypeLB.SelectEntryPos(GetTypeSel());

	aFormatLB.Clear();

	sal_uInt16 nSize = GetFldMgr().GetFormatCount(TYP_DBSETNUMBERFLD, sal_False, IsFldDlgHtmlMode());
	for( i = 0; i < nSize; ++i )
	{
        sal_uInt16 nEntryPos = aFormatLB.InsertEntry(GetFldMgr().GetFormatStr(TYP_DBSETNUMBERFLD, i));
		sal_uInt16 nFmtId = GetFldMgr().GetFormatId( TYP_DBSETNUMBERFLD, i );
        aFormatLB.SetEntryData( nEntryPos, reinterpret_cast<void*>(nFmtId) );
		if( SVX_NUM_ARABIC == nFmtId )
            aFormatLB.SelectEntryPos( nEntryPos );
	}

	if (!IsFldEdit())
	{
		if (nOldPos != LISTBOX_ENTRY_NOTFOUND)
			aTypeLB.SelectEntryPos(nOldPos);

		if (sOldDBName.Len())
		{
			aDatabaseTLB.Select(sOldDBName, sOldTableName, sOldColumnName);
		}
		else
		{
            SwWrtShell *pSh = GetWrtShell();
            if(!pSh)
                pSh = ::GetActiveWrtShell();
            if(pSh)
            {
                SwDBData aTmp(pSh->GetDBData());
                aDatabaseTLB.Select(aTmp.sDataSource, aTmp.sCommand, aEmptyStr);
            }
		}
	}

	if( !IsRefresh() )
	{
		String sUserData = GetUserData();
		if(sUserData.GetToken(0, ';').EqualsIgnoreCaseAscii(USER_DATA_VERSION_1))
		{
			String sVal = sUserData.GetToken(1, ';');
			sal_uInt16 nVal = (sal_uInt16)sVal.ToInt32();
			if(nVal != USHRT_MAX)
			{
                for(i = 0; i < aTypeLB.GetEntryCount(); i++)
					if(nVal == (sal_uInt16)(sal_uLong)aTypeLB.GetEntryData(i))
					{
						aTypeLB.SelectEntryPos(i);
						break;
					}
			}
		}
	}
	TypeHdl(0);

	aTypeLB.SetUpdateMode(sal_True);
	aTypeLB.SetSelectHdl(LINK(this, SwFldDBPage, TypeHdl));
	aTypeLB.SetDoubleClickHdl(LINK(this, SwFldDBPage, InsertHdl));

	if (IsFldEdit())
	{
		aConditionED.SaveValue();
		aValueED.SaveValue();
		sOldDBName = aDatabaseTLB.GetDBName(sOldTableName, sOldColumnName);
		nOldFormat = GetCurField()->GetFormat();
		nOldSubType = GetCurField()->GetSubType();
	}
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

sal_Bool __EXPORT SwFldDBPage::FillItemSet(SfxItemSet& )
{
	String sTableName, sColumnName;
	SwDBData aData;
    sal_Bool bIsTable;
	aData.sDataSource = aDatabaseTLB.GetDBName(sTableName, sColumnName, &bIsTable);
	aData.sCommand = sTableName;
    aData.nCommandType = bIsTable ? 0 : 1;
    SwWrtShell *pSh = GetWrtShell();
    if(!pSh)
        pSh = ::GetActiveWrtShell();

	if (!aData.sDataSource.getLength())
		aData = pSh->GetDBData();

	if(aData.sDataSource.getLength())		// Ohne Datenbank kein neuer Feldbefehl
	{
		sal_uInt16 nTypeId = (sal_uInt16)(sal_uLong)aTypeLB.GetEntryData(GetTypeSel());
		String aVal(aValueED.GetText());
		String aName(aConditionED.GetText());
		sal_uLong nFormat = 0;
		sal_uInt16 nSubType = 0;

		String sDBName = aData.sDataSource;
		sDBName += DB_DELIM;
		sDBName += (String)aData.sCommand;
		sDBName += DB_DELIM;
        sDBName += String::CreateFromInt32(aData.nCommandType);
		sDBName += DB_DELIM;
        if(sColumnName.Len())
		{
			sDBName += sColumnName;
			sDBName += DB_DELIM;
		}
		aName.Insert(sDBName, 0);

		switch (nTypeId)
		{
		case TYP_DBFLD:
			nFormat = aNumFormatLB.GetFormat();
			if (aNewFormatRB.IsEnabled() && aNewFormatRB.IsChecked())
				nSubType = nsSwExtendedSubType::SUB_OWN_FMT;
			aName = sDBName;
			break;

		case TYP_DBSETNUMBERFLD:
			nFormat = (sal_uInt16)(sal_uLong)aFormatLB.GetEntryData(
								aFormatLB.GetSelectEntryPos() );
			break;
		}


		String sTempDBName, sTempTableName, sTempColumnName;
		sTempDBName = aDatabaseTLB.GetDBName(sTempTableName, sTempColumnName);
		sal_Bool bDBListBoxChanged = sOldDBName != sTempDBName ||
			sOldTableName != sTempTableName || sOldColumnName != sTempColumnName;
		if (!IsFldEdit() ||
			aConditionED.GetSavedValue() != aConditionED.GetText() ||
			 aValueED.GetSavedValue() != aValueED.GetText() ||
			 bDBListBoxChanged ||
			 nOldFormat != nFormat || nOldSubType != nSubType)
		{
			InsertFld( nTypeId, nSubType, aName, aVal, nFormat);
		}
	}

	return sal_False;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

SfxTabPage* __EXPORT SwFldDBPage::Create( 	Window* pParent,
						const SfxItemSet& rAttrSet )
{
	return ( new SwFldDBPage( pParent, rAttrSet ) );
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

sal_uInt16 SwFldDBPage::GetGroup()
{
	return GRP_DB;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwFldDBPage, TypeHdl, ListBox *, pBox )
{
	// Alte ListBoxPos sichern
	const sal_uInt16 nOld = GetTypeSel();

	// Aktuelle ListBoxPos
	SetTypeSel(aTypeLB.GetSelectEntryPos());

	if(GetTypeSel() == LISTBOX_ENTRY_NOTFOUND)
	{
		SetTypeSel(0);
		aTypeLB.SelectEntryPos(0);
	}

	if (nOld != GetTypeSel())
	{
        SwWrtShell *pSh = GetWrtShell();
        if(!pSh)
            pSh = ::GetActiveWrtShell();
		sal_Bool bCond = sal_False, bSetNo = sal_False, bFormat = sal_False, bDBFormat = sal_False;
		sal_uInt16 nTypeId = (sal_uInt16)(sal_uLong)aTypeLB.GetEntryData(GetTypeSel());

		aDatabaseTLB.ShowColumns(nTypeId == TYP_DBFLD);

		if (IsFldEdit())
		{
			SwDBData aData;
			String sColumnName;
			if (nTypeId == TYP_DBFLD)
			{
				aData = ((SwDBField*)GetCurField())->GetDBData();
				sColumnName = ((SwDBFieldType*)GetCurField()->GetTyp())->GetColumnName();
			}
			else
			{
				aData = ((SwDBNameInfField*)GetCurField())->GetDBData(pSh->GetDoc());
			}
			aDatabaseTLB.Select(aData.sDataSource, aData.sCommand, sColumnName);
		}

		switch (nTypeId)
		{
			case TYP_DBFLD:
				bFormat = sal_True;
				bDBFormat = sal_True;
				aNumFormatLB.Show();
				aFormatLB.Hide();

				if (pBox)	// Typ wurde vom User geaendert
					aDBFormatRB.Check();

				if (IsFldEdit())
				{
                    if (GetCurField()->GetFormat() != 0 && GetCurField()->GetFormat() != SAL_MAX_UINT32)
						aNumFormatLB.SetDefFormat(GetCurField()->GetFormat());

					if (GetCurField()->GetSubType() & nsSwExtendedSubType::SUB_OWN_FMT)
						aNewFormatRB.Check();
					else
						aDBFormatRB.Check();
				}
				break;

			case TYP_DBNUMSETFLD:
				bSetNo = sal_True;
				// kein break!
			case TYP_DBNEXTSETFLD:
				bCond = sal_True;
				if (IsFldEdit())
				{
					aConditionED.SetText(GetCurField()->GetPar1());
					aValueED.SetText(GetCurField()->GetPar2());
				}
				break;

			case TYP_DBNAMEFLD:
				break;

			case TYP_DBSETNUMBERFLD:
				bFormat = sal_True;
				aNewFormatRB.Check();
				aNumFormatLB.Hide();
				aFormatLB.Show();
				if( IsFldEdit() )
				{
					for( sal_uInt16 nI = aFormatLB.GetEntryCount(); nI; )
						if( GetCurField()->GetFormat() == (sal_uInt16)(sal_uLong)
							aFormatLB.GetEntryData( --nI ))
						{
							aFormatLB.SelectEntryPos( nI );
							break;
						}
				}
				break;
		}

		aConditionFT.Enable(bCond);
		aConditionED.Enable(bCond);
		aValueFT.Enable(bSetNo);
		aValueED.Enable(bSetNo);
		if (nTypeId != TYP_DBFLD)
		{
			aDBFormatRB.Enable(bDBFormat);
			aNewFormatRB.Enable(bDBFormat|bFormat);
			aNumFormatLB.Enable(bDBFormat);
			aFormatLB.Enable(bFormat);
		}
        aFormatFL.Enable(bDBFormat|bFormat);

		if (!IsFldEdit())
		{
			aValueED.SetText(aEmptyStr);
			if (bCond)
				aConditionED.SetText( String::CreateFromAscii(
						RTL_CONSTASCII_STRINGPARAM( "sal_True" )));
			else
				aConditionED.SetText(aEmptyStr);
		}

		CheckInsert();
	}

	return 0;
}

/*--------------------------------------------------------------------
	Beschreibung:
 --------------------------------------------------------------------*/

IMPL_LINK( SwFldDBPage, NumSelectHdl, NumFormatListBox *, pLB )
{
	aNewFormatRB.Check();
	aOldNumSelectHdl.Call(pLB);

	return 0;
}

/*---------------------------------------------------------------------
	Beschreibung:
---------------------------------------------------------------------*/

void SwFldDBPage::CheckInsert()
{
	sal_Bool bInsert = sal_True;
	sal_uInt16 nTypeId = (sal_uInt16)(sal_uLong)aTypeLB.GetEntryData(GetTypeSel());

	SvLBoxEntry* pEntry = aDatabaseTLB.GetCurEntry();

	if (pEntry)
	{
		pEntry = aDatabaseTLB.GetParent(pEntry);

		if (nTypeId == TYP_DBFLD && pEntry)
			pEntry = aDatabaseTLB.GetParent(pEntry);

		bInsert &= pEntry != 0;
	}
	else
		bInsert = sal_False;

	if (nTypeId == TYP_DBNUMSETFLD)
	{
		sal_Bool bHasValue = aValueED.GetText().Len() != 0;

		bInsert &= bHasValue;
	}

	EnableInsert(bInsert);
}

/*---------------------------------------------------------------------
	Beschreibung:
---------------------------------------------------------------------*/

IMPL_LINK( SwFldDBPage, TreeSelectHdl, SvTreeListBox *, pBox )
{
	SvLBoxEntry* pColEntry;
	SvLBoxEntry* pEntry = pColEntry = pBox->GetCurEntry();
	if (pEntry)
	{
		sal_uInt16 nTypeId = (sal_uInt16)(sal_uLong)aTypeLB.GetEntryData(GetTypeSel());

		pEntry = aDatabaseTLB.GetParent(pEntry);

		if (nTypeId == TYP_DBFLD && pEntry)
			pEntry = aDatabaseTLB.GetParent(pEntry);

		CheckInsert();

		if (nTypeId == TYP_DBFLD)
		{
			sal_Bool bNumFormat = sal_False;

			if (pEntry != 0)
			{
				String sTableName;
				String sColumnName;
				sal_Bool bIsTable;
				String sDBName = aDatabaseTLB.GetDBName(sTableName, sColumnName, &bIsTable);
				bNumFormat = GetFldMgr().IsDBNumeric(sDBName,
							sTableName,
							bIsTable,
							sColumnName);
				if (!IsFldEdit())
					aDBFormatRB.Check();
			}

			aDBFormatRB.Enable(bNumFormat);
			aNewFormatRB.Enable(bNumFormat);
			aNumFormatLB.Enable(bNumFormat);
            aFormatFL.Enable(bNumFormat);
		}
	}
	return 0;
}
/*-- 27.05.2004 09:14:01---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK( SwFldDBPage, AddDBHdl, PushButton *, EMPTYARG )
{
    String sNewDB = SwNewDBMgr::LoadAndRegisterDataSource();
    if(sNewDB.Len())
    {
        aDatabaseTLB.AddDataSource(sNewDB);
    }
    return 0;
}

/*--------------------------------------------------------------------
	Beschreibung: Modify
 --------------------------------------------------------------------*/

IMPL_LINK( SwFldDBPage, ModifyHdl, Edit *, EMPTYARG )
{
	CheckInsert();
	return 0;
}

/* -----------------12.01.99 11:21-------------------
 *
 * --------------------------------------------------*/
void	SwFldDBPage::FillUserData()
{
	String sData( String::CreateFromAscii(
						RTL_CONSTASCII_STRINGPARAM( USER_DATA_VERSION )));
	sData += ';';
	sal_uInt16 nTypeSel = aTypeLB.GetSelectEntryPos();

	if( LISTBOX_ENTRY_NOTFOUND == nTypeSel )
		nTypeSel = USHRT_MAX;
	else
		nTypeSel = (sal_uInt16)(sal_uLong)aTypeLB.GetEntryData( nTypeSel );
	sData += String::CreateFromInt32( nTypeSel );
	SetUserData(sData);
}
/* -----------------12.12.2002 11:33-----------------
 *
 * --------------------------------------------------*/
void SwFldDBPage::ActivateMailMergeAddress()
{
    sal_uLong nData = TYP_DBFLD;
    aTypeLB.SelectEntryPos(aTypeLB.GetEntryPos( (const void*) nData ));
    aTypeLB.GetSelectHdl().Call(&aTypeLB);
    const SwDBData& rData = SW_MOD()->GetDBConfig()->GetAddressSource();
	aDatabaseTLB.Select(rData.sDataSource, rData.sCommand, aEmptyStr);
}
/*-- 07.10.2003 13:59:04---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwFldDBPage::SetWrtShell(SwWrtShell& rSh)
{
    aDatabaseTLB.SetWrtShell(rSh);
}