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

#include "optimizerdialog.hxx"
#include "fileopendialog.hxx"
#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#ifndef _COM_SUN_STAR_UTIL_XCloseBroadcaster_HPP_
#include <com/sun/star/util/XCloseBroadcaster.hpp>
#endif
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XLayoutManager.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <osl/time.h>

#include "minimizer.hrc"
#include "helpid.hrc"

#define URL_GRAPHIC_REPO		"private:graphicrepository"
#define IMAGE_ROADMAP			URL_GRAPHIC_REPO "/minimizer/minimizepresi_80.png"
#define IMAGE_ROADMAP_HC		URL_GRAPHIC_REPO "/minimizer/minimizepresi_80_h.png"

// -------------------
// - OPTIMIZERDIALOG -
// -------------------

using namespace ::com::sun::star::io;
using namespace ::com::sun::star::graphic;
using namespace ::com::sun::star::ui;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::script;
using namespace ::com::sun::star::container;

using ::rtl::OUString;

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

void OptimizerDialog::InitDialog()
{
   // setting the dialog properties
	OUString pNames[] = {
		TKGet( TK_Closeable ),
		TKGet( TK_Height ),
		TKGet( TK_HelpURL ),
		TKGet( TK_Moveable ),
		TKGet( TK_PositionX ),
		TKGet( TK_PositionY ),
		TKGet( TK_Title ),
		TKGet( TK_Width ) };

	Any	pValues[] = {
		Any( sal_True ),
		Any( sal_Int32( DIALOG_HEIGHT ) ),
		Any( HID( HID_SDEXT_MINIMIZER_WIZ_DLG ) ),
		Any( sal_True ),
		Any( sal_Int32( 200 ) ),
		Any( sal_Int32( 52 ) ),
		Any( getString( STR_PRESENTATION_MINIMIZER ) ),
		Any( sal_Int32( OD_DIALOG_WIDTH ) ) };

	sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

	Sequence< rtl::OUString >	aNames( pNames, nCount );
	Sequence< Any >				aValues( pValues, nCount );

	mxDialogModelMultiPropertySet->setPropertyValues( aNames, aValues );
}

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

void OptimizerDialog::InitRoadmap()
{
	try
	{
		OUString pNames[] = {
			TKGet( TK_Height ),
			TKGet( TK_PositionX ),
			TKGet( TK_PositionY ),
			TKGet( TK_Step ),
			TKGet( TK_TabIndex ),
			TKGet( TK_Width ) };

		Any	pValues[] = {
			Any( sal_Int32( DIALOG_HEIGHT - 26 ) ),
			Any( sal_Int32( 0 ) ),
			Any( sal_Int32( 0 ) ),
			Any( sal_Int32( 0 ) ),
			Any( mnTabIndex++ ),
			Any( sal_Int32( 85 ) ) };

		sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

		Sequence< rtl::OUString >	aNames( pNames, nCount );
		Sequence< Any >				aValues( pValues, nCount );

		mxRoadmapControlModel = insertControlModel( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlRoadmapModel" ) ),
															  TKGet( TK_rdmNavi ), aNames, aValues	);

		Reference< XPropertySet > xPropertySet( mxRoadmapControlModel, UNO_QUERY_THROW );
		xPropertySet->setPropertyValue( TKGet( TK_Name ), Any( TKGet( TK_rdmNavi ) ) );
		mxRoadmapControl = mxDialogControlContainer->getControl( TKGet( TK_rdmNavi ) );
		InsertRoadmapItem( 0, sal_True, getString( STR_INTRODUCTION ), ITEM_ID_INTRODUCTION );
		InsertRoadmapItem( 1, sal_True, getString( STR_SLIDES ), ITEM_ID_SLIDES );
		InsertRoadmapItem( 2, sal_True, getString( STR_IMAGE_OPTIMIZATION ), ITEM_ID_GRAPHIC_OPTIMIZATION );
		InsertRoadmapItem( 3, sal_True, getString( STR_OLE_OBJECTS ), ITEM_ID_OLE_OPTIMIZATION );
		InsertRoadmapItem( 4, sal_True, getString( STR_SUMMARY ), ITEM_ID_SUMMARY );

		rtl::OUString sBitmap(
			isHighContrast() ?
			rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMAGE_ROADMAP_HC ) ) :
			rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMAGE_ROADMAP ) ) );

		xPropertySet->setPropertyValue( TKGet( TK_ImageURL ), Any( sBitmap ) );
		xPropertySet->setPropertyValue( TKGet( TK_Activated ), Any( (sal_Bool)sal_True ) );
		xPropertySet->setPropertyValue( TKGet( TK_Complete ), Any( (sal_Bool)sal_True ) );
		xPropertySet->setPropertyValue( TKGet( TK_CurrentItemID ), Any( (sal_Int16)ITEM_ID_INTRODUCTION ) );
		xPropertySet->setPropertyValue( TKGet( TK_Text ), Any( getString( STR_STEPS ) ) );
	}
	catch( Exception& )
	{
	}
}

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

void OptimizerDialog::InsertRoadmapItem( const sal_Int32 nIndex, const sal_Bool bEnabled, const rtl::OUString& rLabel, const sal_Int32 nItemID )
{
	try
	{
		Reference< XSingleServiceFactory > xSFRoadmap( mxRoadmapControlModel, UNO_QUERY_THROW );
		Reference< XIndexContainer > aIndexContainerRoadmap( mxRoadmapControlModel, UNO_QUERY_THROW );
		Reference< XInterface > xRoadmapItem( xSFRoadmap->createInstance(), UNO_QUERY_THROW );
		Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY_THROW );
		xPropertySet->setPropertyValue( TKGet( TK_Label ), Any( rLabel ) );
		xPropertySet->setPropertyValue( TKGet( TK_Enabled ), Any( bEnabled ) );
		xPropertySet->setPropertyValue( TKGet( TK_ID ), Any( nItemID ) );
		aIndexContainerRoadmap->insertByIndex( nIndex, Any( xRoadmapItem ) );
	}
	catch( Exception& )
	{

	}
}

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

void OptimizerDialog::UpdateConfiguration()
{
	sal_Int16	nInt16 = 0;
	OUString	aString;
	Any			aAny;

	Sequence< sal_Int16 > aSelectedItems;
	Sequence< OUString > aStringItemList;

	// page0
	aAny = getControlProperty( TKGet( TK_ListBox0Pg0 ), TKGet( TK_SelectedItems ) );
	if ( aAny >>= aSelectedItems )
	{
		if ( aSelectedItems.getLength() )
		{
			sal_Int16 nSelectedItem = aSelectedItems[ 0 ];
			aAny = getControlProperty( TKGet( TK_ListBox0Pg0 ), TKGet( TK_StringItemList ) );
			if ( aAny >>= aStringItemList )
			{
				if ( aStringItemList.getLength() > nSelectedItem )
					SetConfigProperty( TK_Name, Any( aStringItemList[ nSelectedItem ] ) );
			}
		}
	}

	aAny = getControlProperty( TKGet( TK_CheckBox3Pg3 ), TKGet( TK_State ) );
	if ( aAny >>= nInt16 )
	{
		if ( nInt16 )
		{
			aAny = getControlProperty( TKGet( TK_ListBox0Pg3 ), TKGet( TK_SelectedItems ) );
			if ( aAny >>= aSelectedItems )
			{
				if ( aSelectedItems.getLength() )
				{
					sal_Int16 nSelectedItem = aSelectedItems[ 0 ];
					aAny = getControlProperty( TKGet( TK_ListBox0Pg3 ), TKGet( TK_StringItemList ) );
					if ( aAny >>= aStringItemList )
					{
						if ( aStringItemList.getLength() > nSelectedItem )
							SetConfigProperty( TK_CustomShowName, Any( aStringItemList[ nSelectedItem ] ) );
					}
				}
			}
		}
	}
}

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

OptimizerDialog::OptimizerDialog(
	const Reference< XComponentContext > &rxContext,
	const Reference< XFrame > &rxFrame,
	const Reference< XWindowPeer >& rxParent )
	: UnoDialog( rxContext, rxParent )
	, ConfigurationAccess( rxContext, NULL )
	, mxFrame( rxFrame )
	, mnCurrentStep( 0 )
	, mnTabIndex( 0 )
{
	OSL_TRACE("OptimizerDialog::OptimizerDialog");
	OSL_ENSURE( mxFrame.is(), "OptimizerDialog: no XFrame!" );
	Reference< XController > xController( mxFrame->getController() );
	mxModel = xController->getModel();
	Reference< XStorable> xStorable( mxModel, UNO_QUERY_THROW );
	mbIsReadonly = xStorable->isReadonly();

	InitDialog();
	InitRoadmap();
	InitNavigationBar();
	InitPage0();
	InitPage1();
	InitPage2();
	InitPage3();
	InitPage4();
	ActivatePage( 0 );

	OptimizationStats aStats;
	aStats.InitializeStatusValuesFromDocument( mxModel );
	Sequence< PropertyValue > aStatusSequence( aStats.GetStatusSequence() );
	UpdateStatus( aStatusSequence );

	centerDialog();
}

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

OptimizerDialog::~OptimizerDialog()
{
	OSL_TRACE("OptimizerDialog::~OptimizerDialog");
	// not saving configuration if the dialog has been finished via cancel or close window
	if ( mbStatus )
		SaveConfiguration();

	Reference< XComponent > xComponent( mxDialog, UNO_QUERY );
	if ( xComponent.is() )
	{
		OSL_TRACE("OptimizerDialog::~OptimizerDialog - disposing dialog!");
		xComponent->dispose();
	}
}


void SAL_CALL OptimizerDialog::statusChanged(
	const ::com::sun::star::frame::FeatureStateEvent& aState )
throw (::com::sun::star::uno::RuntimeException)
{
	Sequence< PropertyValue > aArguments;
	if ( ( aState.State >>= aArguments ) && aArguments.getLength() )
		UpdateStatus( aArguments );
}

void SAL_CALL OptimizerDialog::disposing(
	const ::com::sun::star::lang::EventObject& /*aSource*/ )
throw (::com::sun::star::uno::RuntimeException)
{}

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

sal_Bool OptimizerDialog::execute()
{
	Reference< XItemEventBroadcaster > maRoadmapBroadcaster( mxRoadmapControl, UNO_QUERY_THROW );
	maRoadmapBroadcaster->addItemListener( this );
	UnoDialog::execute();
	UpdateConfiguration();			// taking actual control settings for the configuration
	maRoadmapBroadcaster->removeItemListener( this );
	return mbStatus;
}

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

void OptimizerDialog::SwitchPage( sal_Int16 nNewStep )
{
	if ( ( nNewStep != mnCurrentStep ) && ( ( nNewStep <= MAX_STEP ) || ( nNewStep >= 0 ) ) )
	{
		sal_Int16 nOldStep = mnCurrentStep;
		if ( nNewStep == 0 )
			disableControl( TKGet( TK_btnNavBack ) );
		else if ( nOldStep == 0 )
			enableControl( TKGet( TK_btnNavBack ) );

		if ( nNewStep == MAX_STEP )
			disableControl( TKGet( TK_btnNavNext ) );
		else if ( nOldStep == MAX_STEP )
			enableControl( TKGet( TK_btnNavNext ) );

		setControlProperty( TKGet( TK_rdmNavi ), TKGet( TK_CurrentItemID ), Any( nNewStep ) );

		DeactivatePage( nOldStep );
		UpdateControlStates( nNewStep );

		ActivatePage( nNewStep );
		mnCurrentStep = nNewStep;
	}
}

void OptimizerDialog::UpdateControlStates( sal_Int16 nPage )
{
	switch( nPage )
	{
		case 0 : UpdateControlStatesPage0(); break;
		case 1 : UpdateControlStatesPage1(); break;
		case 2 : UpdateControlStatesPage2(); break;
		case 3 : UpdateControlStatesPage3(); break;
		case 4 : UpdateControlStatesPage4(); break;
		default:
		{
			UpdateControlStatesPage0();
			UpdateControlStatesPage1();
			UpdateControlStatesPage2();
			UpdateControlStatesPage3();
			UpdateControlStatesPage4();
		}
	}
}

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

rtl::OUString OptimizerDialog::GetSelectedString( const PPPOptimizerTokenEnum eToken )
{
	OUString aSelectedItem;
	Sequence< sal_Int16 > sSelectedItems;
	Sequence< OUString >  sItemList;

	if ( ( getControlProperty( TKGet( eToken ), TKGet( TK_SelectedItems ) ) >>= sSelectedItems ) &&
			( getControlProperty( TKGet( eToken ), TKGet( TK_StringItemList ) ) >>= sItemList ) )
	{
		if ( sSelectedItems.getLength() == 1 )
		{
			sal_Int16 nSelectedItem = sSelectedItems[ 0 ];
			if ( nSelectedItem < sItemList.getLength() )
				aSelectedItem = sItemList[ nSelectedItem ];
		}
	}
	return aSelectedItem;
}

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

void OptimizerDialog::UpdateStatus( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& rStatus )
{
	if ( mxReschedule.is() )
	{
		maStats.InitializeStatusValues( rStatus );
		const Any* pVal( maStats.GetStatusValue( TK_Status ) );
		if ( pVal )
		{
			rtl::OUString sStatus;
			if ( *pVal >>= sStatus )
			{
				setControlProperty( TKGet( TK_FixedText1Pg4 ), TKGet( TK_Enabled ), Any( sal_True ) );
				setControlProperty( TKGet( TK_FixedText1Pg4 ), TKGet( TK_Label ), Any( sStatus ) );
			}
		}
		pVal = maStats.GetStatusValue( TK_Progress );
		if ( pVal )
		{
			sal_Int32 nProgress = 0;
			if ( *pVal >>= nProgress )
				setControlProperty( TKGet( TK_Progress ), TKGet( TK_ProgressValue ), Any( nProgress ) );
		}
		pVal = maStats.GetStatusValue( TK_OpenNewDocument );
		if ( pVal )
			SetConfigProperty( TK_OpenNewDocument, *pVal );

		mxReschedule->reschedule();
	}
}

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

void OptimizerDialog::itemStateChanged( const ItemEvent& Event )
	throw ( RuntimeException )
{
	try
	{
		sal_Int16 nState;
		OUString aControlName;
		Reference< XControl > xControl;
		Any aSource( Event.Source );
		if ( aSource >>= xControl )
		{
			Reference< XPropertySet > xPropertySet( xControl->getModel(), UNO_QUERY_THROW );
			xPropertySet->getPropertyValue( TKGet( TK_Name ) ) >>= aControlName;
			PPPOptimizerTokenEnum eControl( TKGet( aControlName ) );
			switch( eControl )
			{
				case TK_rdmNavi :
				{
					SwitchPage( static_cast< sal_Int16 >( Event.ItemId ) );
				}
				break;
				case TK_CheckBox1Pg1 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
						SetConfigProperty( TK_RemoveCropArea, Any( nState != 0 ) );
				}
				break;
				case TK_CheckBox2Pg1 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
						SetConfigProperty( TK_EmbedLinkedGraphics, Any( nState != 0 ) );
				}
				break;
				case TK_CheckBox0Pg2 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
					{
						SetConfigProperty( TK_OLEOptimization, Any( nState != 0 ) );
						setControlProperty( TKGet( TK_RadioButton0Pg2 ), TKGet( TK_Enabled ), Any( nState != 0 ) );
						setControlProperty( TKGet( TK_RadioButton1Pg2 ), TKGet( TK_Enabled ), Any( nState != 0 ) );
					}
				}
				break;
				case TK_RadioButton0Pg1 :
				{
					sal_Int16 nInt16 = 0;
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nInt16 )
					{
						nInt16 ^= 1;
						SetConfigProperty( TK_JPEGCompression, Any( nInt16 != 0 ) );
						setControlProperty( TKGet( TK_FixedText1Pg1 ), TKGet( TK_Enabled ), Any( nInt16 != 0 ) );
						setControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_Enabled ), Any( nInt16 != 0 ) );
					}
				}
				break;
				case TK_RadioButton1Pg1 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
					{
						SetConfigProperty( TK_JPEGCompression, Any( nState != 0 ) );
						setControlProperty( TKGet( TK_FixedText1Pg1 ), TKGet( TK_Enabled ), Any( nState != 0 ) );
						setControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_Enabled ), Any( nState != 0 ) );
					}
				}
				break;
				case TK_RadioButton0Pg2 :
				{
					sal_Int16 nInt16;
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nInt16 )
					{
						nInt16 ^= 1;
						SetConfigProperty( TK_OLEOptimizationType, Any( nInt16 ) );
					}
				}
				break;
				case TK_RadioButton1Pg2 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
						SetConfigProperty( TK_OLEOptimizationType, Any( nState ) );
				}
				break;
				case TK_CheckBox0Pg3 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
						SetConfigProperty( TK_DeleteUnusedMasterPages, Any( nState != 0 ) );
				}
				break;
				case TK_CheckBox1Pg3 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
						SetConfigProperty( TK_DeleteNotesPages, Any( nState != 0 ) );
				}
				break;
				case TK_CheckBox2Pg3 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
						SetConfigProperty( TK_DeleteHiddenSlides, Any( nState != 0 ) );
				}
				break;
				case TK_CheckBox3Pg3 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
						setControlProperty( TKGet( TK_ListBox0Pg3 ), TKGet( TK_Enabled ), Any( nState != 0 ) );
				}
				break;
				case TK_CheckBox1Pg4 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
						setControlProperty( TKGet( TK_ComboBox0Pg4 ), TKGet( TK_Enabled ), Any( nState != 0 ) );
				}
				break;
				case TK_RadioButton0Pg4 :
				case TK_RadioButton1Pg4 :
				{
					if ( xPropertySet->getPropertyValue( TKGet( TK_State ) ) >>= nState )
						SetConfigProperty( TK_SaveAs, Any( eControl == TK_RadioButton1Pg4 ? nState != 0 : nState == 0 ) );
				}
				break;
				default:
				break;
			}
		}
	}
	catch ( Exception& )
	{
	}
}

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

void OptimizerDialog::actionPerformed( const ActionEvent& rEvent )
	throw ( com::sun::star::uno::RuntimeException )
{
	switch( TKGet( rEvent.ActionCommand ) )
	{
		case TK_btnNavBack :	SwitchPage( mnCurrentStep - 1 ); break;
		case TK_btnNavNext :	SwitchPage( mnCurrentStep + 1 ); break;
		case TK_btnNavFinish :
		{
			UpdateConfiguration();

			SwitchPage( ITEM_ID_SUMMARY );
			DisablePage( ITEM_ID_SUMMARY );
			setControlProperty( TKGet( TK_btnNavHelp ), TKGet( TK_Enabled ), Any( sal_False ) );
			setControlProperty( TKGet( TK_btnNavBack ), TKGet( TK_Enabled ), Any( sal_False ) );
			setControlProperty( TKGet( TK_btnNavNext ), TKGet( TK_Enabled ), Any( sal_False ) );
			setControlProperty( TKGet( TK_btnNavFinish ), TKGet( TK_Enabled ), Any( sal_False ) );
			setControlProperty( TKGet( TK_btnNavCancel ), TKGet( TK_Enabled ), Any( sal_False ) );
			setControlProperty( TKGet( TK_FixedText0Pg4 ), TKGet( TK_Enabled ), Any( sal_True ) );

			// check if we have to open the FileDialog
			sal_Bool	bSuccessfullyExecuted = sal_True;
			sal_Int16	nInt16 = 0;
			getControlProperty( TKGet( TK_RadioButton1Pg4 ), TKGet( TK_State ) ) >>= nInt16;
			if ( nInt16 )
			{
				rtl::OUString aSaveAsURL;
				FileOpenDialog aFileOpenDialog( mxContext, Reference< XWindow >( mxParent, UNO_QUERY ) );

				// generating default file name
				Reference< XStorable > xStorable( mxModel, UNO_QUERY );
				if ( xStorable.is() && xStorable->hasLocation() )
				{
					rtl::OUString aLocation( xStorable->getLocation() );
					if ( aLocation.getLength() )
					{
						sal_Int32 nIndex = aLocation.lastIndexOf( '/', aLocation.getLength() - 1 );
						if ( nIndex >= 0 )
						{
							if ( nIndex < aLocation.getLength() - 1 )
								aLocation = aLocation.copy( nIndex + 1 );

							// remove extension
							nIndex = aLocation.lastIndexOf( '.', aLocation.getLength() - 1 );
							if ( nIndex >= 0 )
								aLocation = aLocation.copy( 0, nIndex );

							// adding .mini
							aLocation = aLocation.concat( OUString::createFromAscii( ".mini" ) );
							aFileOpenDialog.setDefaultName( aLocation );
						}
					}
				}
 				sal_Bool bDialogExecuted = aFileOpenDialog.execute() == dialogs::ExecutableDialogResults::OK;
				if ( bDialogExecuted )
				{
					aSaveAsURL = aFileOpenDialog.getURL();
					SetConfigProperty( TK_SaveAsURL, Any( aSaveAsURL ) );
					SetConfigProperty( TK_FilterName, Any( aFileOpenDialog.getFilterName() ) );
				}
				if ( !aSaveAsURL.getLength() )
				{
					// something goes wrong...
					bSuccessfullyExecuted = sal_False;
				}

				// waiting for 500ms
				if ( mxReschedule.is() )
				{
					mxReschedule->reschedule();
					for ( sal_uInt32 i = osl_getGlobalTimer(); ( i + 500 ) > ( osl_getGlobalTimer() ); )
					mxReschedule->reschedule();
				}
			}
			if ( bSuccessfullyExecuted )
			{	// now check if we have to store a session template
				nInt16 = 0;
				OUString aSettingsName;
				getControlProperty( TKGet( TK_CheckBox1Pg4 ), TKGet( TK_State ) ) >>= nInt16;
				getControlProperty( TKGet( TK_ComboBox0Pg4 ), TKGet( TK_Text ) ) >>= aSettingsName;
				if ( nInt16 && aSettingsName.getLength() )
				{
					std::vector< OptimizerSettings >::iterator aIter( GetOptimizerSettingsByName( aSettingsName ) );
					std::vector< OptimizerSettings >& rSettings( GetOptimizerSettings() );
					OptimizerSettings aNewSettings( rSettings[ 0 ] );
					aNewSettings.maName = aSettingsName;
					if ( aIter == rSettings.end() )
						rSettings.push_back( aNewSettings );
					else
						*aIter = aNewSettings;
				}
			}
			if ( bSuccessfullyExecuted )
			{
				Sequence< Any > aArgs( 1 );
				aArgs[ 0 ] <<= mxFrame;

				Reference < XDispatch > xDispatch(
					mxContext->getServiceManager()->createInstanceWithArgumentsAndContext(
						OUString( RTL_CONSTASCII_USTRINGPARAM(
							"com.sun.star.presentation.PresentationOptimizer" ) ),
						aArgs, mxContext ),
					UNO_QUERY );

				URL aURL;
				aURL.Protocol = OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.com.sun.star.presentation.PresentationOptimizer:" ) );
				aURL.Path = OUString( RTL_CONSTASCII_USTRINGPARAM( "optimize" ) );

				Sequence< PropertyValue > lArguments( 3 );
				lArguments[ 0 ].Name = TKGet( TK_Settings );
				lArguments[ 0 ].Value <<= GetConfigurationSequence();
				lArguments[ 1 ].Name = TKGet( TK_StatusListener );
				lArguments[ 1 ].Value <<= Reference< XStatusListener >( this );
				lArguments[ 2 ].Name = TKGet( TK_ParentWindow );
				lArguments[ 2 ].Value <<= mxDialogWindowPeer;

				if( xDispatch.is() )
					xDispatch->dispatch( aURL, lArguments );

				endExecute( bSuccessfullyExecuted );
			}
			else
			{
				setControlProperty( TKGet( TK_btnNavHelp ), TKGet( TK_Enabled ), Any( sal_True ) );
				setControlProperty( TKGet( TK_btnNavBack ), TKGet( TK_Enabled ), Any( sal_True ) );
				setControlProperty( TKGet( TK_btnNavNext ), TKGet( TK_Enabled ), Any( sal_False ) );
				setControlProperty( TKGet( TK_btnNavFinish ), TKGet( TK_Enabled ), Any( sal_True ) );
				setControlProperty( TKGet( TK_btnNavCancel ), TKGet( TK_Enabled ), Any( sal_True ) );
				EnablePage( ITEM_ID_SUMMARY );
			}
		}
		break;
		case TK_btnNavCancel :	endExecute( sal_False ); break;
		case TK_Button0Pg0 :	// delete configuration
		{
			OUString aSelectedItem( GetSelectedString( TK_ListBox0Pg0 ) );
			if ( aSelectedItem.getLength() )
			{
				std::vector< OptimizerSettings >::iterator aIter( GetOptimizerSettingsByName( aSelectedItem ) );
				std::vector< OptimizerSettings >& rList( GetOptimizerSettings() );
				if ( aIter != rList.end() )
				{
					rList.erase( aIter );
					UpdateControlStates();
				}
			}
		}
		break;
		default:
		{
			Reference< XControl > xControl( rEvent.Source, UNO_QUERY );
			if ( xControl.is() )
			{
				OUString aName;
				Reference< XPropertySet > xProps( xControl->getModel(), UNO_QUERY );
				xProps->getPropertyValue( TKGet( TK_Name ) ) >>= aName;
				if ( TKGet( aName ) == TK_ListBox0Pg0 )
				{
					if ( rEvent.ActionCommand.getLength() )
					{
						std::vector< OptimizerSettings >::iterator aIter( GetOptimizerSettingsByName( rEvent.ActionCommand ) );
						std::vector< OptimizerSettings >& rList( GetOptimizerSettings() );
						if ( aIter != rList.end() )
							rList[ 0 ] = *aIter;
					}
					UpdateControlStates();
				}
			}
		}
			break;
	}
}

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

void OptimizerDialog::textChanged( const TextEvent& rEvent )
	throw ( com::sun::star::uno::RuntimeException )
{
	Reference< XSpinField > xFormattedField( rEvent.Source, UNO_QUERY );
	if ( xFormattedField.is() )
	{
		double fDouble = 0;
		Any aAny = getControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_EffectiveValue ) );
		if ( aAny >>= fDouble )
			SetConfigProperty( TK_JPEGQuality, Any( (sal_Int32)fDouble ) );
		return;
	}

	Reference< XComboBox > xComboBox( rEvent.Source, UNO_QUERY );
	if ( xComboBox.is() )
	{
		rtl::OUString aString;
		Any aAny = getControlProperty( TKGet( TK_ComboBox0Pg1 ), TKGet( TK_Text ) );
		if ( aAny >>= aString )
		{
			sal_Int32 nI0, nI1, nI2, nI3, nI4;
			nI0 = nI1 = nI2 = nI3 = nI4 = 0;

			if ( getString( STR_IMAGE_RESOLUTION_0 ).getToken( 1, ';', nI0 ) == aString )
				aString = getString( STR_IMAGE_RESOLUTION_0 ).getToken( 0, ';', nI4 );
			else if ( getString( STR_IMAGE_RESOLUTION_1 ).getToken( 1, ';', nI1 ) == aString )
				aString = getString( STR_IMAGE_RESOLUTION_1 ).getToken( 0, ';', nI4 );
			else if ( getString( STR_IMAGE_RESOLUTION_2 ).getToken( 1, ';', nI2 ) == aString )
				aString = getString( STR_IMAGE_RESOLUTION_2 ).getToken( 0, ';', nI4 );
			else if ( getString( STR_IMAGE_RESOLUTION_3 ).getToken( 1, ';', nI3 ) == aString )
				aString = getString( STR_IMAGE_RESOLUTION_3 ).getToken( 0, ';', nI4 );

			SetConfigProperty( TK_ImageResolution, Any( aString.toInt32() ) );
		}
	}
}

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

void OptimizerDialog::up( const SpinEvent& /* rEvent */ )
	throw ( com::sun::star::uno::RuntimeException )
{
	double fDouble;
	Any aAny = getControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_EffectiveValue ) );
	if ( aAny >>= fDouble )
	{
		fDouble += 9;
		if ( fDouble > 100 )
			fDouble = 100;
		setControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_EffectiveValue ), Any( fDouble ) );
		SetConfigProperty( TK_JPEGQuality, Any( (sal_Int32)fDouble ) );
	}
}

void OptimizerDialog::down( const SpinEvent& /* rEvent */ )
	throw ( com::sun::star::uno::RuntimeException )
{
	double fDouble;
	Any aAny = getControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_EffectiveValue ) );
	if ( aAny >>= fDouble )
	{
		fDouble -= 9;
		if ( fDouble < 0 )
			fDouble = 0;
		setControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_EffectiveValue ), Any( fDouble ) );
		SetConfigProperty( TK_JPEGQuality, Any( (sal_Int32)fDouble ) );
	}
}

void OptimizerDialog::first( const SpinEvent& /* rEvent */ )
	throw ( com::sun::star::uno::RuntimeException )
{
	setControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_EffectiveValue ), Any( static_cast< double >( 0 ) ) );
	SetConfigProperty( TK_JPEGQuality, Any( (sal_Int32)0 ) );
}

void OptimizerDialog::last( const SpinEvent& /* rEvent */ )
	throw ( com::sun::star::uno::RuntimeException )
{
	setControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_EffectiveValue ), Any( static_cast< double >( 100 ) ) );
	SetConfigProperty( TK_JPEGQuality, Any( (sal_Int32)100 ) );
}

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