/**************************************************************
 * 
 * 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 <vcl/lstbox.hxx>
#include <svl/stritem.hxx>
#include <sfx2/request.hxx>
#include <svx/htmlmode.hxx>
#include <dbfld.hxx>
#include <flddat.hxx>
#include <fmtfld.hxx>
#include <viewopt.hxx>
#include <fldedt.hxx>
#include <docsh.hxx>
#include <swmodule.hxx>
#include <view.hxx>
#include <wrtsh.hxx>
#include <expfld.hxx>
#include <fldtdlg.hxx>
#include <fldpage.hxx>
#include <docufld.hxx>
#include <cmdid.h>
#include <globals.hrc>
#include <sfx2/bindings.hxx>
#include <switerator.hxx>

using namespace ::com::sun::star;

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

SwFldPage::SwFldPage( Window *pParent, const ResId &rId,
						const SfxItemSet &rAttrSet )
    :SfxTabPage     (pParent, rId, rAttrSet),
    m_pCurFld       (0),
    m_pWrtShell     (0),
    m_nPageId       ( static_cast< sal_uInt16 >(rId.GetId()) ),
    m_nTypeSel      (LISTBOX_ENTRY_NOTFOUND),
    m_nSelectionSel (LISTBOX_ENTRY_NOTFOUND),
    m_bFldEdit      (sal_False),
    m_bInsert           (sal_True),
    m_bFldDlgHtmlMode   (sal_False),
    m_bRefresh          (sal_False),
    m_bFirstHTMLInit    (sal_True)
{
//	FreeResource();
}

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

SwFldPage::~SwFldPage()
{
}

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

void SwFldPage::Init()
{
	SwDocShell* pDocSh = (SwDocShell*)SfxObjectShell::Current();
	sal_Bool bNewMode = 0 != (::GetHtmlMode(pDocSh) & HTMLMODE_ON);

    m_bFldEdit = 0 == GetTabDialog();

	// FieldManager neu initialisieren wichtig fuer
	// Dok-Wechsel (fldtdlg:ReInitTabPage)
    m_pCurFld = m_aMgr.GetCurFld();

    if( bNewMode != m_bFldDlgHtmlMode )
	{
        m_bFldDlgHtmlMode = bNewMode;

		// Bereichslistbox initialisieren
        if( m_bFldDlgHtmlMode && m_bFirstHTMLInit )
		{
            m_bFirstHTMLInit = sal_False;
            SwWrtShell *pSh = m_pWrtShell;
            if(! pSh)
                pSh = ::GetActiveWrtShell();
            if(pSh)
            {
                SwDoc* pDoc = pSh->GetDoc();
                pSh->InsertFldType( SwSetExpFieldType( pDoc,
									String::CreateFromAscii("HTML_ON"), 1));
                pSh->InsertFldType( SwSetExpFieldType(pDoc,
									String::CreateFromAscii("HTML_OFF"), 1));
            }
		}
	}
}

/*--------------------------------------------------------------------
	 Beschreibung: Seite neu initialisieren
 --------------------------------------------------------------------*/

void SwFldPage::ActivatePage()
{
    EnableInsert(m_bInsert);
}

/*--------------------------------------------------------------------
	 Beschreibung: Kompletter Reset; neues Feld editieren
 --------------------------------------------------------------------*/

void SwFldPage::EditNewField( sal_Bool bOnlyActivate )
{
	if( !bOnlyActivate )
	{
        m_nTypeSel = LISTBOX_ENTRY_NOTFOUND;
	}
    m_nSelectionSel = LISTBOX_ENTRY_NOTFOUND;
    m_bRefresh = sal_True;
	Reset(*(SfxItemSet*)0);
    m_bRefresh = sal_False;
}

/*--------------------------------------------------------------------
	 Beschreibung: Feld einfuegen
 --------------------------------------------------------------------*/

sal_Bool SwFldPage::InsertFld(sal_uInt16 nTypeId, sal_uInt16 nSubType, const String& rPar1,
                            const String& rPar2, sal_uLong nFormatId,
                            sal_Unicode cSeparator, sal_Bool bIsAutomaticLanguage)
{
	sal_Bool bRet = sal_False;
    SwView* pView = GetActiveView();
    SwWrtShell *pSh = m_pWrtShell ? m_pWrtShell : pView->GetWrtShellPtr();

	if (!IsFldEdit())	// Neues Feld einfuegen
	{
        SwInsertFld_Data aData(nTypeId, nSubType, rPar1, rPar2, nFormatId, 0, cSeparator, bIsAutomaticLanguage );
        //#i26566# provide parent for SwWrtShell::StartInputFldDlg
        aData.pParent = &GetTabDialog()->GetOKButton();
        bRet = m_aMgr.InsertFld( aData );

        uno::Reference< frame::XDispatchRecorder > xRecorder =
                pView->GetViewFrame()->GetBindings().GetRecorder();
		if ( xRecorder.is() )
        {
            sal_Bool bRecordDB = TYP_DBFLD == nTypeId ||
                            TYP_DBSETNUMBERFLD == nTypeId ||
                            TYP_DBNUMSETFLD == nTypeId ||
                            TYP_DBNEXTSETFLD == nTypeId ||
                            TYP_DBNAMEFLD == nTypeId ;

            SfxRequest aReq( pView->GetViewFrame(),
					bRecordDB ?  FN_INSERT_DBFIELD : FN_INSERT_FIELD );
			if(bRecordDB)
			{
				aReq.AppendItem(SfxStringItem
						(FN_INSERT_DBFIELD,rPar1.GetToken(0, DB_DELIM)));
				aReq.AppendItem(SfxStringItem
						(FN_PARAM_1,rPar1.GetToken(1, DB_DELIM)));
                aReq.AppendItem(SfxInt32Item
                        (FN_PARAM_3,rPar1.GetToken(1, DB_DELIM).ToInt32()));
                aReq.AppendItem(SfxStringItem
                        (FN_PARAM_2,rPar1.GetToken(3, DB_DELIM)));
            }
			else
			{
				aReq.AppendItem(SfxStringItem(FN_INSERT_FIELD, rPar1));
                aReq.AppendItem(SfxStringItem
                        (FN_PARAM_3,String(cSeparator)));
                aReq.AppendItem(SfxUInt16Item(FN_PARAM_FIELD_SUBTYPE, nSubType));
            }
			aReq.AppendItem(SfxUInt16Item(FN_PARAM_FIELD_TYPE   , nTypeId));
            aReq.AppendItem(SfxStringItem(FN_PARAM_FIELD_CONTENT, rPar2));
			aReq.AppendItem(SfxUInt32Item(FN_PARAM_FIELD_FORMAT , nFormatId));
			aReq.Done();
		}

	}
	else	// Feld aendern
	{
        SwField *const pTmpFld = m_pCurFld->CopyField();

		String sPar1(rPar1);
		String sPar2(rPar2);
		sal_Bool bDBChanged = sal_False;
		switch( nTypeId )
		{
		case TYP_DATEFLD:
		case TYP_TIMEFLD:
            nSubType = static_cast< sal_uInt16 >(((nTypeId == TYP_DATEFLD) ? DATEFLD : TIMEFLD) |
                       ((nSubType == DATE_VAR) ? 0 : FIXEDFLD));
			break;

		case TYP_DBNAMEFLD:
		case TYP_DBNEXTSETFLD:
		case TYP_DBNUMSETFLD:
		case TYP_DBSETNUMBERFLD:
			{
				xub_StrLen nPos = 0;
				SwDBData aData;

				aData.sDataSource = rPar1.GetToken(0, DB_DELIM, nPos);
				aData.sCommand = rPar1.GetToken(0, DB_DELIM, nPos);
				aData.nCommandType = rPar1.GetToken(0, DB_DELIM, nPos).ToInt32();
				sPar1 = rPar1.Copy(nPos);

				((SwDBNameInfField*)pTmpFld)->SetDBData(aData);
				bDBChanged = sal_True;
			}
			break;

		case TYP_DBFLD:
			{
				SwDBData aData;
				aData.sDataSource = rPar1.GetToken(0, DB_DELIM);
				aData.sCommand = rPar1.GetToken(1, DB_DELIM);
                aData.nCommandType = rPar1.GetToken(2, DB_DELIM).ToInt32();
				String sColumn = rPar1.GetToken(3, DB_DELIM);

				SwDBFieldType* pOldTyp = (SwDBFieldType*)pTmpFld->GetTyp();
				SwDBFieldType* pTyp = (SwDBFieldType*)pSh->InsertFldType(
						SwDBFieldType(pSh->GetDoc(), sColumn, aData));

				SwIterator<SwFmtFld,SwFieldType> aIter( *pOldTyp );

				for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
				{
                    if( pFmtFld->GetField() == m_pCurFld)
					{
                        pFmtFld->RegisterToFieldType(*pTyp);
						pTmpFld->ChgTyp(pTyp);
						break;
					}
				}
				bDBChanged = sal_True;
			}
			break;

		case TYP_SEQFLD:
			{
				SwSetExpFieldType* pTyp = (SwSetExpFieldType*)pTmpFld->GetTyp();
                pTyp->SetOutlineLvl( static_cast< sal_uInt8 >(nSubType & 0xff));
				pTyp->SetDelimiter(cSeparator);

				nSubType = nsSwGetSetExpType::GSE_SEQ;
			}
			break;

		case TYP_INPUTFLD:
			{
				// User- oder SetField ?
                if (m_aMgr.GetFldType(RES_USERFLD, sPar1) == 0 &&
				!(pTmpFld->GetSubType() & INP_TXT))	// SETEXPFLD
				{
					SwSetExpField* pFld = (SwSetExpField*)pTmpFld;
					pFld->SetPromptText(sPar2);
					sPar2 = pFld->GetPar2();
				}
			}
			break;
        case TYP_DOCINFOFLD:
            {
                if( nSubType == nsSwDocInfoSubType::DI_CUSTOM )
                {
                    SwDocInfoField* pDocInfo = static_cast<SwDocInfoField*>( pTmpFld );
                    pDocInfo->SetName( rPar1 );
                }
            }
            break;
		}

		pSh->StartAllAction();

		pTmpFld->SetSubType(nSubType);
        pTmpFld->SetAutomaticLanguage(bIsAutomaticLanguage);

        m_aMgr.UpdateCurFld( nFormatId, sPar1, sPar2, pTmpFld );

        m_pCurFld = m_aMgr.GetCurFld();

		switch (nTypeId)
		{
			case TYP_HIDDENTXTFLD:
			case TYP_HIDDENPARAFLD:
                m_aMgr.EvalExpFlds(pSh);
				break;
		}

		pSh->SetUndoNoResetModified();
		pSh->EndAllAction();
	}

	return bRet;
}

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

void SwFldPage::SavePos( const ListBox* pLst1, const ListBox* pLst2,
						 const ListBox* pLst3 )
{
	const ListBox* aLBArr [ coLBCount ] = { pLst1, pLst2, pLst3 };

	const ListBox** ppLB = aLBArr;
	for( int i = 0; i < coLBCount; ++i, ++ppLB )
		if( (*ppLB) && (*ppLB)->GetEntryCount() )
            m_aLstStrArr[ i ] = (*ppLB)->GetSelectEntry();
		else
            m_aLstStrArr[ i ].Erase();
}

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

void SwFldPage::RestorePos(ListBox* pLst1, ListBox* pLst2, ListBox* pLst3)
{
	sal_uInt16 nPos = 0;
	ListBox* aLBArr [ coLBCount ] = { pLst1, pLst2, pLst3 };
	ListBox** ppLB = aLBArr;
	for( int i = 0; i < coLBCount; ++i, ++ppLB )
        if( (*ppLB) && (*ppLB)->GetEntryCount() && m_aLstStrArr[ i ].Len() &&
			LISTBOX_ENTRY_NOTFOUND !=
                        ( nPos = (*ppLB)->GetEntryPos(m_aLstStrArr[ i ] ) ) )
			(*ppLB)->SelectEntryPos( nPos );
}

/*--------------------------------------------------------------------
	 Beschreibung: Einfuegen von neuen Feldern
 --------------------------------------------------------------------*/

IMPL_LINK( SwFldPage, InsertHdl, Button *, pBtn )
{
	SwFldDlg *pDlg = (SwFldDlg*)GetTabDialog();

	if (pDlg)
	{
		pDlg->InsertHdl();

		if (pBtn)
			pBtn->GrabFocus();	// Wegen InputField-Dlg
	}
	else
	{
		SwFldEditDlg *pEditDlg = (SwFldEditDlg *)GetParent();
		pEditDlg->InsertHdl();
	}

	return 0;
}

/*--------------------------------------------------------------------
	 Beschreibung: "Einfuegen"-Button Enablen/Disablen
 --------------------------------------------------------------------*/

void SwFldPage::EnableInsert(sal_Bool bEnable)
{
	SwFldDlg *pDlg = (SwFldDlg*)GetTabDialog();

	if (pDlg)
	{
        if (pDlg->GetCurPageId() == m_nPageId)
			pDlg->EnableInsert(bEnable);
	}
	else
	{
		SwFldEditDlg *pEditDlg = (SwFldEditDlg *)GetParent();
		pEditDlg->EnableInsert(bEnable);
	}

    m_bInsert = bEnable;
}

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

IMPL_LINK( SwFldPage, NumFormatHdl, ListBox *, EMPTYARG )
{
	InsertHdl();

	return 0;
}

void SwFldPage::SetWrtShell( SwWrtShell* pShell )
{
    m_pWrtShell = pShell;
    m_aMgr.SetWrtShell( pShell );
}
