/**************************************************************
 * 
 * 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_unotools.hxx"
#ifndef GCC
#endif

#include <unotools/pathoptions.hxx>
#include <unotools/configitem.hxx>
#include <unotools/configmgr.hxx>
#include <tools/debug.hxx>
#include <tools/resmgr.hxx>
#include <tools/urlobj.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <osl/mutex.hxx>
#include <osl/file.hxx>
#include <unotools/localfilehelper.hxx>
#include <unotools/bootstrap.hxx>

#include <unotools/ucbhelper.hxx>
#include <vos/process.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/componentcontext.hxx>
#include <com/sun/star/beans/XFastPropertySet.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/util/XStringSubstitution.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/util/XMacroExpander.hpp>
#include <rtl/instance.hxx>

#include <itemholder1.hxx>

#include <vector>
#include <hash_map>

using namespace osl;
using namespace utl;
using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::beans;
using namespace com::sun::star::util;
using namespace com::sun::star::lang;

// define ----------------------------------------------------------------

#define SEARCHPATH_DELIMITER			';'

#define ASCII_STR(s)					OUString( RTL_CONSTASCII_USTRINGPARAM(s) )

#define	SIGN_STARTVARIABLE				ASCII_STR("$(")
#define	SIGN_ENDVARIABLE				ASCII_STR(")")

// Supported variables by the old SvtPathOptions implementation
#define	SUBSTITUTE_INST					"$(inst)"
#define	SUBSTITUTE_PROG					"$(prog)"
#define	SUBSTITUTE_USER					"$(user)"
#define SUBSTITUTE_INSTPATH             "$(instpath)"
#define SUBSTITUTE_PROGPATH             "$(progpath)"
#define SUBSTITUTE_USERPATH             "$(userpath)"
#define	SUBSTITUTE_INSTURL				"$(insturl)"
#define	SUBSTITUTE_PROGURL				"$(progurl)"
#define	SUBSTITUTE_USERURL				"$(userurl)"
#define	SUBSTITUTE_PATH					"$(path)"
//#define	SUBSTITUTE_LANG					"$(lang)"
#define	SUBSTITUTE_LANGID				"$(langid)"
#define	SUBSTITUTE_VLANG				"$(vlang)"
#define	SUBSTITUTE_WORKDIRURL			"$(workdirurl)"

#define STRPOS_NOTFOUND					-1

struct OUStringHashCode
{
    size_t operator()( const ::rtl::OUString& sString ) const
	{
		return sString.hashCode();
	}
};

enum VarNameProperty
{
	VAR_NEEDS_SYSTEM_PATH,
	VAR_NEEDS_FILEURL
};

class NameToHandleMap : public ::std::hash_map<	::rtl::OUString, sal_Int32, OUStringHashCode, ::std::equal_to< ::rtl::OUString > >
{
	public:
		inline void free() { NameToHandleMap().swap( *this ); }
};

class EnumToHandleMap : public ::std::hash_map< sal_Int32, sal_Int32, std::hash< sal_Int32 >, std::equal_to< sal_Int32 > >
{
	public:
		inline void free() { EnumToHandleMap().swap( *this ); }
};

class VarNameToEnumMap : public ::std::hash_map< OUString, VarNameProperty, OUStringHashCode, ::std::equal_to< OUString > >
{
	public:
		inline void free() { VarNameToEnumMap().swap( *this ); }
};


// class SvtPathOptions_Impl ---------------------------------------------
class SvtPathOptions_Impl
{
	private:
		// Local variables to return const references
		std::vector< String >				m_aPathArray;
		Reference< XFastPropertySet >		m_xPathSettings;
		Reference< XStringSubstitution >	m_xSubstVariables;
        Reference< XMacroExpander >         m_xMacroExpander;
        mutable EnumToHandleMap             m_aMapEnumToPropHandle;
		VarNameToEnumMap					m_aMapVarNamesToEnum;

	    ::com::sun::star::lang::Locale 						m_aLocale;
		String								m_aEmptyString;
        mutable ::osl::Mutex                m_aMutex;

	public:
						SvtPathOptions_Impl();

		// get the pathes, not const because of using a mutex
        const String&   GetPath( SvtPathOptions::Pathes );
        const String&   GetAddinPath() { return GetPath( SvtPathOptions::PATH_ADDIN ); }
		const String&	GetAutoCorrectPath() { return GetPath( SvtPathOptions::PATH_AUTOCORRECT ); }
		const String&	GetAutoTextPath() { return GetPath( SvtPathOptions::PATH_AUTOTEXT ); }
		const String&	GetBackupPath() { return GetPath( SvtPathOptions::PATH_BACKUP ); }
		const String&	GetBasicPath() { return GetPath( SvtPathOptions::PATH_BASIC ); }
		const String&	GetBitmapPath() { return GetPath( SvtPathOptions::PATH_BITMAP ); }
		const String&	GetConfigPath() { return GetPath( SvtPathOptions::PATH_CONFIG ); }
		const String&	GetDictionaryPath() { return GetPath( SvtPathOptions::PATH_DICTIONARY ); }
		const String&	GetFavoritesPath() { return GetPath( SvtPathOptions::PATH_FAVORITES ); }
		const String&	GetFilterPath() { return GetPath( SvtPathOptions::PATH_FILTER ); }
		const String&	GetGalleryPath() { return GetPath( SvtPathOptions::PATH_GALLERY ); }
		const String&	GetGraphicPath() { return GetPath( SvtPathOptions::PATH_GRAPHIC ); }
		const String&	GetHelpPath() { return GetPath( SvtPathOptions::PATH_HELP ); }
		const String&	GetLinguisticPath() { return GetPath( SvtPathOptions::PATH_LINGUISTIC ); }
		const String&	GetModulePath() { return GetPath( SvtPathOptions::PATH_MODULE ); }
		const String&	GetPalettePath() { return GetPath( SvtPathOptions::PATH_PALETTE ); }
		const String&	GetPluginPath() { return GetPath( SvtPathOptions::PATH_PLUGIN ); }
		const String&	GetStoragePath() { return GetPath( SvtPathOptions::PATH_STORAGE ); }
		const String&	GetTempPath() { return GetPath( SvtPathOptions::PATH_TEMP ); }
		const String&	GetTemplatePath() { return GetPath( SvtPathOptions::PATH_TEMPLATE ); }
		const String&	GetUserConfigPath() { return GetPath( SvtPathOptions::PATH_USERCONFIG ); }
		const String&	GetWorkPath() { return GetPath( SvtPathOptions::PATH_WORK ); }
	    const String&   GetUIConfigPath() { return GetPath( SvtPathOptions::PATH_UICONFIG ); }
        const String&   GetFingerprintPath() { return GetPath( SvtPathOptions::PATH_FINGERPRINT ); }

		// set the pathes
        void            SetPath( SvtPathOptions::Pathes, const String& rNewPath );
        void            SetAddinPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_ADDIN, rPath ); }
		void			SetAutoCorrectPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_AUTOCORRECT, rPath ); }
		void			SetAutoTextPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_AUTOTEXT, rPath ); }
		void			SetBackupPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_BACKUP, rPath ); }
		void			SetBasicPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_BASIC, rPath ); }
		void			SetBitmapPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_BITMAP, rPath ); }
		void			SetConfigPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_CONFIG, rPath ); }
		void			SetDictionaryPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_DICTIONARY, rPath ); }
		void			SetFavoritesPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_FAVORITES, rPath ); }
		void			SetFilterPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_FILTER, rPath ); }
		void			SetGalleryPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_GALLERY, rPath ); }
		void			SetGraphicPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_GRAPHIC, rPath ); }
		void			SetHelpPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_HELP, rPath ); }
		void			SetLinguisticPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_LINGUISTIC, rPath ); }
		void			SetModulePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_MODULE, rPath ); }
		void			SetPalettePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_PALETTE, rPath ); }
		void			SetPluginPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_PLUGIN, rPath ); }
		void			SetStoragePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_STORAGE, rPath ); }
		void			SetTempPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_TEMP, rPath ); }
		void			SetTemplatePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_TEMPLATE, rPath ); }
		void			SetUserConfigPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_USERCONFIG, rPath ); }
		void			SetWorkPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_WORK, rPath ); }

		rtl::OUString	SubstVar( const rtl::OUString& rVar ) const;
		rtl::OUString	ExpandMacros( const rtl::OUString& rPath ) const;
		rtl::OUString	UsePathVariables( const rtl::OUString& rPath ) const;

		::com::sun::star::lang::Locale	GetLocale() const { return m_aLocale; }

        sal_Bool            IsPathReadonly(SvtPathOptions::Pathes ePath)const;
};

// global ----------------------------------------------------------------

static SvtPathOptions_Impl* pOptions = NULL;
static sal_Int32 nRefCount = 0;

// functions -------------------------------------------------------------
struct PropertyStruct
{
	const char*				pPropName;	// The ascii name of the Office path
	SvtPathOptions::Pathes	ePath;		// The enum value used by SvtPathOptions
};

struct VarNameAttribute
{
	const char*				pVarName;		// The name of the path variable
	VarNameProperty			eVarProperty;	// Which return value is needed by this path variable
};

static PropertyStruct aPropNames[] =
{
	{ "Addin",			SvtPathOptions::PATH_ADDIN			},
	{ "AutoCorrect",	SvtPathOptions::PATH_AUTOCORRECT	},
	{ "AutoText",		SvtPathOptions::PATH_AUTOTEXT		},
	{ "Backup",			SvtPathOptions::PATH_BACKUP			},
	{ "Basic",			SvtPathOptions::PATH_BASIC			},
	{ "Bitmap",			SvtPathOptions::PATH_BITMAP			},
	{ "Config",			SvtPathOptions::PATH_CONFIG			},
	{ "Dictionary",		SvtPathOptions::PATH_DICTIONARY		},
	{ "Favorite",		SvtPathOptions::PATH_FAVORITES		},
	{ "Filter",			SvtPathOptions::PATH_FILTER			},
	{ "Gallery",		SvtPathOptions::PATH_GALLERY		},
	{ "Graphic",		SvtPathOptions::PATH_GRAPHIC		},
	{ "Help",			SvtPathOptions::PATH_HELP			},
	{ "Linguistic",		SvtPathOptions::PATH_LINGUISTIC		},
	{ "Module",			SvtPathOptions::PATH_MODULE			},
	{ "Palette",		SvtPathOptions::PATH_PALETTE		},
	{ "Plugin",			SvtPathOptions::PATH_PLUGIN			},
	{ "Storage",		SvtPathOptions::PATH_STORAGE		},
	{ "Temp",			SvtPathOptions::PATH_TEMP			},
	{ "Template",		SvtPathOptions::PATH_TEMPLATE		},
	{ "UserConfig",		SvtPathOptions::PATH_USERCONFIG		},
    { "Work",           SvtPathOptions::PATH_WORK			},
    { "UIConfig",       SvtPathOptions::PATH_UICONFIG		},
    { "Fingerprint",    SvtPathOptions::PATH_FINGERPRINT	}
};

static VarNameAttribute aVarNameAttribute[] =
{
	{ SUBSTITUTE_INSTPATH,	VAR_NEEDS_SYSTEM_PATH },	// $(instpath)
	{ SUBSTITUTE_PROGPATH,	VAR_NEEDS_SYSTEM_PATH },	// $(progpath)
	{ SUBSTITUTE_USERPATH,	VAR_NEEDS_SYSTEM_PATH },	// $(userpath)
	{ SUBSTITUTE_PATH,		VAR_NEEDS_SYSTEM_PATH },	// $(path)
};

#if 0
// currently unused
static Sequence< OUString > GetPathPropertyNames()
{
	const int nCount = sizeof( aPropNames ) / sizeof( PropertyStruct );
	Sequence< OUString > aNames( nCount );
	OUString* pNames = aNames.getArray();
	for ( int i = 0; i < nCount; i++ )
		pNames[i] = OUString::createFromAscii( aPropNames[i].pPropName );

	return aNames;
}
#endif

// class SvtPathOptions_Impl ---------------------------------------------

const String& SvtPathOptions_Impl::GetPath( SvtPathOptions::Pathes ePath )
{
	::osl::MutexGuard aGuard( m_aMutex );

	if ( ePath >= SvtPathOptions::PATH_COUNT )
        return m_aEmptyString;

    OUString 	aPathValue;
	String		aResult;
	sal_Int32	nHandle = m_aMapEnumToPropHandle[ (sal_Int32)ePath ];

	// Substitution is done by the service itself using the substition service
	Any 		a = m_xPathSettings->getFastPropertyValue( nHandle );
	a >>= aPathValue;
	if( ePath == SvtPathOptions::PATH_ADDIN     ||
        ePath == SvtPathOptions::PATH_FILTER    ||
        ePath == SvtPathOptions::PATH_HELP      ||
        ePath == SvtPathOptions::PATH_MODULE    ||
        ePath == SvtPathOptions::PATH_PLUGIN    ||
        ePath == SvtPathOptions::PATH_STORAGE
      )
	{
        // These office paths have to be converted to system pathes
        utl::LocalFileHelper::ConvertURLToPhysicalName( aPathValue, aResult );
        aPathValue = aResult;
	}

	m_aPathArray[ ePath ] = aPathValue;
    return m_aPathArray[ ePath ];
}
// -----------------------------------------------------------------------
sal_Bool SvtPathOptions_Impl::IsPathReadonly(SvtPathOptions::Pathes ePath)const
{
    ::osl::MutexGuard aGuard( m_aMutex );
    sal_Bool bReadonly = sal_False;
    if ( ePath < SvtPathOptions::PATH_COUNT )
    {
        Reference<XPropertySet> xPrSet(m_xPathSettings, UNO_QUERY);
        if(xPrSet.is())
        {
            Reference<XPropertySetInfo> xInfo = xPrSet->getPropertySetInfo();
			const char* pA = aPropNames[ePath].pPropName;
			::rtl::OUString sU = OUString::createFromAscii(pA);
            Property aProperty = xInfo->getPropertyByName(sU);
            bReadonly = 0 != (aProperty.Attributes & PropertyAttribute::READONLY);
        }
    }
    return bReadonly;
}
// -----------------------------------------------------------------------

void SvtPathOptions_Impl::SetPath( SvtPathOptions::Pathes ePath, const String& rNewPath )
{
	::osl::MutexGuard aGuard( m_aMutex );

	if ( ePath < SvtPathOptions::PATH_COUNT )
	{
		String 		aResult;
		OUString	aNewValue;
		Any			a;

		switch ( ePath )
		{
			case SvtPathOptions::PATH_ADDIN:
			case SvtPathOptions::PATH_FILTER:
			case SvtPathOptions::PATH_HELP:
			case SvtPathOptions::PATH_MODULE:
			case SvtPathOptions::PATH_PLUGIN:
			case SvtPathOptions::PATH_STORAGE:
			{
				// These office paths have to be convert back to UCB-URL's
				utl::LocalFileHelper::ConvertPhysicalNameToURL( rNewPath, aResult );
				aNewValue = aResult;
			}
			break;

			default:
				aNewValue = rNewPath;
		}

		// Resubstitution is done by the service itself using the substition service
		a <<= aNewValue;
		try
		{
			m_xPathSettings->setFastPropertyValue( m_aMapEnumToPropHandle[ (sal_Int32)ePath], a );
		}
		catch (const Exception&)
		{
		}
	}
}

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

OUString SvtPathOptions_Impl::ExpandMacros( const rtl::OUString& rPath ) const
{
    ::rtl::OUString sExpanded( rPath );

    const INetURLObject aParser( rPath );
    if ( aParser.GetProtocol() == INET_PROT_VND_SUN_STAR_EXPAND )
        sExpanded = m_xMacroExpander->expandMacros( aParser.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) );

    return sExpanded;
}

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

OUString SvtPathOptions_Impl::UsePathVariables( const OUString& rPath ) const
{
	return m_xSubstVariables->reSubstituteVariables( rPath );
}

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

OUString SvtPathOptions_Impl::SubstVar( const OUString& rVar ) const
{
	// Don't work at parameter-string directly. Copy it.
	OUString aWorkText = rVar;

	// Convert the returned path to system path!
	sal_Bool bConvertLocal = sal_False;

	// Search for first occur of "$(...".
	sal_Int32 nPosition	= aWorkText.indexOf( SIGN_STARTVARIABLE );	// = first position of "$(" in string
	sal_Int32 nLength	= 0;										// = count of letters from "$(" to ")" in string

	// Have we found any variable like "$(...)"?
	if ( nPosition != STRPOS_NOTFOUND )
	{
		// Yes; Get length of found variable.
		// If no ")" was found - nLength is set to 0 by default! see before.
		sal_Int32 nEndPosition = aWorkText.indexOf( SIGN_ENDVARIABLE, nPosition );
		if ( nEndPosition != STRPOS_NOTFOUND )
			nLength = nEndPosition - nPosition + 1;
	}

	// Is there another path variable?
	while ( ( nPosition != STRPOS_NOTFOUND ) && ( nLength > 0 ) )
	{
		// YES; Get the next variable for replace.
		OUString aReplacement;
		OUString aSubString = aWorkText.copy( nPosition, nLength );
        aSubString = aSubString.toAsciiLowerCase();

		// Look for special variable that needs a system path.
		VarNameToEnumMap::const_iterator pIter = m_aMapVarNamesToEnum.find( aSubString );
		if ( pIter != m_aMapVarNamesToEnum.end() )
			bConvertLocal = sal_True;

		nPosition += nLength;

		// We must control index in string before call something at OUString!
		// The OUString-implementation don't do it for us :-( but the result is not defined otherwise.
		if ( nPosition + 1 > aWorkText.getLength() )
		{
			// Position is out of range. Break loop!
			nPosition = STRPOS_NOTFOUND;
			nLength = 0;
		}
		else
		{
			// Else; Position is valid. Search for next variable.
			nPosition = aWorkText.indexOf( SIGN_STARTVARIABLE, nPosition );
			// Have we found any variable like "$(...)"?
			if ( nPosition != STRPOS_NOTFOUND )
			{
				// Yes; Get length of found variable. If no ")" was found - nLength must set to 0!
				nLength	= 0;
				sal_Int32 nEndPosition = aWorkText.indexOf( SIGN_ENDVARIABLE, nPosition );
				if ( nEndPosition != STRPOS_NOTFOUND )
					nLength = nEndPosition - nPosition + 1;
			}
		}
	}

	aWorkText = m_xSubstVariables->substituteVariables( rVar, sal_False );

	if ( bConvertLocal )
	{
		// Convert the URL to a system path for special path variables
        String aReturn;
		utl::LocalFileHelper::ConvertURLToPhysicalName( aWorkText, aReturn );
		return aReturn;
	}

    return aWorkText;
}

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

SvtPathOptions_Impl::SvtPathOptions_Impl() :
	m_aPathArray( (sal_Int32)SvtPathOptions::PATH_COUNT )
{
	Reference< XMultiServiceFactory > xSMgr = comphelper::getProcessServiceFactory();

	// Create necessary services
	m_xPathSettings = Reference< XFastPropertySet >( xSMgr->createInstance(
													::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
														"com.sun.star.util.PathSettings" ))),
												UNO_QUERY );
    if ( !m_xPathSettings.is() )
	{
        // #112719#: check for existence
		DBG_ERROR( "SvtPathOptions_Impl::SvtPathOptions_Impl(): #112719# happened again!" );
        throw RuntimeException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Service com.sun.star.util.PathSettings cannot be created" )),
            Reference< XInterface >() );
	}

    ::comphelper::ComponentContext aContext( xSMgr );
    m_xSubstVariables.set( aContext.createComponent( "com.sun.star.util.PathSubstitution" ), UNO_QUERY_THROW );
    m_xMacroExpander.set( aContext.getSingleton( "com.sun.star.util.theMacroExpander" ), UNO_QUERY_THROW );

    // Create temporary hash map to have a mapping between property names and property handles
	Reference< XPropertySet > xPropertySet = Reference< XPropertySet >( m_xPathSettings, UNO_QUERY );
	Reference< XPropertySetInfo > xPropSetInfo = xPropertySet->getPropertySetInfo();
	Sequence< Property > aPathPropSeq = xPropSetInfo->getProperties();

	NameToHandleMap aTempHashMap;
	for ( sal_Int32 n = 0; n < aPathPropSeq.getLength(); n++ )
	{
		const com::sun::star::beans::Property& aProperty = aPathPropSeq[n];
		aTempHashMap.insert( NameToHandleMap::value_type( aProperty.Name, aProperty.Handle ));
	}

	// Create mapping between internal enum (SvtPathOptions::Pathes) and property handle
	sal_Int32 nCount = sizeof( aPropNames ) / sizeof( PropertyStruct );
	sal_Int32 i;
	for ( i = 0; i < nCount; i++ )
	{
		NameToHandleMap::const_iterator pIter =
			aTempHashMap.find( rtl::OUString::createFromAscii( aPropNames[i].pPropName ));

		if ( pIter != aTempHashMap.end() )
		{
			sal_Int32 nHandle	= pIter->second;
			sal_Int32 nEnum		= aPropNames[i].ePath;
			m_aMapEnumToPropHandle.insert( EnumToHandleMap::value_type( nEnum, nHandle ));
		}
	}

	// Create hash map for path variables that need a system path as a return value!
	nCount = sizeof( aVarNameAttribute ) / sizeof( VarNameAttribute );
	for ( i = 0; i < nCount; i++ )
	{
		m_aMapVarNamesToEnum.insert( VarNameToEnumMap::value_type(
				OUString::createFromAscii( aVarNameAttribute[i].pVarName ),
				aVarNameAttribute[i].eVarProperty ));
	}

	// Set language type!
	Any aLocale = ConfigManager::GetConfigManager()->GetDirectConfigProperty( ConfigManager::LOCALE );
	OUString aLocaleStr;
	if ( aLocale >>= aLocaleStr )
    {
        sal_Int32 nIndex = 0;
        m_aLocale.Language = aLocaleStr.getToken(0, '-', nIndex );
        m_aLocale.Country = aLocaleStr.getToken(0, '-', nIndex );
        m_aLocale.Variant = aLocaleStr.getToken(0, '-', nIndex );
    }
	else
	{
		DBG_ERRORFILE( "wrong any type" );
        m_aLocale.Language = OStringToOUString(OString("en"), RTL_TEXTENCODING_UTF8);
        m_aLocale.Country =  OStringToOUString(OString("US"), RTL_TEXTENCODING_UTF8);
        m_aLocale.Variant =  OStringToOUString(OString(""), RTL_TEXTENCODING_UTF8);
	}
}

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

// class SvtPathOptions --------------------------------------------------

namespace { struct lclMutex : public rtl::Static< ::osl::Mutex, lclMutex > {}; }

SvtPathOptions::SvtPathOptions()
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( lclMutex::get() );
    if ( !pOptions )
	{
        pOptions = new SvtPathOptions_Impl;
        ItemHolder1::holdConfigItem(E_PATHOPTIONS);
	}
    ++nRefCount;
    pImp = pOptions;
}

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

SvtPathOptions::~SvtPathOptions()
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( lclMutex::get() );
    if ( !--nRefCount )
	{
        DELETEZ( pOptions );
	}
}

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

const String& SvtPathOptions::GetAddinPath() const
{
	return pImp->GetAddinPath();
}

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

const String& SvtPathOptions::GetAutoCorrectPath() const
{
	return pImp->GetAutoCorrectPath();
}

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

const String& SvtPathOptions::GetAutoTextPath() const
{
	return pImp->GetAutoTextPath();
}

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

const String& SvtPathOptions::GetBackupPath() const
{
	return pImp->GetBackupPath();
}

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

const String& SvtPathOptions::GetBasicPath() const
{
	return pImp->GetBasicPath();
}

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

const String& SvtPathOptions::GetBitmapPath() const
{
	return pImp->GetBitmapPath();
}

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

const String& SvtPathOptions::GetConfigPath() const
{
	return pImp->GetConfigPath();
}

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

const String& SvtPathOptions::GetDictionaryPath() const
{
	return pImp->GetDictionaryPath();
}

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

const String& SvtPathOptions::GetFavoritesPath() const
{
	return pImp->GetFavoritesPath();
}

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

const String& SvtPathOptions::GetFilterPath() const
{
	return pImp->GetFilterPath();
}

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

const String& SvtPathOptions::GetGalleryPath() const
{
	return pImp->GetGalleryPath();
}

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

const String& SvtPathOptions::GetGraphicPath() const
{
	return pImp->GetGraphicPath();
}

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

const String& SvtPathOptions::GetHelpPath() const
{
	return pImp->GetHelpPath();
}

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

const String& SvtPathOptions::GetLinguisticPath() const
{
	return pImp->GetLinguisticPath();
}

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

const String& SvtPathOptions::GetFingerprintPath() const
{
    return pImp->GetFingerprintPath();
}

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

const String& SvtPathOptions::GetModulePath() const
{
	return pImp->GetModulePath();
}

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

const String& SvtPathOptions::GetPalettePath() const
{
	return pImp->GetPalettePath();
}

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

const String& SvtPathOptions::GetPluginPath() const
{
	return pImp->GetPluginPath();
}

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

const String& SvtPathOptions::GetStoragePath() const
{
	return pImp->GetStoragePath();
}

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

const String& SvtPathOptions::GetTempPath() const
{
	return pImp->GetTempPath();
}

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

const String& SvtPathOptions::GetTemplatePath() const
{
	return pImp->GetTemplatePath();
}

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

const String& SvtPathOptions::GetUserConfigPath() const
{
	return pImp->GetUserConfigPath();
}

const String& SvtPathOptions::GetUIConfigPath() const
{
    return pImp->GetUIConfigPath();
}

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

const String& SvtPathOptions::GetWorkPath() const
{
	return pImp->GetWorkPath();
}

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

void SvtPathOptions::SetAddinPath( const String& rPath )
{
	pImp->SetAddinPath( rPath );
}

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

void SvtPathOptions::SetAutoCorrectPath( const String& rPath )
{
	pImp->SetAutoCorrectPath( rPath );
}

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

void SvtPathOptions::SetAutoTextPath( const String& rPath )
{
	pImp->SetAutoTextPath( rPath );
}

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

void SvtPathOptions::SetBackupPath( const String& rPath )
{
	pImp->SetBackupPath( rPath );
}

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

void SvtPathOptions::SetBasicPath( const String& rPath )
{
	pImp->SetBasicPath( rPath );
}

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

void SvtPathOptions::SetBitmapPath( const String& rPath )
{
	pImp->SetBitmapPath( rPath );
}

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

void SvtPathOptions::SetConfigPath( const String& rPath )
{
	pImp->SetConfigPath( rPath );
}

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

void SvtPathOptions::SetDictionaryPath( const String& rPath )
{
	pImp->SetDictionaryPath( rPath );
}

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

void SvtPathOptions::SetFavoritesPath( const String& rPath )
{
	pImp->SetFavoritesPath( rPath );
}

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

void SvtPathOptions::SetFilterPath( const String& rPath )
{
	pImp->SetFilterPath( rPath );
}

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

void SvtPathOptions::SetGalleryPath( const String& rPath )
{
	pImp->SetGalleryPath( rPath );
}

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

void SvtPathOptions::SetGraphicPath( const String& rPath )
{
	pImp->SetGraphicPath( rPath );
}

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

void SvtPathOptions::SetHelpPath( const String& rPath )
{
	pImp->SetHelpPath( rPath );
}

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

void SvtPathOptions::SetLinguisticPath( const String& rPath )
{
	pImp->SetLinguisticPath( rPath );
}

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

void SvtPathOptions::SetModulePath( const String& rPath )
{
	pImp->SetModulePath( rPath );
}

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

void SvtPathOptions::SetPalettePath( const String& rPath )
{
	pImp->SetPalettePath( rPath );
}

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

void SvtPathOptions::SetPluginPath( const String& rPath )
{
	pImp->SetPluginPath( rPath );
}

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

void SvtPathOptions::SetStoragePath( const String& rPath )
{
	pImp->SetStoragePath( rPath );
}

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

void SvtPathOptions::SetTempPath( const String& rPath )
{
	pImp->SetTempPath( rPath );
}

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

void SvtPathOptions::SetTemplatePath( const String& rPath )
{
	pImp->SetTemplatePath( rPath );
}

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

void SvtPathOptions::SetUserConfigPath( const String& rPath )
{
	pImp->SetUserConfigPath( rPath );
}

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

void SvtPathOptions::SetWorkPath( const String& rPath )
{
	pImp->SetWorkPath( rPath );
}

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

String SvtPathOptions::SubstituteVariable( const String& rVar ) const
{
    String aRet = pImp->SubstVar( rVar );
	return aRet;
}

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

String SvtPathOptions::ExpandMacros( const String& rPath ) const
{
    return pImp->ExpandMacros( rPath );
}

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

String SvtPathOptions::UseVariable( const String& rPath ) const
{
    String aRet = pImp->UsePathVariables( rPath );
	return aRet;
}

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

sal_Bool SvtPathOptions::SearchFile( String& rIniFile, Pathes ePath )
{
	// check parameter: empty inifile name?
	if ( !rIniFile.Len() )
	{
		DBG_ERRORFILE( "SvtPathOptions::SearchFile(): invalid parameter" );
		return sal_False;
	}

    String aIniFile = pImp->SubstVar( rIniFile );
	sal_Bool bRet = sal_False;

	switch ( ePath )
	{
		case PATH_USERCONFIG:
		{
            // path is a URL
			bRet = sal_True;
            INetURLObject aObj( GetUserConfigPath() );
			xub_StrLen i, nCount = aIniFile.GetTokenCount( '/' );
			for ( i = 0; i < nCount; ++i )
				aObj.insertName( aIniFile.GetToken( i, '/' ) );

            if ( !::utl::UCBContentHelper::Exists( aObj.GetMainURL( INetURLObject::NO_DECODE ) ) )
			{
                aObj.SetSmartURL( GetConfigPath() );
				aObj.insertName( aIniFile );
                bRet = ::utl::UCBContentHelper::Exists( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
			}

			if ( bRet )
				rIniFile = aObj.GetMainURL( INetURLObject::NO_DECODE );

			break;
		}

		default:
		{
			String aPath;
			switch ( ePath )
			{
				case PATH_ADDIN:		aPath = GetAddinPath();			break;
				case PATH_AUTOCORRECT:	aPath = GetAutoCorrectPath();	break;
				case PATH_AUTOTEXT:		aPath = GetAutoTextPath();		break;
				case PATH_BACKUP:		aPath = GetBackupPath();		break;
				case PATH_BASIC:		aPath = GetBasicPath();			break;
				case PATH_BITMAP:		aPath = GetBitmapPath();		break;
				case PATH_CONFIG:		aPath = GetConfigPath();		break;
				case PATH_DICTIONARY:	aPath = GetDictionaryPath();	break;
				case PATH_FAVORITES:	aPath = GetFavoritesPath();		break;
				case PATH_FILTER:		aPath = GetFilterPath();		break;
				case PATH_GALLERY:		aPath = GetGalleryPath();		break;
				case PATH_GRAPHIC:		aPath = GetGraphicPath();		break;
				case PATH_HELP:			aPath = GetHelpPath();			break;
				case PATH_LINGUISTIC:	aPath = GetLinguisticPath();	break;
				case PATH_MODULE:		aPath = GetModulePath();		break;
				case PATH_PALETTE:		aPath = GetPalettePath();		break;
				case PATH_PLUGIN:		aPath = GetPluginPath();		break;
				case PATH_STORAGE:		aPath = GetStoragePath();		break;
				case PATH_TEMP:			aPath = GetTempPath();			break;
				case PATH_TEMPLATE:		aPath = GetTemplatePath();      break;
				case PATH_WORK:			aPath = GetWorkPath();			break;
                case PATH_UICONFIG:     aPath = GetUIConfigPath();      break;
                case PATH_FINGERPRINT:  aPath = GetFingerprintPath();   break;
				case PATH_USERCONFIG:/*-Wall???*/			break;
                case PATH_COUNT: /*-Wall???*/ break;
			}

			sal_uInt16 j, nIdx = 0, nTokenCount = aPath.GetTokenCount( SEARCHPATH_DELIMITER );
			for ( j = 0; j < nTokenCount; ++j )
			{
                sal_Bool bIsURL = sal_True;
				String aPathToken = aPath.GetToken( 0, SEARCHPATH_DELIMITER, nIdx );
				INetURLObject aObj( aPathToken );
				if ( aObj.HasError() )
				{
                    bIsURL = sal_False;
					String aURL;
					if ( LocalFileHelper::ConvertPhysicalNameToURL( aPathToken, aURL ) )
						aObj.SetURL( aURL );
				}
                if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_EXPAND )
                {
                    ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
                    Reference< XMacroExpander > xMacroExpander( aContext.getSingleton( "com.sun.star.util.theMacroExpander" ), UNO_QUERY );
                    OSL_ENSURE( xMacroExpander.is(), "SvtPathOptions::SearchFile: unable to access the MacroExpander singleton!" );
                    if ( xMacroExpander.is() )
                    {
                        const ::rtl::OUString sExpandedPath = xMacroExpander->expandMacros( aObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) );
                        aObj.SetURL( sExpandedPath );
                    }
                }

				xub_StrLen i, nCount = aIniFile.GetTokenCount( '/' );
				for ( i = 0; i < nCount; ++i )
					aObj.insertName( aIniFile.GetToken( i, '/' ) );
                bRet = ::utl::UCBContentHelper::Exists( aObj.GetMainURL( INetURLObject::NO_DECODE ) );

				if ( bRet )
				{
                    if ( !bIsURL )
                        ::utl::LocalFileHelper::ConvertURLToPhysicalName(
											aObj.GetMainURL( INetURLObject::NO_DECODE ), rIniFile );
					else
						rIniFile = aObj.GetMainURL( INetURLObject::NO_DECODE );
					break;
				}
			}
		}
	}

	return bRet;
}

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

::com::sun::star::lang::Locale SvtPathOptions::GetLocale() const
{
	return pImp->GetLocale();
}
// -----------------------------------------------------------------------
sal_Bool SvtPathOptions::IsPathReadonly(Pathes ePath)const
{
    return pImp->IsPathReadonly(ePath);
}
// -----------------------------------------------------------------------
const String& SvtPathOptions::GetPath(Pathes ePath)const
{
    return pImp->GetPath(ePath);
}
// -----------------------------------------------------------------------
void SvtPathOptions::SetPath( SvtPathOptions::Pathes ePath, const String& rNewPath )
{
    pImp->SetPath(ePath, rNewPath);
}

// class PathService -----------------------------------------------------
#include <com/sun/star/frame/XConfigManager.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <cppuhelper/implbase2.hxx>

class PathService : public ::cppu::WeakImplHelper2< ::com::sun::star::frame::XConfigManager, ::com::sun::star::lang::XServiceInfo >
{
    virtual ::rtl::OUString	SAL_CALL	getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL			supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
										getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL	substituteVariables( const ::rtl::OUString& sText ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL				addPropertyChangeListener( const ::rtl::OUString& sKeyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL				removePropertyChangeListener( const ::rtl::OUString& sKeyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL				flush(  ) throw(::com::sun::star::uno::RuntimeException);
};

// class PathService -----------------------------------------------------

void SAL_CALL PathService::addPropertyChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) throw(::com::sun::star::uno::RuntimeException) {}
void SAL_CALL PathService::removePropertyChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) throw(::com::sun::star::uno::RuntimeException) {}
void SAL_CALL PathService::flush(  ) throw(::com::sun::star::uno::RuntimeException) {}

::rtl::OUString SAL_CALL PathService::substituteVariables( const ::rtl::OUString& sText ) throw(::com::sun::star::uno::RuntimeException)
{
    return SvtPathOptions().SubstituteVariable( sText );
}

::rtl::OUString SAL_CALL PathService::getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException)
{
    return OUString::createFromAscii("com.sun.star.comp.unotools.PathService");
}

sal_Bool SAL_CALL PathService::supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException)
{
    if ( ServiceName.compareToAscii("com.sun.star.config.SpecialConfigManager") == COMPARE_EQUAL )
        return sal_True;
    else
        return sal_False;
}

::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL PathService::getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException)
{
    Sequence< OUString > aRet(1);
    *aRet.getArray() = OUString::createFromAscii("com.sun.star.config.SpecialConfigManager");
    return aRet;
}
