/**************************************************************
 *
 * 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_svx.hxx"

// include ---------------------------------------------------------------

#include <limits.h>
#include <tools/shl.hxx>
#include <vcl/status.hxx>
#include <vcl/menu.hxx>
#include <vcl/image.hxx>
#include <svl/stritem.hxx>
#include <svl/ptitem.hxx>
#include <svl/itempool.hxx>
#include <sfx2/app.hxx>
#include <sfx2/module.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/objsh.hxx>
#include <svl/intitem.hxx>

#include "svx/pszctrl.hxx"

#define PAINT_OFFSET	5

#include <editeng/sizeitem.hxx>
#include <svx/dialmgr.hxx>
#include "svx/dlgutil.hxx"
#include "stbctrls.h"

#include <svx/dialogs.hrc>
#include <unotools/localedatawrapper.hxx>
#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
#include <comphelper/processfactory.hxx>
#endif

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

/*	[Beschreibung]

	Funktion, mit der ein metrischer Wert in textueller Darstellung
	umgewandelt wird.

	nVal ist hier der metrische Wert in der Einheit eUnit.

	[Querverweise]

	<SvxPosSizeStatusBarControl::Paint(const UserDrawEvent&)>
*/

String SvxPosSizeStatusBarControl::GetMetricStr_Impl( long nVal )
{
	// Applikations-Metrik besorgen und setzen
	FieldUnit eOutUnit = SfxModule::GetModuleFieldUnit( getFrameInterface() );
	FieldUnit eInUnit = FUNIT_100TH_MM;

	String sMetric;
	const sal_Unicode cSep = Application::GetSettings().GetLocaleDataWrapper().getNumDecimalSep().GetChar(0);
	sal_Int64 nConvVal = MetricField::ConvertValue( nVal * 100, 0L, 0, eInUnit, eOutUnit );

	if ( nConvVal < 0 && ( nConvVal / 100 == 0 ) )
		sMetric += '-';
	sMetric += String::CreateFromInt64( nConvVal / 100 );

	if( FUNIT_NONE != eOutUnit )
	{
		sMetric += cSep;
		sal_Int64 nFract = nConvVal % 100;

		if ( nFract < 0 )
			nFract *= -1;
		if ( nFract < 10 )
			sMetric += '0';
		sMetric += String::CreateFromInt64( nFract );
	}

	return sMetric;
}

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

SFX_IMPL_STATUSBAR_CONTROL(SvxPosSizeStatusBarControl, SvxSizeItem);

// class FunctionPopup_Impl ----------------------------------------------

class FunctionPopup_Impl : public PopupMenu
{
public:
	FunctionPopup_Impl( sal_uInt16 nCheck );

	sal_uInt16			GetSelected() const { return nSelected; }

private:
	sal_uInt16			nSelected;

	virtual void	Select();
};

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

FunctionPopup_Impl::FunctionPopup_Impl( sal_uInt16 nCheck ) :
	PopupMenu( ResId( RID_SVXMNU_PSZ_FUNC, DIALOG_MGR() ) ),
	nSelected( 0 )
{
	if (nCheck)
		CheckItem( nCheck );
}

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

void FunctionPopup_Impl::Select()
{
	nSelected = GetCurItemId();
}

// struct SvxPosSizeStatusBarControl_Impl --------------------------------

struct SvxPosSizeStatusBarControl_Impl

/*	[Beschreibung]

	Diese Implementations-Struktur der Klasse SvxPosSizeStatusBarControl
	dient der Entkopplung von Änderungen vom exportierten Interface sowie
	der Verringerung von extern sichtbaren Symbolen.

	Eine Instanz existiert pro SvxPosSizeStatusBarControl-Instanz
	für deren Laufzeit.
*/

{
	Point	aPos;		// gültig, wenn eine Position angezeigt wird
	Size	aSize;		// gültig, wenn eine Größe angezeigt wird
	String	aStr;		// gültig, wenn ein Text angezeigt wird
	sal_Bool	bPos;		// show position?
	sal_Bool	bSize;		// show size?
	sal_Bool	bTable;		// Tabellenindex anzeigen?
	sal_Bool	bHasMenu;	// Calc Popup-Menü anzeigen?
	sal_uInt16	nFunction;	// selektierte Calc Funktion
	Image	aPosImage; 	// Image für die Positionsanzeige
	Image	aSizeImage;	// Image für die Größenanzeige
};

// class SvxPosSizeStatusBarControl ------------------------------------------

/*	[Beschreibung]

	Ctor():
	Anlegen einer Impl-Klassen-Instanz, Default die Zeitanzeige enablen,
	Images für die Position und Größe laden.
*/

#define STR_POSITION ".uno:Position"
#define STR_TABLECELL ".uno:StateTableCell"
#define STR_FUNC ".uno:StatusBarFunc"

SvxPosSizeStatusBarControl::SvxPosSizeStatusBarControl( sal_uInt16 _nSlotId,
														sal_uInt16 _nId,
														StatusBar& rStb ) :
	SfxStatusBarControl( _nSlotId, _nId, rStb ),
	pImp( new SvxPosSizeStatusBarControl_Impl )
{
	pImp->bPos = sal_False;
	pImp->bSize = sal_False;
	pImp->bTable = sal_False;
	pImp->bHasMenu = sal_False;
	pImp->nFunction = 0;
	sal_Bool bHC = GetStatusBar().GetSettings().GetStyleSettings().GetHighContrastMode();
		pImp->aPosImage = Image( SVX_RES( bHC ? RID_SVXBMP_POSITION_H : RID_SVXBMP_POSITION ) );
		pImp->aSizeImage = Image( SVX_RES( bHC ? RID_SVXBMP_SIZE_H : RID_SVXBMP_SIZE ) );

	addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STR_POSITION ))); // SID_ATTR_POSITION
	addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STR_TABLECELL ))); // SID_TABLE_CELL
	addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STR_FUNC ))); // SID_PSZ_FUNCTION
}

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

/*	[Beschreibung]

	Dtor():
	Pointer auf die Impl-Klasse löschen, damit der Timer gestoppt wird.
*/

SvxPosSizeStatusBarControl::~SvxPosSizeStatusBarControl()
{
	delete pImp;
}

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

/*	[Beschreibung]

	SID_PSZ_FUNCTION aktiviert das Popup-Menü für Calc, ansonsten:

	Statusbenachrichtigung;
	Je nach Item-Typ wird eine bestimmte Anzeige enabled, die anderen disabled.

				NULL/Void	SfxPointItem	SvxSizeItem		SfxStringItem
	------------------------------------------------------------------------
	Zeit		sal_True	sal_False		sal_False		FALSE
	Position	sal_False									FALSE
	Größe		FALSE						TRUE			FALSE
	Text		sal_False					sal_False		TRUE

	Ein anderes Item bewirkt einen Assert, die Zeitanzeige wird enabled.
*/

void SvxPosSizeStatusBarControl::StateChanged( sal_uInt16 nSID, SfxItemState eState,
											   const SfxPoolItem* pState )
{
	// da Kombi-Controller, immer die aktuelle Id als HelpId setzen
	// gecachten HelpText vorher löschen
	GetStatusBar().SetHelpText( GetId(), String() );

	switch ( nSID )
	{
		case SID_ATTR_POSITION : GetStatusBar().SetHelpId( GetId(), STR_POSITION ); break;
		case SID_TABLE_CELL: GetStatusBar().SetHelpId( GetId(), STR_TABLECELL ); break;
		case SID_PSZ_FUNCTION: GetStatusBar().SetHelpId( GetId(), STR_FUNC ); break;
		default: break;
	}

	if ( nSID == SID_PSZ_FUNCTION )
	{
		if ( eState == SFX_ITEM_AVAILABLE )
		{
			pImp->bHasMenu = sal_True;
			if ( pState && pState->ISA(SfxUInt16Item) )
				pImp->nFunction = ((const SfxUInt16Item*)pState)->GetValue();
		}
		else
			pImp->bHasMenu = sal_False;
	}
	else if ( SFX_ITEM_AVAILABLE != eState )
	{
		// #i34458# don't switch to empty display before an empty state was
		// notified for all display types

		if ( nSID == SID_TABLE_CELL )
			pImp->bTable = sal_False;
		else if ( nSID == SID_ATTR_POSITION )
			pImp->bPos = sal_False;
		else if ( nSID == GetSlotId() ) // controller is registered for SID_ATTR_SIZE
			pImp->bSize = sal_False;
		else
		{
			DBG_ERRORFILE("unknown slot id");
		}
	}
	else if ( pState->ISA( SfxPointItem ) )
	{
		// Position anzeigen
		pImp->aPos = ( (SfxPointItem*)pState )->GetValue();
		pImp->bPos = sal_True;
		pImp->bTable = sal_False;
	}
	else if ( pState->ISA( SvxSizeItem ) )
	{
		// Größe anzeigen
		pImp->aSize = ( (SvxSizeItem*)pState )->GetSize();
		pImp->bSize = sal_True;
		pImp->bTable = sal_False;
	}
	else if ( pState->ISA( SfxStringItem ) )
	{
		// String anzeigen (Tabellen-Zelle oder anderes)
		pImp->aStr = ( (SfxStringItem*)pState )->GetValue();
		pImp->bTable = sal_True;
		pImp->bPos = sal_False;
		pImp->bSize = sal_False;
	}
	else
	{
		DBG_ERRORFILE( "invalid item type" );
		// trotzdem Datum und Zeit anzeigen
		pImp->bPos = sal_False;
		pImp->bSize = sal_False;
		pImp->bTable = sal_False;
	}

	if ( GetStatusBar().AreItemsVisible() )
		GetStatusBar().SetItemData( GetId(), 0 );

	//	nur Strings auch als Text an der StatusBar setzen, damit Tip-Hilfe
	//	funktioniert, wenn der Text zu lang ist.
	String aText;
	if ( pImp->bTable )
		aText = pImp->aStr;
	GetStatusBar().SetItemText( GetId(), aText );
}

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

/*	[Beschreibung]

	Popup-Menü ausführen, wenn per Status enabled
*/

void SvxPosSizeStatusBarControl::Command( const CommandEvent& rCEvt )
{
	if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU && pImp->bHasMenu )
	{
		sal_uInt16 nSelect = pImp->nFunction;
		if (!nSelect)
			nSelect = PSZ_FUNC_NONE;
		FunctionPopup_Impl aMenu( nSelect );
		if ( aMenu.Execute( &GetStatusBar(), rCEvt.GetMousePosPixel() ) )
		{
			nSelect = aMenu.GetSelected();
			if (nSelect)
			{
				if (nSelect == PSZ_FUNC_NONE)
					nSelect = 0;

				::com::sun::star::uno::Any a;
				SfxUInt16Item aItem( SID_PSZ_FUNCTION, nSelect );

				::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs( 1 );
				aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StatusBarFunc" ));
				aItem.QueryValue( a );
				aArgs[0].Value = a;

				execute( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StatusBarFunc" )), aArgs );
//				GetBindings().GetDispatcher()->Execute( SID_PSZ_FUNCTION, SFX_CALLMODE_RECORD, &aItem, 0L );
			}
		}
	}
	else
		SfxStatusBarControl::Command( rCEvt );
}

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

/*	[Beschreibung]

	Je nach enableden Anzeigentyp, wird der Wert angezeigt. Vorher wird
	das Rectangle übermalt (gelöscht).
*/

void SvxPosSizeStatusBarControl::Paint( const UserDrawEvent& rUsrEvt )
{
	OutputDevice* pDev = rUsrEvt.GetDevice();
	DBG_ASSERT( pDev, "no OutputDevice on UserDrawEvent" );
	const Rectangle& rRect = rUsrEvt.GetRect();
	StatusBar& rBar = GetStatusBar();
	Point aItemPos = rBar.GetItemTextPos( GetId() );
	Color aOldLineColor = pDev->GetLineColor();
	Color aOldFillColor = pDev->GetFillColor();
	pDev->SetLineColor();
	pDev->SetFillColor( pDev->GetBackground().GetColor() );

	if ( pImp->bPos || pImp->bSize )
	{
		// Position für Size-Anzeige berechnen
		long nSizePosX =
			rRect.Left() + rRect.GetWidth() / 2 + PAINT_OFFSET;
		// Position zeichnen
		Point aPnt = rRect.TopLeft();
		aPnt.Y() = aItemPos.Y();
		aPnt.X() += PAINT_OFFSET;
		pDev->DrawImage( aPnt, pImp->aPosImage );
		aPnt.X() += pImp->aPosImage.GetSizePixel().Width();
		aPnt.X() += PAINT_OFFSET;
		String aStr = GetMetricStr_Impl( pImp->aPos.X());
		aStr.AppendAscii(" / ");
		aStr += GetMetricStr_Impl( pImp->aPos.Y());
		pDev->DrawRect(
			Rectangle( aPnt, Point( nSizePosX, rRect.Bottom() ) ) );
		pDev->DrawText( aPnt, aStr );

		// falls verfügbar, Größe zeichnen
		aPnt.X() = nSizePosX;

		if ( pImp->bSize )
		{
			pDev->DrawImage( aPnt, pImp->aSizeImage );
			aPnt.X() += pImp->aSizeImage.GetSizePixel().Width();
			Point aDrwPnt = aPnt;
			aPnt.X() += PAINT_OFFSET;
			aStr = GetMetricStr_Impl( pImp->aSize.Width() );
			aStr.AppendAscii(" x ");
			aStr += GetMetricStr_Impl( pImp->aSize.Height() );
			pDev->DrawRect( Rectangle( aDrwPnt, rRect.BottomRight() ) );
			pDev->DrawText( aPnt, aStr );
		}
		else
			pDev->DrawRect( Rectangle( aPnt, rRect.BottomRight() ) );
	}
	else if ( pImp->bTable )
	{
		pDev->DrawRect( rRect );
		pDev->DrawText( Point(
			rRect.Left() + rRect.GetWidth() / 2 - pDev->GetTextWidth( pImp->aStr ) / 2,
			aItemPos.Y() ),	pImp->aStr );
	}
	else
	{
		// Empty display if neither size nor table position are available.
		// Date/Time are no longer used (#65302#).
		pDev->DrawRect( rRect );
	}

	pDev->SetLineColor( aOldLineColor );
	pDev->SetFillColor( aOldFillColor );
}

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

sal_uIntPtr SvxPosSizeStatusBarControl::GetDefItemWidth(const StatusBar& rStb)
{
	Image aTmpPosImage( ResId( RID_SVXBMP_POSITION, DIALOG_MGR() ) );
	Image aTmpSizeImage( ResId( RID_SVXBMP_SIZE, DIALOG_MGR() ) );

	sal_uIntPtr nWidth=PAINT_OFFSET+aTmpPosImage.GetSizePixel().Width();
	nWidth+=PAINT_OFFSET+aTmpSizeImage.GetSizePixel().Width();
	nWidth+=2*(PAINT_OFFSET+rStb.GetTextWidth(String::CreateFromAscii("XXXX,XX / XXXX,XX")));

	return nWidth;
}

/* vim: set noet sw=4 ts=4: */
