/**************************************************************
 * 
 * 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>
#define _SVX_PSZCTRL_CXX

#include "svx/pszctrl.hxx"

#define PAINT_OFFSET	5

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

#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 "Anderungen vom exportierten Interface sowie
	der Verringerung von extern sichtbaren Symbolen.

	Eine Instanz exisitiert pro SvxPosSizeStatusBarControl-Instanz
	f"ur deren Laufzeit.
*/

{
	Point   aPos;		// g"ultig, wenn eine Position angezeigt wird
	Size    aSize;		// g"ultig, wenn eine Gr"o/se angezeigt wird
	String	aStr;		// g"ultig, wenn ein Text angezeigt wird
    sal_Bool    bPos;       // show position
	sal_Bool	bSize;		// Gr"o/se anzeigen?
	sal_Bool	bTable;		// Tabellenindex anzeigen?
	sal_Bool	bHasMenu;	// StarCalc Popup-Menue anzeigen?
	sal_uInt16	nFunction;	// selektierte StarCalc Funktion
	Image	aPosImage; 	// Image f"ur die Positionsanzeige
	Image	aSizeImage;	// Image f"ur die Gr"o/senanzeige
};

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

/*	[Beschreibung]

	Ctor():
	Anlegen einer Impl-Klassen-Instanz, Default die Zeitanzeige enablen,
	Images fu"r die Position und Gro"sse 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;
	pImp->aPosImage = Image( ResId( RID_SVXBMP_POSITION, DIALOG_MGR() ) );
	pImp->aSizeImage = Image( ResId( RID_SVXBMP_SIZE, DIALOG_MGR() ) );

    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 lo"schen, damit der Timer gestoppt wird.
*/

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

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

/*	[Beschreibung]

	SID_PSZ_FUNCTION aktiviert das Popup-Menue fuer 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
	Gro"sse		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"oschen
	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 ) )
	{
		// Groesse 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-Menue ausfuehren, 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 u"bermalt (gelo"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 fuer 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"ugbar, Gr"osse 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;
}


