/**************************************************************
 * 
 * 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 <tools/shl.hxx>
#ifndef _STATUS_HXX //autogen
#include <vcl/status.hxx>
#endif
#ifndef _MENU_HXX //autogen
#include <vcl/menu.hxx>
#endif
#include <sfx2/dispatch.hxx>
#include <tools/urlobj.hxx>

#include <svx/dialogs.hrc>

#include "svx/zoomctrl.hxx"
//CHINA001 #include "zoom.hxx"
#include <svx/zoomitem.hxx>
#include "stbctrls.h"
#include <svx/dialmgr.hxx>

SFX_IMPL_STATUSBAR_CONTROL(SvxZoomStatusBarControl,SvxZoomItem);

// class ZoomPopup_Impl --------------------------------------------------

class ZoomPopup_Impl : public PopupMenu
{
public:
	ZoomPopup_Impl( sal_uInt16 nZ, sal_uInt16 nValueSet );

	sal_uInt16			GetZoom() const { return nZoom; }
	sal_uInt16			GetCurId() const { return nCurId; }

private:
	sal_uInt16			nZoom;
	sal_uInt16			nCurId;

	virtual void	Select();
};

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

ZoomPopup_Impl::ZoomPopup_Impl( sal_uInt16 nZ, sal_uInt16 nValueSet )

:	PopupMenu( ResId( RID_SVXMNU_ZOOM, DIALOG_MGR() ) ),

	nZoom( nZ )
{
	static sal_uInt16 aTable[] =
	{
		SVX_ZOOM_ENABLE_50, 		ZOOM_50,
		SVX_ZOOM_ENABLE_100,		ZOOM_100,
		SVX_ZOOM_ENABLE_150,		ZOOM_150,
		SVX_ZOOM_ENABLE_200,		ZOOM_200,
		SVX_ZOOM_ENABLE_OPTIMAL,	ZOOM_OPTIMAL,
		SVX_ZOOM_ENABLE_WHOLEPAGE,	ZOOM_WHOLE_PAGE,
		SVX_ZOOM_ENABLE_PAGEWIDTH,	ZOOM_PAGE_WIDTH
	};

	for ( sal_uInt16 nPos = 0; nPos < sizeof(aTable) / sizeof(sal_uInt16); nPos += 2 )
		if ( ( aTable[nPos] != ( aTable[nPos] & nValueSet ) ) )
			EnableItem( aTable[nPos+1], sal_False );
}

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

void ZoomPopup_Impl::Select()
{
	nCurId = GetCurItemId();

	switch ( nCurId )
	{
		case ZOOM_200:			nZoom = 200; break;
		case ZOOM_150:			nZoom = 150; break;
		case ZOOM_100:			nZoom = 100; break;
		case ZOOM_75:			nZoom =  75; break;
		case ZOOM_50:			nZoom =  50; break;

		case ZOOM_OPTIMAL:
		case ZOOM_PAGE_WIDTH:
		case ZOOM_WHOLE_PAGE:	nZoom = 0; break;

	}
}

// class SvxZoomStatusBarControl ------------------------------------------

SvxZoomStatusBarControl::SvxZoomStatusBarControl( sal_uInt16 _nSlotId,
                                                  sal_uInt16 _nId,
												  StatusBar& rStb ) :

	SfxStatusBarControl( _nSlotId, _nId, rStb ),
	nZoom( 100 ),
	nValueSet( SVX_ZOOM_ENABLE_ALL )
{
}

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

void SvxZoomStatusBarControl::StateChanged( sal_uInt16, SfxItemState eState,
											const SfxPoolItem* pState )
{
	if( SFX_ITEM_AVAILABLE != eState )
	{
		GetStatusBar().SetItemText( GetId(), String() );
		nValueSet = 0;
	}
	else if ( pState->ISA( SfxUInt16Item) )
	{
		const SfxUInt16Item* pItem = (const SfxUInt16Item*)pState;
		nZoom = pItem->GetValue();
		String aStr( String::CreateFromInt32(nZoom) );
		aStr += '%';
		GetStatusBar().SetItemText( GetId(), aStr );

		if ( pState->ISA(SvxZoomItem) )
		{
			nValueSet = ((const SvxZoomItem*)pState)->GetValueSet();
/*!!!
			SvxZoomType eType = ((const SvxZoomItem*)pState)->GetType();

			switch ( eType )
			{
				case SVX_ZOOM_OPTIMAL:
					GetStatusBar().SetItemText( GetId(), "Opt." );
					break;
				case SVX_ZOOM_WHOLEPAGE:
					GetStatusBar().SetItemText( GetId(), "Page" );
					break;
				case SVX_ZOOM_PAGEWIDTH:
					GetStatusBar().SetItemText( GetId(), "Width" );
					break;
			}
*/
		}
		else
		{
			DBG_WARNING( "use SfxZoomItem for SID_ATTR_ZOOM" );
			nValueSet = SVX_ZOOM_ENABLE_ALL;
		}
	}
}

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

void SvxZoomStatusBarControl::Paint( const UserDrawEvent& )
{
	String aStr( String::CreateFromInt32( nZoom ));
	aStr += '%';
	GetStatusBar().SetItemText( GetId(), aStr );
}

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

void SvxZoomStatusBarControl::Command( const CommandEvent& rCEvt )
{
	if ( COMMAND_CONTEXTMENU & rCEvt.GetCommand() && 0 != nValueSet )
	{
		CaptureMouse();
		ZoomPopup_Impl aPop( nZoom, nValueSet );
		StatusBar& rStatusbar = GetStatusBar();

		if ( aPop.Execute( &rStatusbar, rCEvt.GetMousePosPixel() ) && ( nZoom != aPop.GetZoom() || !nZoom ) )
		{
			nZoom = aPop.GetZoom();
			SvxZoomItem aZoom( SVX_ZOOM_PERCENT, nZoom, GetId() );

			switch( aPop.GetCurId() )
			{
			case ZOOM_OPTIMAL:		aZoom.SetType( SVX_ZOOM_OPTIMAL ); break;
			case ZOOM_PAGE_WIDTH:	aZoom.SetType( SVX_ZOOM_PAGEWIDTH ); break;
			case ZOOM_WHOLE_PAGE:	aZoom.SetType( SVX_ZOOM_WHOLEPAGE ); break;
			}

            ::com::sun::star::uno::Any a;
            INetURLObject aObj( m_aCommandURL );
            
            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs( 1 );
            aArgs[0].Name  = aObj.GetURLPath();
            aZoom.QueryValue( a );
            aArgs[0].Value = a;
            
            execute( aArgs );
		}
		ReleaseMouse();
	}
	else
		SfxStatusBarControl::Command( rCEvt );
}

sal_uIntPtr SvxZoomStatusBarControl::GetDefItemWidth(const StatusBar& rStb)
{
	long nWidth1 =  rStb.GetTextWidth(String::CreateFromAscii("XXXXX%"));
	return nWidth1;
}


