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



#ifndef _CMDID_H
#include <cmdid.h>
#endif
#include <hintids.hxx>
#include <tools/ref.hxx>
#ifndef _SVX_DIALOGS_HRC
#include <svx/dialogs.hrc>
#endif
#include <vcl/field.hxx>
#include <vcl/svapp.hxx>
#include <unotools/localedatawrapper.hxx>
#include <unotools/syslocale.hxx>
#include <editeng/sizeitem.hxx>
#include <svx/pageitem.hxx>
#include <svl/eitem.hxx>
#include <editeng/ulspitem.hxx>
#include <uitool.hxx>
#include <pagedesc.hxx>
#include <pgfnote.hxx>
#include <uiitems.hxx>

#ifndef _GLOBALS_HRC
#include <globals.hrc>
#endif
#ifndef _MISC_HRC
#include <misc.hrc>
#endif
#ifndef _PGFNOTE_HRC
#include <pgfnote.hrc>
#endif

#define TWIP_TO_LBOX 5
/*-----------------------------------------------------#---------------
	Beschreibung:   vordefinierte Linien in Point
 --------------------------------------------------------------------*/

static const sal_uInt16 __FAR_DATA nLines[] = {
	0,
	50,
	100,
	150,
	200,
	500
};

static const sal_uInt16 nLineCount = sizeof(nLines) / sizeof(nLines[0]);

static sal_uInt16 __FAR_DATA aPageRg[] = {
	FN_PARAM_FTN_INFO, FN_PARAM_FTN_INFO,
	0
};


/*------------------------------------------------------------------------
 Beschreibung:	liefert zurueck, ob die Linienbreite nWidth bereits
				in der Listbox enthalten ist.
------------------------------------------------------------------------*/


sal_Bool lcl_HasLineWidth(sal_uInt16 nWidth)
{
	for(sal_uInt16 i = 0; i < nLineCount; ++i) {
		if(nLines[i] == nWidth)
			return sal_True;
	}
	return sal_False;
}

/*------------------------------------------------------------------------
 Beschreibung:	Handler fuer umschalten zwischen den unterschiedlichen
				Arten, wie die Hoehe des Fussnotenbereiches angegeben
				werden kann.
------------------------------------------------------------------------*/


IMPL_LINK_INLINE_START( SwFootNotePage, HeightPage, Button *, EMPTYARG )
{
	aMaxHeightEdit.Enable(sal_False);
	return 0;
}
IMPL_LINK_INLINE_END( SwFootNotePage, HeightPage, Button *, EMPTYARG )


IMPL_LINK_INLINE_START( SwFootNotePage, HeightMetric, Button *, EMPTYARG )
{
	aMaxHeightEdit.Enable();
	aMaxHeightEdit.GrabFocus();
	return 0;
}
IMPL_LINK_INLINE_END( SwFootNotePage, HeightMetric, Button *, EMPTYARG )

/*------------------------------------------------------------------------
 Beschreibung:	Handler Grenzwerte
------------------------------------------------------------------------*/


IMPL_LINK( SwFootNotePage, HeightModify, MetricField *, EMPTYARG )
{
	aMaxHeightEdit.SetMax(aMaxHeightEdit.Normalize(lMaxHeight -
			(aDistEdit.Denormalize(aDistEdit.GetValue(FUNIT_TWIP)) +
			aLineDistEdit.Denormalize(aLineDistEdit.GetValue(FUNIT_TWIP)))),
			FUNIT_TWIP);
	if(aMaxHeightEdit.GetValue() < 0)
		aMaxHeightEdit.SetValue(0);
	aDistEdit.SetMax(aDistEdit.Normalize(lMaxHeight -
			(aMaxHeightEdit.Denormalize(aMaxHeightEdit.GetValue(FUNIT_TWIP)) +
			aLineDistEdit.Denormalize(aLineDistEdit.GetValue(FUNIT_TWIP)))),
			FUNIT_TWIP);
	if(aDistEdit.GetValue() < 0)
		aDistEdit.SetValue(0);
	aLineDistEdit.SetMax(aLineDistEdit.Normalize(lMaxHeight -
			(aMaxHeightEdit.Denormalize(aMaxHeightEdit.GetValue(FUNIT_TWIP)) +
			aDistEdit.Denormalize(aDistEdit.GetValue(FUNIT_TWIP)))),
			FUNIT_TWIP);
	return 0;
}

// CTOR / DTOR -----------------------------------------------------------

SwFootNotePage::SwFootNotePage(Window *pParent, const SfxItemSet &rSet) :

	SfxTabPage(pParent, SW_RES(TP_FOOTNOTE_PAGE), rSet),
    aPosHeader(this, 		SW_RES(FL_FOOTNOTE_SIZE)),
	aMaxHeightPageBtn(this, SW_RES(RB_MAXHEIGHT_PAGE)),
	aMaxHeightBtn(this, 	SW_RES(RB_MAXHEIGHT)),
	aMaxHeightEdit(this, 	SW_RES(ED_MAXHEIGHT)),
	aDistLbl(this, 			SW_RES(FT_DIST)),
	aDistEdit(this, 		SW_RES(ED_DIST)),
	
	aLineHeader(this, 		SW_RES(FL_LINE)),
    aLinePosLbl(this, 		SW_RES(FT_LINEPOS)),
	aLinePosBox(this, 		SW_RES(DLB_LINEPOS)),
	aLineTypeLbl(this, 		SW_RES(FT_LINETYPE)),
	aLineTypeBox(this, 		SW_RES(DLB_LINETYPE)),
	aLineWidthLbl(this, 	SW_RES(FT_LINEWIDTH)),
	aLineWidthEdit(this, 	SW_RES(ED_LINEWIDTH)),
	aLineDistLbl(this, 		SW_RES(FT_LINEDIST)),
	aLineDistEdit(this, 	SW_RES(ED_LINEDIST))
	{
	FreeResource();

	SetExchangeSupport();
	FieldUnit aMetric = ::GetDfltMetric(sal_False);
	SetMetric( aMaxHeightEdit,	aMetric );
	SetMetric( aDistEdit, 		aMetric );
	SetMetric( aLineDistEdit, 	aMetric );
	MeasurementSystem eSys = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
	long nHeightValue = MEASURE_METRIC != eSys ? 1440 : 1134;
	aMaxHeightEdit.SetValue(aMaxHeightEdit.Normalize(nHeightValue),FUNIT_TWIP);;
	aMaxHeightEdit.SetAccessibleRelationLabeledBy(&aMaxHeightBtn);
}

SwFootNotePage::~SwFootNotePage()
{
}


SfxTabPage* SwFootNotePage::Create(Window *pParent, const SfxItemSet &rSet)
{
	return new SwFootNotePage(pParent, rSet);
}


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


void SwFootNotePage::Reset(const SfxItemSet &rSet)
{
	// Falls noch kein Bsp vorhanden Init hier sonst im Activate
	//
	SwPageFtnInfo* pDefFtnInfo = 0;
	const SwPageFtnInfo* pFtnInfo;
	const SfxPoolItem* pItem = SfxTabPage::GetItem(rSet, FN_PARAM_FTN_INFO);
	if( pItem )
	{
		pFtnInfo = &((const SwPageFtnInfoItem*)pItem)->GetPageFtnInfo();
	}
	else
	{
		// wenn "Standard" betaetigt wird, wird das Fussnotenitem geloescht,
		// deswegen muss hier eine Fussnotenstruktur erzeugt werden
		pDefFtnInfo = new SwPageFtnInfo();
		pFtnInfo = pDefFtnInfo;
	}
		// Hoehe Fussnotenbereich
	SwTwips lHeight = pFtnInfo->GetHeight();
	if(lHeight)
	{
		aMaxHeightEdit.SetValue(aMaxHeightEdit.Normalize(lHeight),FUNIT_TWIP);
		aMaxHeightBtn.Check(sal_True);
	}
	else
	{
		aMaxHeightPageBtn.Check(sal_True);
		aMaxHeightEdit.Enable(sal_False);
	}
	aMaxHeightPageBtn.SetClickHdl(LINK(this,SwFootNotePage,HeightPage));
	aMaxHeightBtn.SetClickHdl(LINK(this,SwFootNotePage,HeightMetric));
	Link aLk = LINK(this, SwFootNotePage, HeightModify);
	aMaxHeightEdit.SetLoseFocusHdl( aLk );
	aDistEdit.SetLoseFocusHdl( aLk );
	aLineDistEdit.SetLoseFocusHdl( aLk );

	// Trennlinie
	for(sal_uInt16 i = 0; i < nLineCount; ++i)
		aLineTypeBox.InsertEntry(nLines[i]);

	const sal_uInt16 nWidth = (sal_uInt16)pFtnInfo->GetLineWidth() * TWIP_TO_LBOX;
	if ( !lcl_HasLineWidth(nWidth) )
		aLineTypeBox.InsertEntry(nWidth);
	aLineTypeBox.SelectEntry(nWidth);

    // Position
    aLinePosBox.SelectEntryPos( static_cast< sal_uInt16 >(pFtnInfo->GetAdj()) );

		// Breite
	Fraction aTmp( 100, 1 );
	aTmp *= pFtnInfo->GetWidth();
	aLineWidthEdit.SetValue( static_cast<long>(aTmp) );

		// Abstand Fussnotenbereich
	aDistEdit.SetValue(aDistEdit.Normalize(pFtnInfo->GetTopDist()),FUNIT_TWIP);
	aLineDistEdit.SetValue(
		aLineDistEdit.Normalize(pFtnInfo->GetBottomDist()), FUNIT_TWIP);
	ActivatePage( rSet );
	delete pDefFtnInfo;
}

/*--------------------------------------------------------------------
	Beschreibung:	Attribute in den Set stopfen bei OK
 --------------------------------------------------------------------*/


sal_Bool SwFootNotePage::FillItemSet(SfxItemSet &rSet)
{
	SwPageFtnInfoItem aItem((const SwPageFtnInfoItem&)GetItemSet().Get(FN_PARAM_FTN_INFO));

	// Das ist das Original
	SwPageFtnInfo &rFtnInfo = aItem.GetPageFtnInfo();

		// Hoehe Fussnotenbereich
	if(aMaxHeightBtn.IsChecked())
        rFtnInfo.SetHeight( static_cast< SwTwips >(
                aMaxHeightEdit.Denormalize(aMaxHeightEdit.GetValue(FUNIT_TWIP))));
	else
		rFtnInfo.SetHeight(0);

		// Abstand Fussnotenbereich
    rFtnInfo.SetTopDist(  static_cast< SwTwips >(
            aDistEdit.Denormalize(aDistEdit.GetValue(FUNIT_TWIP))));
    rFtnInfo.SetBottomDist(  static_cast< SwTwips >(
            aLineDistEdit.Denormalize(aLineDistEdit.GetValue(FUNIT_TWIP))));

		// Trennlinie
	const sal_uInt16 nPos = aLineTypeBox.GetSelectEntryPos();
	if( LISTBOX_ENTRY_NOTFOUND != nPos )
		rFtnInfo.SetLineWidth(nLines[nPos] / TWIP_TO_LBOX);

		// Position
	rFtnInfo.SetAdj((SwFtnAdj)aLinePosBox.GetSelectEntryPos());

		// Breite
    rFtnInfo.SetWidth(Fraction( static_cast< long >(aLineWidthEdit.GetValue()), 100));

	const SfxPoolItem* pOldItem;
	if(0 == (pOldItem = GetOldItem( rSet, FN_PARAM_FTN_INFO )) ||
				aItem != *pOldItem )
		rSet.Put(aItem);

	return sal_True;
}

void SwFootNotePage::ActivatePage(const SfxItemSet& rSet)
{
	const SvxSizeItem& rSize = (const SvxSizeItem&)rSet.Get( RES_FRM_SIZE );
	lMaxHeight = rSize.GetSize().Height();

	const SfxPoolItem* pItem;
	if( SFX_ITEM_SET == rSet.GetItemState( rSet.GetPool()->GetWhich( SID_ATTR_PAGE_HEADERSET), sal_False, &pItem ) )
	{
		const SfxItemSet& rHeaderSet = ((SvxSetItem*)pItem)->GetItemSet();
		const SfxBoolItem& rHeaderOn =
			(const SfxBoolItem&)rHeaderSet.Get( rSet.GetPool()->GetWhich( SID_ATTR_PAGE_ON ) );

		if ( rHeaderOn.GetValue() )
		{
            const SvxSizeItem& rSizeItem =
				(const SvxSizeItem&)rHeaderSet.Get(rSet.GetPool()->GetWhich(SID_ATTR_PAGE_SIZE));
            lMaxHeight -= rSizeItem.GetSize().Height();
		}
	}

	if( SFX_ITEM_SET == rSet.GetItemState( rSet.GetPool()->GetWhich( SID_ATTR_PAGE_FOOTERSET),
			sal_False, &pItem ) )
	{
		const SfxItemSet& rFooterSet = ((SvxSetItem*)pItem)->GetItemSet();
		const SfxBoolItem& rFooterOn =
			(const SfxBoolItem&)rFooterSet.Get( SID_ATTR_PAGE_ON );

		if ( rFooterOn.GetValue() )
		{
            const SvxSizeItem& rSizeItem =
				(const SvxSizeItem&)rFooterSet.Get( rSet.GetPool()->GetWhich( SID_ATTR_PAGE_SIZE ) );
            lMaxHeight -= rSizeItem.GetSize().Height();
		}
	}

	if ( rSet.GetItemState( RES_UL_SPACE , sal_False ) == SFX_ITEM_SET )
	{
		const SvxULSpaceItem &rUL = (const SvxULSpaceItem&)rSet.Get( RES_UL_SPACE );
		lMaxHeight -= rUL.GetUpper() + rUL.GetLower();
	}

	lMaxHeight *= 8;
	lMaxHeight /= 10;

	// Maximalwerte setzen
	HeightModify(0);
}

int SwFootNotePage::DeactivatePage( SfxItemSet* _pSet)
{
    if(_pSet)
        FillItemSet(*_pSet);

	return sal_True;
}

sal_uInt16* SwFootNotePage::GetRanges()
{
	return aPageRg;
}