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



#include "precompiled_basctl.hxx"
#include <ide_pch.hxx>

#include <basidesh.hxx> 
#include <baside3.hxx>
#include <basobj.hxx>
#include <iderdll.hxx>
#include "dlged.hxx"

#include <localizationmgr.hxx> 
#include <com/sun/star/resource/XStringResourceSupplier.hpp>
#include <com/sun/star/frame/XLayoutManager.hpp>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::resource;

static ::rtl::OUString aDot  = ::rtl::OUString::createFromAscii( "." );
static ::rtl::OUString aEsc  = ::rtl::OUString::createFromAscii( "&" );
static ::rtl::OUString aSemi = ::rtl::OUString::createFromAscii( ";" );


LocalizationMgr::LocalizationMgr( BasicIDEShell* pIDEShell,
    const ScriptDocument& rDocument, String aLibName,
	const Reference< XStringResourceManager >& xStringResourceManager )
		: m_xStringResourceManager( xStringResourceManager )
		, m_pIDEShell( pIDEShell )
		, m_aDocument( rDocument )
		, m_aLibName( aLibName )
{
}

bool LocalizationMgr::isLibraryLocalized( void )
{
	bool bRet = false;
	if( m_xStringResourceManager.is() )
	{
		Sequence< Locale > aLocaleSeq = m_xStringResourceManager->getLocales();
		bRet = ( aLocaleSeq.getLength() > 0 );
	}
	return bRet;
}

void LocalizationMgr::handleTranslationbar( void )
{
	static ::rtl::OUString aLayoutManagerName = ::rtl::OUString::createFromAscii( "LayoutManager" );
	static ::rtl::OUString aToolBarResName =
		::rtl::OUString::createFromAscii( "private:resource/toolbar/translationbar" );

	Reference< beans::XPropertySet > xFrameProps
		( m_pIDEShell->GetViewFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY );
	if ( xFrameProps.is() )
    {
		Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
		uno::Any a = xFrameProps->getPropertyValue( aLayoutManagerName );
		a >>= xLayoutManager;
        if ( xLayoutManager.is() )
        {
			if ( !isLibraryLocalized() )
            {
                xLayoutManager->destroyElement( aToolBarResName );
            }
            else
            {
                xLayoutManager->createElement( aToolBarResName );
                xLayoutManager->requestElement( aToolBarResName );
            }
        }
    }
}


//============================================
// TODO: -> export from toolkit

struct LanguageDependentProp
{
    const char* pPropName;
    sal_Int32   nPropNameLength;
};

static LanguageDependentProp aLanguageDependentProp[] =
{
    { "Text",            4 },
    { "Label",           5 },
    { "Title",           5 },
    { "HelpText",        8 },
    { "CurrencySymbol", 14 },
    { "StringItemList", 14 },
    { 0, 0                 }
};

bool isLanguageDependentProperty( ::rtl::OUString aName )
{
	bool bRet = false;

	LanguageDependentProp* pLangDepProp = aLanguageDependentProp;
	while( pLangDepProp->pPropName != 0 )
	{
		if( aName.equalsAsciiL( pLangDepProp->pPropName, pLangDepProp->nPropNameLength ))
		{
			bRet = true;
			break;
		}
		pLangDepProp++;
	}
	return bRet;
} 
//============================================
 
void LocalizationMgr::implEnableDisableResourceForAllLibraryDialogs( HandleResourceMode eMode )
{
    Sequence< ::rtl::OUString > aDlgNames = m_aDocument.getObjectNames( E_DIALOGS, m_aLibName );
    sal_Int32 nDlgCount = aDlgNames.getLength();
    const ::rtl::OUString* pDlgNames = aDlgNames.getConstArray();

	Reference< XStringResourceResolver > xDummyStringResolver;
	for( sal_Int32 i = 0 ; i < nDlgCount ; i++ )
	{
		String aDlgName = pDlgNames[ i ];
		DialogWindow* pWin = m_pIDEShell->FindDlgWin( m_aDocument, m_aLibName, aDlgName, sal_False );
		if( pWin && dynamic_cast< DialogWindow* >(pWin) )
		{
			DialogWindow* pDialogWin = static_cast< DialogWindow* >( pWin );
			Reference< container::XNameContainer > xDialog = pDialogWin->GetDialog();
			if( xDialog.is() )
			{
				// Handle dialog itself as control
				Any aDialogCtrl;
				aDialogCtrl <<= xDialog;
				implHandleControlResourceProperties( aDialogCtrl, aDlgName,
					::rtl::OUString(), m_xStringResourceManager, xDummyStringResolver, eMode );

				// Handle all controls
				Sequence< ::rtl::OUString > aNames = xDialog->getElementNames();
				const ::rtl::OUString* pNames = aNames.getConstArray();
				sal_Int32 nCtrls = aNames.getLength();
				for( sal_Int32 j = 0 ; j < nCtrls ; ++j )
				{
					::rtl::OUString aCtrlName( pNames[j] );
					Any aCtrl = xDialog->getByName( aCtrlName );
					implHandleControlResourceProperties( aCtrl, aDlgName,
						aCtrlName, m_xStringResourceManager, xDummyStringResolver, eMode );
				}
			}
		}
	}
}


::rtl::OUString implCreatePureResourceId
	( const ::rtl::OUString& aDialogName, const ::rtl::OUString& aCtrlName,
	  const ::rtl::OUString& aPropName,
	  Reference< XStringResourceManager > xStringResourceManager )
{
	sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
	::rtl::OUString aPureIdStr = ::rtl::OUString::valueOf( nUniqueId );
	aPureIdStr += aDot;
	aPureIdStr += aDialogName;
	aPureIdStr += aDot;
	if( !aCtrlName.isEmpty() )
	{
		aPureIdStr += aCtrlName;
		aPureIdStr += aDot;
	}
	aPureIdStr += aPropName;
	return aPureIdStr;
}

extern bool localesAreEqual( const ::com::sun::star::lang::Locale& rLocaleLeft,
							 const ::com::sun::star::lang::Locale& rLocaleRight );

// Works on xStringResourceManager's current language for SET_IDS/RESET_IDS,
// anyway only one language should exist when calling this method then, 
// either the first one for mode SET_IDS or the last one for mode RESET_IDS
sal_Int32 LocalizationMgr::implHandleControlResourceProperties
	( Any aControlAny, const ::rtl::OUString& aDialogName, const ::rtl::OUString& aCtrlName,
		Reference< XStringResourceManager > xStringResourceManager, 
		Reference< XStringResourceResolver > xSourceStringResolver, HandleResourceMode eMode )
{
	sal_Int32 nChangedCount = 0;

	Reference< XPropertySet > xPropertySet;
	aControlAny >>= xPropertySet;
	if( xPropertySet.is() )
	{
		Sequence< Locale > aLocaleSeq = xStringResourceManager->getLocales();
		sal_Int32 nLocaleCount = aLocaleSeq.getLength();
		if( nLocaleCount == 0 )
			return 0;

		Reference< XPropertySetInfo > xPropertySetInfo = xPropertySet->getPropertySetInfo();
		if( xPropertySetInfo.is() )
		{
			// get sequence of control properties
			Sequence< Property > aPropSeq = xPropertySetInfo->getProperties();
			const Property* pProps = aPropSeq.getConstArray();
			sal_Int32 nCtrlProps = aPropSeq.getLength();

			// create a map of tab indices and control names, sorted by tab index
			for( sal_Int32 j = 0 ; j < nCtrlProps ; ++j )
			{
				const Property& rProp = pProps[j];
				::rtl::OUString aPropName = rProp.Name;
		        TypeClass eType = rProp.Type.getTypeClass();
				bool bLanguageDependentProperty =
					(eType == TypeClass_STRING || eType == TypeClass_SEQUENCE)
					&& isLanguageDependentProperty( aPropName );
				if( !bLanguageDependentProperty )
					continue;

				if( eType == TypeClass_STRING )
				{
					Any aPropAny = xPropertySet->getPropertyValue( aPropName );
					::rtl::OUString aPropStr;
					aPropAny >>= aPropStr;

					// Replace string by id, add id+string to StringResource
					if( eMode == SET_IDS )
					{
						bool bEscAlreadyExisting = (!aPropStr.isEmpty() && aPropStr.getStr()[0] == '&' );
						if( bEscAlreadyExisting )
							continue;

						::rtl::OUString aPureIdStr = implCreatePureResourceId
							( aDialogName, aCtrlName, aPropName, xStringResourceManager );

						// Set Id for all locales
						const Locale* pLocales = aLocaleSeq.getConstArray();
						for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
						{
							const Locale& rLocale = pLocales[ i ];
							xStringResourceManager->setStringForLocale( aPureIdStr, aPropStr, rLocale );
						}

						::rtl::OUString aPropIdStr = aEsc;
						aPropIdStr += aPureIdStr;
						// TODO?: Change here and in toolkit
						//aPropIdStr += aSemi;
						(void)aSemi;
						aPropAny <<= aPropIdStr;
						xPropertySet->setPropertyValue( aPropName, aPropAny );
					}
					// Replace id by string from StringResource
					else if( eMode == RESET_IDS )
					{
						if( aPropStr.getLength() > 1 )
						{
							::rtl::OUString aPureIdStr = aPropStr.copy( 1 );
							::rtl::OUString aNewPropStr = aPropStr;
							try
							{
								aNewPropStr = xStringResourceManager->resolveString( aPureIdStr );
							}
							catch(MissingResourceException&)
							{
							}
							aPropAny <<= aNewPropStr;
							xPropertySet->setPropertyValue( aPropName, aPropAny );
						}
					}
					// Remove Id for all locales
					else if( eMode == REMOVE_IDS_FROM_RESOURCE )
					{
						if( aPropStr.getLength() > 1 )
						{
							::rtl::OUString aPureIdStr = aPropStr.copy( 1 );

							const Locale* pLocales = aLocaleSeq.getConstArray();
							for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
							{
								const Locale& rLocale = pLocales[ i ];
								try
								{
									xStringResourceManager->removeIdForLocale( aPureIdStr, rLocale );
								}
								catch(MissingResourceException&)
								{
								}
							}
						}
					}
					// Rename resource id
					else if( eMode == RENAME_DIALOG_IDS || eMode == RENAME_CONTROL_IDS )
					{
						::rtl::OUString aSourceIdStr = aPropStr;
						::rtl::OUString aPureSourceIdStr = aSourceIdStr.copy( 1 );

						::rtl::OUString aPureIdStr = implCreatePureResourceId
							( aDialogName, aCtrlName, aPropName, xStringResourceManager );

						// Set new Id and remove old one for all locales
						const Locale* pLocales = aLocaleSeq.getConstArray();
						for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
						{
							const Locale& rLocale = pLocales[ i ];
							::rtl::OUString aResStr;
							try
							{
								aResStr = xStringResourceManager->resolveStringForLocale
									( aPureSourceIdStr, rLocale );
								xStringResourceManager->removeIdForLocale( aPureSourceIdStr, rLocale );
								xStringResourceManager->setStringForLocale( aPureIdStr, aResStr, rLocale );
							}
							catch(MissingResourceException&)
							{}
						}

						::rtl::OUString aPropIdStr = aEsc;
						aPropIdStr += aPureIdStr;
						// TODO?: Change here and in toolkit
						//aPropIdStr += aSemi;
						(void)aSemi;
						aPropAny <<= aPropIdStr;
						xPropertySet->setPropertyValue( aPropName, aPropAny );
					}
					// Replace string by string from source StringResourceResolver
					else if( eMode == MOVE_RESOURCES && xSourceStringResolver.is() )
					{
						::rtl::OUString aSourceIdStr = aPropStr;
						::rtl::OUString aPureSourceIdStr = aSourceIdStr.copy( 1 );

						::rtl::OUString aPureIdStr = implCreatePureResourceId
							( aDialogName, aCtrlName, aPropName, xStringResourceManager );

						const Locale& rDefaultLocale = xSourceStringResolver->getDefaultLocale();

						// Set Id for all locales
						const Locale* pLocales = aLocaleSeq.getConstArray();
						for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
						{
							const Locale& rLocale = pLocales[ i ];
							::rtl::OUString aResStr;
							try
							{
								aResStr = xSourceStringResolver->resolveStringForLocale
									( aPureSourceIdStr, rLocale );
							}
							catch(MissingResourceException&)
							{
								aResStr = xSourceStringResolver->resolveStringForLocale
									( aPureSourceIdStr, rDefaultLocale );
							}
							xStringResourceManager->setStringForLocale( aPureIdStr, aResStr, rLocale );
						}

						::rtl::OUString aPropIdStr = aEsc;
						aPropIdStr += aPureIdStr;
						// TODO?: Change here and in toolkit
						//aPropIdStr += aSemi;
						(void)aSemi;
						aPropAny <<= aPropIdStr;
						xPropertySet->setPropertyValue( aPropName, aPropAny );
					}
					// Copy string from source to target resource
					else if( eMode == COPY_RESOURCES && xSourceStringResolver.is() )
					{
						::rtl::OUString aSourceIdStr = aPropStr;
						::rtl::OUString aPureSourceIdStr = aSourceIdStr.copy( 1 );

						const Locale& rDefaultLocale = xSourceStringResolver->getDefaultLocale();

						// Copy Id for all locales
						const Locale* pLocales = aLocaleSeq.getConstArray();
						for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
						{
							const Locale& rLocale = pLocales[ i ];
							::rtl::OUString aResStr;
							try
							{
								aResStr = xSourceStringResolver->resolveStringForLocale
									( aPureSourceIdStr, rLocale );
							}
							catch(MissingResourceException&)
							{
								aResStr = xSourceStringResolver->resolveStringForLocale
									( aPureSourceIdStr, rDefaultLocale );
							}
							xStringResourceManager->setStringForLocale( aPureSourceIdStr, aResStr, rLocale );
						}
					}
					nChangedCount++;
				}

				// Listbox / Combobox
				else if( eType == TypeClass_SEQUENCE )
				{
					Any aPropAny = xPropertySet->getPropertyValue( aPropName );
					Sequence< ::rtl::OUString > aPropStrings;
					aPropAny >>= aPropStrings;

					const ::rtl::OUString* pPropStrings = aPropStrings.getConstArray();
					sal_Int32 nPropStringCount = aPropStrings.getLength();
					if( nPropStringCount == 0 )
						continue;

					// Replace string by id, add id+string to StringResource
					if( eMode == SET_IDS )
					{
						Sequence< ::rtl::OUString > aIdStrings;
						aIdStrings.realloc( nPropStringCount );
						::rtl::OUString* pIdStrings = aIdStrings.getArray();

						::rtl::OUString aIdStrBase = aDot;
						aIdStrBase += aCtrlName;
						aIdStrBase += aDot;
						aIdStrBase += aPropName;

						const Locale* pLocales = aLocaleSeq.getConstArray();
						sal_Int32 i;
						for ( i = 0; i < nPropStringCount; ++i )
						{
							::rtl::OUString aPropStr = pPropStrings[i];
							bool bEscAlreadyExisting = (!aPropStr.isEmpty() && aPropStr.getStr()[0] == '&' );
							if( bEscAlreadyExisting )
							{
								pIdStrings[i] = aPropStr;
								continue;
							}

							sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
							::rtl::OUString aPureIdStr = ::rtl::OUString::valueOf( nUniqueId );
							aPureIdStr += aIdStrBase;

							// Set Id for all locales
							for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
							{
								const Locale& rLocale = pLocales[ iLocale ];
								xStringResourceManager->setStringForLocale( aPureIdStr, aPropStr, rLocale );
							}

							::rtl::OUString aPropIdStr = aEsc;
							aPropIdStr += aPureIdStr;
							pIdStrings[i] = aPropIdStr;
						}
						aPropAny <<= aIdStrings;
						xPropertySet->setPropertyValue( aPropName, aPropAny );
					}
					// Replace id by string from StringResource
					else if( eMode == RESET_IDS )
					{
						Sequence< ::rtl::OUString > aNewPropStrings;
						aNewPropStrings.realloc( nPropStringCount );
						::rtl::OUString* pNewPropStrings = aNewPropStrings.getArray();

						sal_Int32 i;
						for ( i = 0; i < nPropStringCount; ++i )
						{
							::rtl::OUString aIdStr = pPropStrings[i];
							::rtl::OUString aNewPropStr = aIdStr;
							if( aIdStr.getLength() > 1 )
							{
								::rtl::OUString aPureIdStr = aIdStr.copy( 1 );
								try
								{
									aNewPropStr = xStringResourceManager->resolveString( aPureIdStr );
								}
								catch(MissingResourceException&)
								{
								}
							}
							pNewPropStrings[i] = aNewPropStr;
						}
						aPropAny <<= aNewPropStrings;
						xPropertySet->setPropertyValue( aPropName, aPropAny );
					}
					// Remove Id for all locales
					else if( eMode == REMOVE_IDS_FROM_RESOURCE )
					{
						Sequence< ::rtl::OUString > aNewPropStrings;
						aNewPropStrings.realloc( nPropStringCount );

						const Locale* pLocales = aLocaleSeq.getConstArray();
						sal_Int32 i;
						for ( i = 0; i < nPropStringCount; ++i )
						{
							::rtl::OUString aIdStr = pPropStrings[i];
							if( aIdStr.getLength() > 1 )
							{
								::rtl::OUString aPureIdStr = aIdStr.copy( 1 );

								for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
								{
									const Locale& rLocale = pLocales[iLocale];
									try
									{
										xStringResourceManager->removeIdForLocale( aPureIdStr, rLocale );
									}
									catch(MissingResourceException&)
									{
									}
								}
							}
						}
					}
					// Rename resource id
					else if( eMode == RENAME_CONTROL_IDS )
					{
						Sequence< ::rtl::OUString > aIdStrings;
						aIdStrings.realloc( nPropStringCount );
						::rtl::OUString* pIdStrings = aIdStrings.getArray();

						::rtl::OUString aIdStrBase = aDot;
						aIdStrBase += aCtrlName;
						aIdStrBase += aDot;
						aIdStrBase += aPropName;

						const Locale* pLocales = aLocaleSeq.getConstArray();
						sal_Int32 i;
						for ( i = 0; i < nPropStringCount; ++i )
						{
							::rtl::OUString aSourceIdStr = pPropStrings[i];
							::rtl::OUString aPureSourceIdStr = aSourceIdStr.copy( 1 );

							sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
							::rtl::OUString aPureIdStr = ::rtl::OUString::valueOf( nUniqueId );
							aPureIdStr += aIdStrBase;

							// Set Id for all locales
							for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
							{
								const Locale& rLocale = pLocales[ iLocale ];

								::rtl::OUString aResStr;
								try
								{
									aResStr = xStringResourceManager->resolveStringForLocale
										( aPureSourceIdStr, rLocale );
									xStringResourceManager->removeIdForLocale( aPureSourceIdStr, rLocale );
									xStringResourceManager->setStringForLocale( aPureIdStr, aResStr, rLocale );
								}
								catch(MissingResourceException&)
								{}
							}

							::rtl::OUString aPropIdStr = aEsc;
							aPropIdStr += aPureIdStr;
							pIdStrings[i] = aPropIdStr;
						}
						aPropAny <<= aIdStrings;
						xPropertySet->setPropertyValue( aPropName, aPropAny );
					}
					// Replace string by string from source StringResourceResolver
					else if( eMode == MOVE_RESOURCES && xSourceStringResolver.is() )
					{
						Sequence< ::rtl::OUString > aIdStrings;
						aIdStrings.realloc( nPropStringCount );
						::rtl::OUString* pIdStrings = aIdStrings.getArray();

						::rtl::OUString aIdStrBase = aDot;
						aIdStrBase += aCtrlName;
						aIdStrBase += aDot;
						aIdStrBase += aPropName;

						const Locale& rDefaultLocale = xSourceStringResolver->getDefaultLocale();

						const Locale* pLocales = aLocaleSeq.getConstArray();
						sal_Int32 i;
						for ( i = 0; i < nPropStringCount; ++i )
						{
							::rtl::OUString aSourceIdStr = pPropStrings[i];
							::rtl::OUString aPureSourceIdStr = aSourceIdStr.copy( 1 );

							sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
							::rtl::OUString aPureIdStr = ::rtl::OUString::valueOf( nUniqueId );
							aPureIdStr += aIdStrBase;

							// Set Id for all locales
							for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
							{
								const Locale& rLocale = pLocales[ iLocale ];

								::rtl::OUString aResStr;
								try
								{
									aResStr = xSourceStringResolver->resolveStringForLocale
										( aPureSourceIdStr, rLocale );
								}
								catch(MissingResourceException&)
								{
									aResStr = xSourceStringResolver->resolveStringForLocale
										( aPureSourceIdStr, rDefaultLocale );
								}
								xStringResourceManager->setStringForLocale( aPureIdStr, aResStr, rLocale );
							}

							::rtl::OUString aPropIdStr = aEsc;
							aPropIdStr += aPureIdStr;
							pIdStrings[i] = aPropIdStr;
						}
						aPropAny <<= aIdStrings;
						xPropertySet->setPropertyValue( aPropName, aPropAny );
					}
					// Copy string from source to target resource
					else if( eMode == COPY_RESOURCES && xSourceStringResolver.is() )
					{
						const Locale& rDefaultLocale = xSourceStringResolver->getDefaultLocale();

						const Locale* pLocales = aLocaleSeq.getConstArray();
						sal_Int32 i;
						for ( i = 0; i < nPropStringCount; ++i )
						{
							::rtl::OUString aSourceIdStr = pPropStrings[i];
							::rtl::OUString aPureSourceIdStr = aSourceIdStr.copy( 1 );

							// Set Id for all locales
							for( sal_Int32 iLocale = 0 ; iLocale < nLocaleCount ; iLocale++ )
							{
								const Locale& rLocale = pLocales[ iLocale ];

								::rtl::OUString aResStr;
								try
								{
									aResStr = xSourceStringResolver->resolveStringForLocale
										( aPureSourceIdStr, rLocale );
								}
								catch(MissingResourceException&)
								{
									aResStr = xSourceStringResolver->resolveStringForLocale
										( aPureSourceIdStr, rDefaultLocale );
								}
								xStringResourceManager->setStringForLocale( aPureSourceIdStr, aResStr, rLocale );
							}
						}
					}
					nChangedCount++;
				}
			}
		}
	}
	return nChangedCount;
}

/*
void TEST_simulateDialogAddRemoveLocale( bool bAdd )
{
	Sequence< Locale > aLocaleSeq( 1 );
	Locale* pLocales = aLocaleSeq.getArray();

	::com::sun::star::lang::Locale aLocale_en;
	aLocale_en.Language = ::rtl::OUString::createFromAscii( "en" );
	aLocale_en.Country = ::rtl::OUString::createFromAscii( "US" );

	::com::sun::star::lang::Locale aLocale_de;
	aLocale_de.Language = ::rtl::OUString::createFromAscii( "de" );
	aLocale_de.Country = ::rtl::OUString::createFromAscii( "DE" );

	::com::sun::star::lang::Locale aLocale_fr;
	aLocale_fr.Language = ::rtl::OUString::createFromAscii( "fr" );
	aLocale_fr.Country = ::rtl::OUString::createFromAscii( "FR" );

	int n = 0;
	if( n == 0 )
		pLocales[0] = aLocale_en;
	else if( n == 1 )
		pLocales[0] = aLocale_de;
	else if( n == 2 )
		pLocales[0] = aLocale_fr;

	BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
	LocalizationMgr* pMgr = pIDEShell->GetCurLocalizationMgr();
	if( bAdd )
		pMgr->handleAddLocales( aLocaleSeq );
	else
		pMgr->handleRemoveLocales( aLocaleSeq );
}

void TEST_simulateDialogAddLocale( void )
{
	TEST_simulateDialogAddRemoveLocale( true );
}

void TEST_simulateDialogRemoveLocale( void )
{
	TEST_simulateDialogAddRemoveLocale( false );
}
*/

void LocalizationMgr::handleAddLocales( Sequence< Locale > aLocaleSeq )
{
	const Locale* pLocales = aLocaleSeq.getConstArray();
	sal_Int32 nLocaleCount = aLocaleSeq.getLength();

	if( isLibraryLocalized() )
	{
		for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
		{
			const Locale& rLocale = pLocales[ i ];
			m_xStringResourceManager->newLocale( rLocale );
		}
	}
	else
	{
		DBG_ASSERT( nLocaleCount==1, "LocalizationMgr::handleAddLocales(): Only one first locale allowed" );

		const Locale& rLocale = pLocales[ 0 ];
		m_xStringResourceManager->newLocale( rLocale );
		enableResourceForAllLibraryDialogs();
	}

	BasicIDE::MarkDocumentModified( m_aDocument );

	// update locale toolbar
    SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
    if ( pBindings )
		pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );

	handleTranslationbar();
}


void LocalizationMgr::handleRemoveLocales( Sequence< Locale > aLocaleSeq )
{
	const Locale* pLocales = aLocaleSeq.getConstArray();
	sal_Int32 nLocaleCount = aLocaleSeq.getLength();
	bool bConsistant = true;
	bool bModified = false;

	for( sal_Int32 i = 0 ; i < nLocaleCount ; i++ )
	{
		const Locale& rLocale = pLocales[ i ];
		bool bRemove = true;

		// Check if last locale
		Sequence< Locale > aResLocaleSeq = m_xStringResourceManager->getLocales();
		if( aResLocaleSeq.getLength() == 1 )
        {
			const Locale& rLastResLocale = aResLocaleSeq.getConstArray()[ 0 ];
			if( localesAreEqual( rLocale, rLastResLocale ) )
			{
				disableResourceForAllLibraryDialogs();
			}
			else
			{
				// Inconsistancy, keep last locale
				bConsistant = false;
				bRemove = false;
			}
        }

		if( bRemove )
        {
			try
			{
				m_xStringResourceManager->removeLocale( rLocale );
				bModified = true;
			}
			catch(IllegalArgumentException&)
			{
				bConsistant = false;
			}
        }
	}
	if( bModified )
	{
		BasicIDE::MarkDocumentModified( m_aDocument );

		// update slots
        SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
        if ( pBindings )
		{
			pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );
			pBindings->Invalidate( SID_BASICIDE_MANAGE_LANG );
		}

		handleTranslationbar();
	}

	DBG_ASSERT( bConsistant, 
		"LocalizationMgr::handleRemoveLocales(): sequence contains unsupported locales" );
}

void LocalizationMgr::handleSetDefaultLocale( Locale aLocale )
{
	if( m_xStringResourceManager.is() )
	{
		try
		{
			m_xStringResourceManager->setDefaultLocale( aLocale );
		}
		catch(IllegalArgumentException&)
		{
			DBG_ERROR( "LocalizationMgr::handleSetDefaultLocale: Invalid locale" );
		}

		// update locale toolbar
        SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
        if ( pBindings )
			pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );
	}
}

void LocalizationMgr::handleSetCurrentLocale( ::com::sun::star::lang::Locale aLocale )
{
	if( m_xStringResourceManager.is() )
	{
		try
		{
			m_xStringResourceManager->setCurrentLocale( aLocale, false );
		}
		catch(IllegalArgumentException&)
		{
			DBG_ERROR( "LocalizationMgr::handleSetCurrentLocale: Invalid locale" );
		}

		// update locale toolbar
        SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
        if ( pBindings )
			pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );

		IDEBaseWindow* pCurWin = m_pIDEShell->GetCurWindow();
		if ( pCurWin && !pCurWin->IsSuspended() && dynamic_cast< DialogWindow* >(pCurWin) )
		{
			DialogWindow* pDlgWin = (DialogWindow*)pCurWin;
			DlgEditor* pWinEditor = pDlgWin->GetEditor();
			if( pWinEditor )
				pWinEditor->UpdatePropertyBrowserDelayed();
		}
	}
}

void LocalizationMgr::handleBasicStarted( void )
{
	if( m_xStringResourceManager.is() )
		m_aLocaleBeforeBasicStart = m_xStringResourceManager->getCurrentLocale();
}

void LocalizationMgr::handleBasicStopped( void )
{
	try
	{
		if( m_xStringResourceManager.is() )
			m_xStringResourceManager->setCurrentLocale( m_aLocaleBeforeBasicStart, true );
	}
	catch(IllegalArgumentException&)
	{
	}
}


DialogWindow* FindDialogWindowForEditor( DlgEditor* pEditor )
{
	BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
	IDEWindowTable& aIDEWindowTable = pIDEShell->GetIDEWindowTable();
	IDEBaseWindow* pWin = aIDEWindowTable.First();
	DialogWindow* pFoundDlgWin = NULL;
	while( pWin )
	{
		if ( !pWin->IsSuspended() && dynamic_cast< DialogWindow* >(pWin) )
		{
			DialogWindow* pDlgWin = (DialogWindow*)pWin;
			DlgEditor* pWinEditor = pDlgWin->GetEditor();
			if( pWinEditor == pEditor )
			{
				pFoundDlgWin = pDlgWin;
				break;
			}
		}
		pWin = aIDEWindowTable.Next();
	}
	return pFoundDlgWin;
} 


void LocalizationMgr::setControlResourceIDsForNewEditorObject( DlgEditor* pEditor,
	Any aControlAny, const ::rtl::OUString& aCtrlName )
{
	// Get library for DlgEditor
	DialogWindow* pDlgWin = FindDialogWindowForEditor( pEditor );
	if( !pDlgWin )
		return;
    ScriptDocument aDocument( pDlgWin->GetDocument() );
    DBG_ASSERT( aDocument.isValid(), "LocalizationMgr::setControlResourceIDsForNewEditorObject: invalid document!" );
    if ( !aDocument.isValid() )
        return;
	const String& rLibName = pDlgWin->GetLibName();
	Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, rLibName, sal_True ) );
	Reference< XStringResourceManager > xStringResourceManager =
		LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );

	// Set resource property
	if( !xStringResourceManager.is() || xStringResourceManager->getLocales().getLength() == 0 )
		return;

	::rtl::OUString aDialogName = pDlgWin->GetName();
	Reference< XStringResourceResolver > xDummyStringResolver;
	sal_Int32 nChangedCount = implHandleControlResourceProperties
		( aControlAny, aDialogName, aCtrlName, xStringResourceManager,
		  xDummyStringResolver, SET_IDS );

	if( nChangedCount )
		BasicIDE::MarkDocumentModified( aDocument );
} 

void LocalizationMgr::renameControlResourceIDsForEditorObject( DlgEditor* pEditor,
	::com::sun::star::uno::Any aControlAny, const ::rtl::OUString& aNewCtrlName )
{
	// Get library for DlgEditor
	DialogWindow* pDlgWin = FindDialogWindowForEditor( pEditor );
	if( !pDlgWin )
		return;
    ScriptDocument aDocument( pDlgWin->GetDocument() );
    DBG_ASSERT( aDocument.isValid(), "LocalizationMgr::renameControlResourceIDsForEditorObject: invalid document!" );
    if ( !aDocument.isValid() )
        return;
	const String& rLibName = pDlgWin->GetLibName();
	Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, rLibName, sal_True ) );
	Reference< XStringResourceManager > xStringResourceManager =
		LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );

	// Set resource property
	if( !xStringResourceManager.is() || xStringResourceManager->getLocales().getLength() == 0 )
		return;

	::rtl::OUString aDialogName = pDlgWin->GetName();
	Reference< XStringResourceResolver > xDummyStringResolver;
	implHandleControlResourceProperties
		( aControlAny, aDialogName, aNewCtrlName, xStringResourceManager,
		  xDummyStringResolver, RENAME_CONTROL_IDS );
} 


void LocalizationMgr::deleteControlResourceIDsForDeletedEditorObject( DlgEditor* pEditor,
	Any aControlAny, const ::rtl::OUString& aCtrlName )
{
	// Get library for DlgEditor
	DialogWindow* pDlgWin = FindDialogWindowForEditor( pEditor );
	if( !pDlgWin )
		return;
    ScriptDocument aDocument( pDlgWin->GetDocument() );
    DBG_ASSERT( aDocument.isValid(), "LocalizationMgr::deleteControlResourceIDsForDeletedEditorObject: invalid document!" );
    if ( !aDocument.isValid() )
        return;
	const String& rLibName = pDlgWin->GetLibName();
	Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, rLibName, sal_True ) );
	Reference< XStringResourceManager > xStringResourceManager =
		LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );

	::rtl::OUString aDialogName = pDlgWin->GetName();
	Reference< XStringResourceResolver > xDummyStringResolver;
	sal_Int32 nChangedCount = implHandleControlResourceProperties
		( aControlAny, aDialogName, aCtrlName, xStringResourceManager,
		  xDummyStringResolver, REMOVE_IDS_FROM_RESOURCE );

	if( nChangedCount )
		BasicIDE::MarkDocumentModified( aDocument );
} 

void LocalizationMgr::setStringResourceAtDialog( const ScriptDocument& rDocument, const String& aLibName,
	const String& aDlgName, Reference< container::XNameContainer > xDialogModel )
{
	static ::rtl::OUString aResourceResolverPropName = ::rtl::OUString::createFromAscii( "ResourceResolver" );

	// Get library
	Reference< container::XNameContainer > xDialogLib( rDocument.getLibrary( E_DIALOGS, aLibName, sal_True ) );
	Reference< XStringResourceManager > xStringResourceManager =
		LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );

	// Set resource property
	if( xStringResourceManager.is() )
	{
		// Not very elegant as dialog may or may not be localized yet
		// TODO: Find better place, where dialog is created
		if( xStringResourceManager->getLocales().getLength() > 0 )
		{
			Any aDialogCtrl;
			aDialogCtrl <<= xDialogModel;
			Reference< XStringResourceResolver > xDummyStringResolver;
			implHandleControlResourceProperties( aDialogCtrl, aDlgName,
				::rtl::OUString(), xStringResourceManager,
				xDummyStringResolver, SET_IDS );
		}

		Reference< beans::XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY );
		Any aStringResourceManagerAny;
		aStringResourceManagerAny <<= xStringResourceManager;
		xDlgPSet->setPropertyValue( aResourceResolverPropName, aStringResourceManagerAny );
	}
}

void LocalizationMgr::renameStringResourceIDs( const ScriptDocument& rDocument, const String& aLibName,
	const String& aDlgName, Reference< container::XNameContainer > xDialogModel )
{
	// Get library
	Reference< container::XNameContainer > xDialogLib( rDocument.getLibrary( E_DIALOGS, aLibName, sal_True ) );
	Reference< XStringResourceManager > xStringResourceManager =
		LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
	if( !xStringResourceManager.is() )
		return;

	Any aDialogCtrl;
	aDialogCtrl <<= xDialogModel;
	Reference< XStringResourceResolver > xDummyStringResolver;
	implHandleControlResourceProperties( aDialogCtrl, aDlgName,
		::rtl::OUString(), xStringResourceManager,
		xDummyStringResolver, RENAME_DIALOG_IDS );

	// Handle all controls
	Sequence< ::rtl::OUString > aNames = xDialogModel->getElementNames();
	const ::rtl::OUString* pNames = aNames.getConstArray();
	sal_Int32 nCtrls = aNames.getLength();
	for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
	{
		::rtl::OUString aCtrlName( pNames[i] );
		Any aCtrl = xDialogModel->getByName( aCtrlName );
		implHandleControlResourceProperties( aCtrl, aDlgName,
			aCtrlName, xStringResourceManager,
			xDummyStringResolver, RENAME_DIALOG_IDS );
	}
}

void LocalizationMgr::removeResourceForDialog( const ScriptDocument& rDocument, const String& aLibName,
	const String& aDlgName, Reference< container::XNameContainer > xDialogModel )
{
	// Get library
	Reference< container::XNameContainer > xDialogLib( rDocument.getLibrary( E_DIALOGS, aLibName, sal_True ) );
	Reference< XStringResourceManager > xStringResourceManager =
		LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
	if( !xStringResourceManager.is() )
		return;

	Any aDialogCtrl;
	aDialogCtrl <<= xDialogModel;
	Reference< XStringResourceResolver > xDummyStringResolver;
	implHandleControlResourceProperties( aDialogCtrl, aDlgName,
		::rtl::OUString(), xStringResourceManager,
		xDummyStringResolver, REMOVE_IDS_FROM_RESOURCE );

	// Handle all controls
	Sequence< ::rtl::OUString > aNames = xDialogModel->getElementNames();
	const ::rtl::OUString* pNames = aNames.getConstArray();
	sal_Int32 nCtrls = aNames.getLength();
	for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
	{
		::rtl::OUString aCtrlName( pNames[i] );
		Any aCtrl = xDialogModel->getByName( aCtrlName );
		implHandleControlResourceProperties( aCtrl, aDlgName,
			aCtrlName, xStringResourceManager,
			xDummyStringResolver, REMOVE_IDS_FROM_RESOURCE );
	}
}

void LocalizationMgr::resetResourceForDialog( Reference< container::XNameContainer > xDialogModel,
	Reference< XStringResourceManager > xStringResourceManager )
{
	if( !xStringResourceManager.is() )
		return;

	// Dialog as control
	::rtl::OUString aDummyName;
	Any aDialogCtrl;
	aDialogCtrl <<= xDialogModel;
	Reference< XStringResourceResolver > xDummyStringResolver;
	implHandleControlResourceProperties( aDialogCtrl, aDummyName,
		aDummyName, xStringResourceManager, xDummyStringResolver, RESET_IDS );

	// Handle all controls
	Sequence< ::rtl::OUString > aNames = xDialogModel->getElementNames();
	const ::rtl::OUString* pNames = aNames.getConstArray();
	sal_Int32 nCtrls = aNames.getLength();
	for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
	{
		::rtl::OUString aCtrlName( pNames[i] );
		Any aCtrl = xDialogModel->getByName( aCtrlName );
		implHandleControlResourceProperties( aCtrl, aDummyName,
			aCtrlName, xStringResourceManager, xDummyStringResolver, RESET_IDS );
	}
}

void LocalizationMgr::setResourceIDsForDialog( Reference< container::XNameContainer > xDialogModel,
	Reference< XStringResourceManager > xStringResourceManager )
{
	if( !xStringResourceManager.is() )
		return;

	// Dialog as control
	::rtl::OUString aDummyName;
	Any aDialogCtrl;
	aDialogCtrl <<= xDialogModel;
	Reference< XStringResourceResolver > xDummyStringResolver;
	implHandleControlResourceProperties( aDialogCtrl, aDummyName,
		aDummyName, xStringResourceManager, xDummyStringResolver, SET_IDS );

	// Handle all controls
	Sequence< ::rtl::OUString > aNames = xDialogModel->getElementNames();
	const ::rtl::OUString* pNames = aNames.getConstArray();
	sal_Int32 nCtrls = aNames.getLength();
	for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
	{
		::rtl::OUString aCtrlName( pNames[i] );
		Any aCtrl = xDialogModel->getByName( aCtrlName );
		implHandleControlResourceProperties( aCtrl, aDummyName,
			aCtrlName, xStringResourceManager, xDummyStringResolver, SET_IDS );
	}
}

void LocalizationMgr::copyResourcesForPastedEditorObject( DlgEditor* pEditor,
	Any aControlAny, const ::rtl::OUString& aCtrlName,
	Reference< XStringResourceResolver > xSourceStringResolver )
{
	// Get library for DlgEditor
	DialogWindow* pDlgWin = FindDialogWindowForEditor( pEditor );
	if( !pDlgWin )
		return;
    ScriptDocument aDocument( pDlgWin->GetDocument() );
    DBG_ASSERT( aDocument.isValid(), "LocalizationMgr::copyResourcesForPastedEditorObject: invalid document!" );
    if ( !aDocument.isValid() )
        return;
	const String& rLibName = pDlgWin->GetLibName();
	Reference< container::XNameContainer > xDialogLib( aDocument.getLibrary( E_DIALOGS, rLibName, sal_True ) );
	Reference< XStringResourceManager > xStringResourceManager =
		LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );

	// Set resource property
	if( !xStringResourceManager.is() || xStringResourceManager->getLocales().getLength() == 0 )
		return;

	::rtl::OUString aDialogName = pDlgWin->GetName();
	implHandleControlResourceProperties
		( aControlAny, aDialogName, aCtrlName, xStringResourceManager,
		  xSourceStringResolver, MOVE_RESOURCES );
} 

void LocalizationMgr::copyResourceForDroppedDialog( Reference< container::XNameContainer > xDialogModel,
	const ::rtl::OUString& aDialogName, Reference< XStringResourceManager > xStringResourceManager,
	Reference< XStringResourceResolver > xSourceStringResolver )
{
	if( !xStringResourceManager.is() )
		return;

	// Dialog as control
	::rtl::OUString aDummyName;
	Any aDialogCtrl;
	aDialogCtrl <<= xDialogModel;
	implHandleControlResourceProperties( aDialogCtrl, aDialogName,
		aDummyName, xStringResourceManager, xSourceStringResolver, MOVE_RESOURCES );

	// Handle all controls
	Sequence< ::rtl::OUString > aNames = xDialogModel->getElementNames();
	const ::rtl::OUString* pNames = aNames.getConstArray();
	sal_Int32 nCtrls = aNames.getLength();
	for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
	{
		::rtl::OUString aCtrlName( pNames[i] );
		Any aCtrl = xDialogModel->getByName( aCtrlName );
		implHandleControlResourceProperties( aCtrl, aDialogName,
			aCtrlName, xStringResourceManager, xSourceStringResolver, MOVE_RESOURCES );
	}
}

void LocalizationMgr::copyResourceForDialog(
	const Reference< container::XNameContainer >& xDialogModel,
	const Reference< XStringResourceResolver >& xSourceStringResolver,
	const Reference< XStringResourceManager >& xTargetStringResourceManager )
{
	if( !xDialogModel.is() || !xSourceStringResolver.is() || !xTargetStringResourceManager.is() )
		return;

	::rtl::OUString aDummyName;
	Any aDialogCtrl;
	aDialogCtrl <<= xDialogModel;
	implHandleControlResourceProperties
		( aDialogCtrl, aDummyName, aDummyName, xTargetStringResourceManager,
		  xSourceStringResolver, COPY_RESOURCES );

	// Handle all controls
	Sequence< ::rtl::OUString > aNames = xDialogModel->getElementNames();
	const ::rtl::OUString* pNames = aNames.getConstArray();
	sal_Int32 nCtrls = aNames.getLength();
	for( sal_Int32 i = 0 ; i < nCtrls ; ++i )
	{
		::rtl::OUString aCtrlName( pNames[i] );
		Any aCtrl = xDialogModel->getByName( aCtrlName );
		implHandleControlResourceProperties( aCtrl, aDummyName, aDummyName,
			xTargetStringResourceManager, xSourceStringResolver, COPY_RESOURCES );
	}
}

Reference< XStringResourceManager > LocalizationMgr::getStringResourceFromDialogLibrary
	( Reference< container::XNameContainer > xDialogLib )
{
	Reference< XStringResourceManager > xStringResourceManager;
	if( xDialogLib.is() )
	{
		Reference< resource::XStringResourceSupplier > xStringResourceSupplier( xDialogLib, UNO_QUERY );
		if( xStringResourceSupplier.is() )
		{
			Reference< resource::XStringResourceResolver >
				xStringResourceResolver = xStringResourceSupplier->getStringResource();

			xStringResourceManager = 
				Reference< resource::XStringResourceManager >( xStringResourceResolver, UNO_QUERY );
		}
	}
	return xStringResourceManager;
}

