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

#include <string.h>
#include <rtl/ustrbuf.hxx>
#ifndef _VOS_DIAGNOSE_HXX_
#include <vos/diagnose.hxx>
#endif
#include "tvread.hxx"
#include <expat.h>
#include <osl/file.hxx>
#include <com/sun/star/frame/XConfigManager.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>

#include <comphelper/processfactory.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
#include <com/sun/star/util/XMacroExpander.hpp>
#include <com/sun/star/uri/XUriReferenceFactory.hpp>
#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
#include <comphelper/locale.hxx>

namespace treeview {

	
	class TVDom
	{
		friend class TVChildTarget;
		friend class TVRead;
	
	public:
		
		TVDom( TVDom* arent = 0 )
			: kind( other ),
              parent( arent ),
			  childs( 0 )
		{
		}

		~TVDom()
		{
			for( unsigned i = 0; i < childs.size(); ++i )
				delete childs[i];
		}
	
	
		TVDom* newChild()
		{
			childs.push_back( new TVDom( this ) );
			return childs.back();
		}
	
	
		TVDom* getParent() const
		{
			if( parent )
				return parent;
			else
				return const_cast<TVDom*>(this);    // I am my own parent, if I am the root
		}

		enum Kind {
			tree_view,
			tree_node,
			tree_leaf,
			other
		};
	
		bool isLeaf() const { return kind == TVDom::tree_leaf; }
		void setKind( Kind ind ) { kind = ind; }
		Kind getKind( ) const { return kind; }
	
	
		void setApplication( const char* appl )
		{
			application = rtl::OUString( (sal_Char*)(appl),
										 strlen( appl ),
										 RTL_TEXTENCODING_UTF8 );
		}
	
		void setTitle( const char* itle )
		{
			title += rtl::OUString( (sal_Char*)(itle),
                                    strlen( itle ),
                                    RTL_TEXTENCODING_UTF8 );
		}
        
		void setTitle( const XML_Char* itle,int len )
		{
			title += rtl::OUString( (sal_Char*)(itle),
                                    len,
                                    RTL_TEXTENCODING_UTF8 );
		}
	
		void setId( const char* d )
		{
			id = rtl::OUString( (sal_Char*)(d),
								strlen( d ),
								RTL_TEXTENCODING_UTF8 );
		}	

		void setAnchor( const char* nchor )
		{
			anchor = rtl::OUString( (sal_Char*)(nchor),
									strlen( nchor ),
									RTL_TEXTENCODING_UTF8 );
		}

		rtl::OUString getTargetURL()
		{
			if( ! targetURL.getLength() )
			{
				sal_Int32 len;
                for ( const TVDom* p = this;; p = p->parent )
                {
                    len = p->application.getLength();
                    if ( len != 0 )
                        break;
                }
				
				rtl::OUStringBuffer strBuff( 22 + len + id.getLength() );
				strBuff.appendAscii(
									"vnd.sun.star.help://"
									).append(id);
				
				targetURL = strBuff.makeStringAndClear();
			}
			
			return targetURL;
		}
	
	private:
	
		Kind   kind;
		rtl::OUString  application;
		rtl::OUString  title;
		rtl::OUString  id;
		rtl::OUString  anchor;
		rtl::OUString  targetURL;
		
		TVDom *parent;
		std::vector< TVDom* > childs;
	};

}



using namespace treeview;
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::beans;
using namespace com::sun::star::lang;
using namespace com::sun::star::util;
using namespace com::sun::star::frame;
using namespace com::sun::star::container;
using namespace com::sun::star::deployment;


ConfigData::ConfigData()
	: prodName( rtl::OUString::createFromAscii( "%PRODUCTNAME" ) ),
	  prodVersion( rtl::OUString::createFromAscii( "%PRODUCTVERSION" ) ),
	  vendName( rtl::OUString::createFromAscii( "%VENDORNAME" ) ),
	  vendVersion( rtl::OUString::createFromAscii( "%VENDORVERSION" ) ),
	  vendShort( rtl::OUString::createFromAscii( "%VENDORSHORT" ) )
{
}

void SAL_CALL ConfigData::replaceName( rtl::OUString& oustring ) const
{
	sal_Int32 idx = -1,k = 0,off;
	bool cap = false;
	rtl::OUStringBuffer aStrBuf( 0 );
	
	while( ( idx = oustring.indexOf( sal_Unicode('%'),++idx ) ) != -1 )
	{
		if( oustring.indexOf( prodName,idx ) == idx )
			off = PRODUCTNAME;
		else if( oustring.indexOf( prodVersion,idx ) == idx )
			off = PRODUCTVERSION;
		else if( oustring.indexOf( vendName,idx ) == idx )
			off = VENDORNAME;
		else if( oustring.indexOf( vendVersion,idx ) == idx )
			off = VENDORVERSION;
		else if( oustring.indexOf( vendShort,idx ) == idx )
			off = VENDORSHORT;
		else
			off = -1;
		
		if( off != -1 )
		{
			if( ! cap )
			{
				cap = true;
				aStrBuf.ensureCapacity( 256 );
			}
			
			aStrBuf.append( &oustring.getStr()[k],idx - k );
			aStrBuf.append( m_vReplacement[off] );
			k = idx + m_vAdd[off];
		}
	}
	
	if( cap )
	{
		if( k < oustring.getLength() )
			aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k );
		oustring = aStrBuf.makeStringAndClear();
	}
}




//////////////////////////////////////////////////////////////////////////
// XInterface
//////////////////////////////////////////////////////////////////////////


void SAL_CALL
TVBase::acquire(
	void )
	throw()
{
  OWeakObject::acquire();
}


void SAL_CALL
TVBase::release(
		      void )
  throw()
{
  OWeakObject::release();
}


Any SAL_CALL
TVBase::queryInterface(
	const Type& rType )
	throw( RuntimeException )
{
	Any aRet = cppu::queryInterface( rType,
									 SAL_STATIC_CAST( XTypeProvider*, this ),
									 SAL_STATIC_CAST( XNameAccess*, this ),
									 SAL_STATIC_CAST( XHierarchicalNameAccess*, this ),
									 SAL_STATIC_CAST( XChangesNotifier*, this ),
									 SAL_STATIC_CAST( XComponent*, this ) );
	
	return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}


////////////////////////////////////////////////////////////////////////////////
//
// XTypeProvider methods.

XTYPEPROVIDER_IMPL_5( TVBase,
				   	  XTypeProvider,
					  XNameAccess,
					  XHierarchicalNameAccess,
					  XChangesNotifier,
					  XComponent );






// TVRead


TVRead::TVRead( const ConfigData& configData,TVDom* tvDom )
{
	if( ! tvDom )
		return;
	
	Title = tvDom->title;
	configData.replaceName( Title );
	if( tvDom->isLeaf() )
	{
		TargetURL = ( tvDom->getTargetURL() + configData.appendix );
		if( tvDom->anchor.getLength() )
			TargetURL += ( rtl::OUString::createFromAscii( "#" ) +
						   tvDom->anchor );
	}
	else
		Children = new TVChildTarget( configData,tvDom );
}



TVRead::~TVRead()
{
}






// XNameAccess

Any SAL_CALL
TVRead::getByName( const rtl::OUString& aName )
	throw( NoSuchElementException,
		   WrappedTargetException,
		   RuntimeException )
{
	bool found( true );
	Any aAny;
	if( aName.compareToAscii( "Title" ) == 0 )
		aAny <<= Title;
	else if( aName.compareToAscii( "TargetURL" ) == 0 )
		aAny <<= TargetURL;
	else if( aName.compareToAscii( "Children" ) == 0 )
	{			   
		cppu::OWeakObject* p = Children.get();
		aAny <<= Reference< XInterface >( p );
	}
	else
		found = false;
	
	if( found )
		return aAny;

	throw NoSuchElementException();
}




Sequence< rtl::OUString > SAL_CALL
TVRead::getElementNames( )
	throw( RuntimeException )
{
	Sequence< rtl::OUString > seq( 3 );
	
	seq[0] = rtl::OUString::createFromAscii( "Title" );
	seq[1] = rtl::OUString::createFromAscii( "TargetURL" );
	seq[2] = rtl::OUString::createFromAscii( "Children" );

	return seq;
}



sal_Bool SAL_CALL
TVRead::hasByName( const rtl::OUString& aName )
	throw( RuntimeException )
{
	if( aName.compareToAscii( "Title" ) == 0        ||
		aName.compareToAscii( "TargetURL" ) == 0    ||
		aName.compareToAscii( "Children" ) == 0 )
		return true;
	
	return false;
}


// XHierarchicalNameAccess

Any SAL_CALL
TVRead::getByHierarchicalName( const rtl::OUString& aName )
	throw( NoSuchElementException,
		   RuntimeException )
{
	sal_Int32 idx;
	rtl::OUString name( aName );
	
	if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1  &&
		name.copy( 0,idx ).compareToAscii( "Children" ) == 0 )
		return Children->getByHierarchicalName( name.copy( 1 + idx ) );
	
	return getByName( name );
}




sal_Bool SAL_CALL
TVRead::hasByHierarchicalName( const rtl::OUString& aName )
	throw( RuntimeException )
{
	sal_Int32 idx;
	rtl::OUString name( aName );
	
   	if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1  &&
		name.copy( 0,idx ).compareToAscii( "Children" ) == 0 )
		return Children->hasByHierarchicalName( name.copy( 1 + idx ) );
	
	return hasByName( name );
}



/**************************************************************************/
/*                                                                        */
/*                      TVChildTarget                                     */
/*                                                                        */
/**************************************************************************/




extern "C" void start_handler(void *userData,
				   const XML_Char *name,
				   const XML_Char **atts)
{	
	TVDom::Kind kind;
	
	if( strcmp( name,"help_section" ) == 0  ||
		strcmp( name,"node" ) == 0 )
		kind = TVDom::tree_node;
	else if( strcmp( name,"topic" ) == 0 )
		kind = TVDom::tree_leaf;
	else
		return;
	
	TVDom **tvDom = static_cast< TVDom** >( userData );
	TVDom  *p;
	p = *tvDom;

	*tvDom = p->newChild();
	p = *tvDom;
	
	p->setKind( kind );
	while( *atts )
	{
		if( strcmp( *atts,"application" ) == 0 )
			p->setApplication( *(atts+1) );
		else if( strcmp( *atts,"title" ) == 0 )
			p->setTitle( *(atts+1) );
		else if( strcmp( *atts,"id" ) == 0 )
			p->setId( *(atts+1) );
		else if( strcmp( *atts,"anchor" ) == 0 )
			p->setAnchor( *(atts+1) );
		
		atts+=2;
	}
}


extern "C" void end_handler(void *userData,
				 const XML_Char *name )
{
	(void)name;

	TVDom **tvDom = static_cast< TVDom** >( userData );
	*tvDom = (*tvDom)->getParent();
}


extern "C" void data_handler( void *userData,
				   const XML_Char *s,
				   int len)
{
	TVDom **tvDom = static_cast< TVDom** >( userData );
	if( (*tvDom)->isLeaf() )
		(*tvDom)->setTitle( s,len );
}



TVChildTarget::TVChildTarget( const ConfigData& configData,TVDom* tvDom )
{
	Elements.resize( tvDom->childs.size() );
	for( unsigned i = 0; i < Elements.size(); ++i )
		Elements[i] = new TVRead( configData,tvDom->childs[i] );
}
	
							  



TVChildTarget::TVChildTarget( const Reference< XMultiServiceFactory >& xMSF )
{	
	ConfigData configData = init( xMSF );

	if( ! configData.locale.getLength()  ||
		! configData.system.getLength() )
		return;
	
	sal_uInt64 	ret,len = 0;
	int j = configData.vFileURL.size();
	
	TVDom tvDom;
	TVDom* pTVDom = &tvDom;

	while( j )
	{
		len = configData.vFileLen[--j];
		char* s = new char[ int(len) ];  // the buffer to hold the installed files
		osl::File aFile( configData.vFileURL[j] );
		aFile.open( OpenFlag_Read );
		aFile.read( s,len,ret );
		aFile.close();
		
		XML_Parser parser = XML_ParserCreate( 0 );
		XML_SetElementHandler( parser,
							   start_handler,
							   end_handler );
		XML_SetCharacterDataHandler( parser,
									 data_handler);
		XML_SetUserData( parser,&pTVDom ); // does not return this
		
		int parsed = XML_Parse( parser,s,int( len ),j==0 );
        (void)parsed;
		OSL_ENSURE( parsed, "TVChildTarget::TVChildTarget(): Tree file parsing failed" );
		
		XML_ParserFree( parser );		
		delete[] s;
	}	
	
	// now TVDom holds the relevant information

	Elements.resize( tvDom.childs.size() );
	for( unsigned i = 0; i < Elements.size(); ++i )
		Elements[i] = new TVRead( configData,tvDom.childs[i] );
}


TVChildTarget::~TVChildTarget()
{
}



Any SAL_CALL
TVChildTarget::getByName( const rtl::OUString& aName )
	throw( NoSuchElementException,
		   WrappedTargetException,
		   RuntimeException )
{
	rtl::OUString num( aName.getStr()+2,aName.getLength()-4 ); 
	sal_Int32 idx = num.toInt32() - 1;
	if( idx < 0 || Elements.size() <= sal_uInt32( idx ) )
		throw NoSuchElementException();
	
	Any aAny;
	cppu::OWeakObject* p = Elements[idx].get();
	aAny <<= Reference< XInterface >( p );
	return aAny;
}




Sequence< rtl::OUString > SAL_CALL
TVChildTarget::getElementNames( )
	throw( RuntimeException )
{
	Sequence< rtl::OUString > seq( Elements.size() );
	for( unsigned i = 0; i < Elements.size(); ++i )
		seq[i] = rtl::OUString::valueOf( sal_Int32( 1+i ) );
	
	return seq;
}



sal_Bool SAL_CALL
TVChildTarget::hasByName( const rtl::OUString& aName )
	throw( RuntimeException )
{
	rtl::OUString num( aName.getStr()+2,aName.getLength()-4 ); 
	sal_Int32 idx = num.toInt32() - 1;
	if( idx < 0 || Elements.size() <= sal_uInt32( idx ) )
		return false;
	
	return true;
}



// XHierarchicalNameAccess

Any SAL_CALL
TVChildTarget::getByHierarchicalName( const rtl::OUString& aName )
	throw( NoSuchElementException,
		   RuntimeException )
{
	sal_Int32 idx;
	rtl::OUString name( aName );
	
	if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 )
	{
		rtl::OUString num( name.getStr()+2,idx-4 ); 
		sal_Int32 pref = num.toInt32() - 1;
		
		if( pref < 0 || Elements.size() <= sal_uInt32( pref ) )
			throw NoSuchElementException();
		
		return Elements[pref]->getByHierarchicalName( name.copy( 1 + idx ) );
	}
	else
		return getByName( name );
}



sal_Bool SAL_CALL
TVChildTarget::hasByHierarchicalName( const rtl::OUString& aName )
	throw( RuntimeException )
{
	sal_Int32 idx;
	rtl::OUString name( aName );
	
   	if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 )
	{
		rtl::OUString num( name.getStr()+2,idx-4 );
		sal_Int32 pref = num.toInt32() - 1;		
		if( pref < 0 || Elements.size() <= sal_uInt32( pref ) )
			return false;
		
		return Elements[pref]->hasByHierarchicalName( name.copy( 1 + idx ) );
	}
	else
		return hasByName( name );
}






ConfigData TVChildTarget::init( const Reference< XMultiServiceFactory >& xSMgr )
{
	ConfigData configData;
	Reference< XMultiServiceFactory >  sProvider( getConfiguration(xSMgr) );
	
	/**********************************************************************/
	/*                       reading Office.Common                        */
	/**********************************************************************/
	
	Reference< XHierarchicalNameAccess > xHierAccess( getHierAccess( sProvider,
																	 "org.openoffice.Office.Common" ) );
	rtl::OUString system( getKey( xHierAccess,"Help/System" ) );	
	sal_Bool showBasic( getBooleanKey(xHierAccess,"Help/ShowBasic") );
	rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) );
	if( ! instPath.getLength() )
	  // try to determine path from default
	  instPath = rtl::OUString::createFromAscii( "$(instpath)/help" );
	
	// replace anything like $(instpath);
	subst( xSMgr,instPath );

	/**********************************************************************/
	/*                       reading setup                                */
	/**********************************************************************/

	xHierAccess = getHierAccess( sProvider,
								 "org.openoffice.Setup" );
	
	rtl::OUString productName( getKey(  xHierAccess,"Product/ooName" ) );
    rtl::OUString setupversion( getKey( xHierAccess,"Product/ooSetupVersion" ) );
    rtl::OUString setupextension;

    try
    {
        uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
	          xSMgr ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), uno::UNO_QUERY_THROW);

        uno::Sequence < uno::Any > lParams(1);
        beans::PropertyValue                       aParam ;
        aParam.Name    = ::rtl::OUString::createFromAscii("nodepath");
        aParam.Value <<= ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Product");
        lParams[0] = uno::makeAny(aParam);

        // open it
        uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments(
                    ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"),
                    lParams) );

        uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY);
        uno::Any aRet = xDirectAccess->getByName(::rtl::OUString::createFromAscii("ooSetupExtension"));

        aRet >>= setupextension;
    }
    catch ( uno::Exception& )
    {
    }

	rtl::OUString productVersion( setupversion + 
								  rtl::OUString::createFromAscii( " " ) +
								  setupextension );
	rtl::OUString locale( getKey( xHierAccess,"L10N/ooLocale" ) );

	
	// Determine fileurl from url and locale
	rtl::OUString url;
	osl::FileBase::RC errFile = osl::FileBase::getFileURLFromSystemPath( instPath,url );
	if( errFile != osl::FileBase::E_None ) return configData;
	if( url.lastIndexOf( sal_Unicode( '/' ) ) != url.getLength() - 1 )
		url += rtl::OUString::createFromAscii( "/" );
	rtl::OUString ret;
	sal_Int32 idx;
	osl::DirectoryItem aDirItem;
	if( osl::FileBase::E_None == osl::DirectoryItem::get( url + locale,aDirItem ) )
		ret = locale;
	else if( ( ( idx = locale.indexOf( '-' ) ) != -1 ||
			   ( idx = locale.indexOf( '_' ) ) != -1 ) &&
			 osl::FileBase::E_None == osl::DirectoryItem::get( url + locale.copy( 0,idx ),
															   aDirItem ) )
		ret = locale.copy( 0,idx );
    else
        {
        locale = rtl::OUString::createFromAscii( "en-US" );
        ret = rtl::OUString::createFromAscii("en");
        }
	url = url + ret;
	
	// first of all, try do determine whether there are any *.tree files present

	// Start with extensions to set them at the end of the list
	TreeFileIterator aTreeIt( locale );
	rtl::OUString aTreeFile;
	sal_Int32 nFileSize;
	while( (aTreeFile = aTreeIt.nextTreeFile( nFileSize ) ).getLength() > 0 )
	{
		configData.vFileLen.push_back( nFileSize );
		configData.vFileURL.push_back( aTreeFile );
	}

	osl::Directory aDirectory( url );
	osl::FileStatus aFileStatus( FileStatusMask_FileName | FileStatusMask_FileSize | FileStatusMask_FileURL );
	if( osl::Directory::E_None == aDirectory.open() )
	{
		int idx_ = 0;
		rtl::OUString aFileUrl, aFileName;
		while( aDirectory.getNextItem( aDirItem ) == osl::FileBase::E_None &&
			   aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None &&
			   aFileStatus.isValid( FileStatusMask_FileURL ) && 
			   aFileStatus.isValid( FileStatusMask_FileName ) )
		  {
			aFileUrl = aFileStatus.getFileURL();
			aFileName = aFileStatus.getFileName();
			idx_ = aFileName.lastIndexOf( sal_Unicode( '.' ) );
			if( idx_ == -1 )
			  continue;
			
			const sal_Unicode* str = aFileName.getStr();
			
			if( aFileName.getLength() == idx_ + 5                   && 
				( str[idx_ + 1] == 't' || str[idx_ + 1] == 'T' )    && 
				( str[idx_ + 2] == 'r' || str[idx_ + 2] == 'R' )    &&
				( str[idx_ + 3] == 'e' || str[idx_ + 3] == 'E' )    &&
				( str[idx_ + 4] == 'e' || str[idx_ + 4] == 'E' ) )
			  {
				OSL_ENSURE( aFileStatus.isValid( FileStatusMask_FileSize ),
                            "invalid file size" );			
				
				rtl::OUString baseName = aFileName.copy(0,idx_).toAsciiLowerCase();
				if(! showBasic && baseName.compareToAscii("sbasic") == 0 )
				  continue;
				
				configData.vFileLen.push_back( aFileStatus.getFileSize() );
				configData.vFileURL.push_back( aFileUrl );
			  }
		  }
		aDirectory.close();
	}

	configData.m_vAdd[0] = 12;
	configData.m_vAdd[1] = 15;
	configData.m_vAdd[2] = 11;
	configData.m_vAdd[3] = 14;
	configData.m_vAdd[4] = 12;
	configData.m_vReplacement[0] = productName;
	configData.m_vReplacement[1] = productVersion;
	// m_vReplacement[2...4] (vendorName/-Version/-Short) are empty strings

   	configData.system = system;
	configData.locale = locale;		
	configData.appendix =
		rtl::OUString::createFromAscii( "?Language=" ) +
		configData.locale +
		rtl::OUString::createFromAscii( "&System=" ) +
		configData.system +
        rtl::OUString::createFromAscii( "&UseDB=no" ) ;
	
	return configData;
}









Reference< XMultiServiceFactory >
TVChildTarget::getConfiguration(const Reference< XMultiServiceFactory >& m_xSMgr) const
{
	Reference< XMultiServiceFactory > sProvider;
	if( m_xSMgr.is() )
	{
		try
		{
			rtl::OUString sProviderService =
				rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" );
			sProvider =
				Reference< XMultiServiceFactory >(
					m_xSMgr->createInstance( sProviderService ),
					UNO_QUERY );
		}
		catch( const com::sun::star::uno::Exception& )
		{
			OSL_ENSURE( sProvider.is(),"cant instantiate configuration" );
		}
	}
	
	return sProvider;
}



Reference< XHierarchicalNameAccess >
TVChildTarget::getHierAccess( const Reference< XMultiServiceFactory >& sProvider,
							  const char* file ) const
{
	Reference< XHierarchicalNameAccess > xHierAccess;
	
	if( sProvider.is() )
	{
		Sequence< Any > seq(1);
		rtl::OUString sReaderService =
			rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" );
		
		seq[0] <<= rtl::OUString::createFromAscii( file );		
		
		try
		{
			xHierAccess = 
				Reference< XHierarchicalNameAccess >
				( sProvider->createInstanceWithArguments( sReaderService,seq ),
				  UNO_QUERY );
		}
		catch( const com::sun::star::uno::Exception& )
		{
		}
	}
	
	return xHierAccess;
}



rtl::OUString
TVChildTarget::getKey( const Reference< XHierarchicalNameAccess >& xHierAccess,
					   const char* key ) const
{
    rtl::OUString instPath;
	if( xHierAccess.is() )
	{
		Any aAny;
		try
		{
			aAny =
				xHierAccess->getByHierarchicalName( rtl::OUString::createFromAscii( key ) );
		}
		catch( const com::sun::star::container::NoSuchElementException& )
		{
		}
		aAny >>= instPath;
	}
	return instPath;
}


sal_Bool
TVChildTarget::getBooleanKey(const Reference<
							 XHierarchicalNameAccess >& xHierAccess,
							 const char* key) const
{
  sal_Bool ret = sal_False;
  if( xHierAccess.is() )
	{
	  Any aAny;
	  try
		{
		  aAny =
			xHierAccess->getByHierarchicalName(
											   rtl::OUString::createFromAscii(key));
		}
	  catch( const com::sun::star::container::NoSuchElementException& )
		{
		}
	  aAny >>= ret;
	}
  return ret;
}


void TVChildTarget::subst( const Reference< XMultiServiceFactory >& m_xSMgr,
						   rtl::OUString& instpath ) const
{
	Reference< XConfigManager >  xCfgMgr;
	if( m_xSMgr.is() )
	{
		try
		{
			xCfgMgr =
				Reference< XConfigManager >(
					m_xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.config.SpecialConfigManager" ) ),
					UNO_QUERY );
		}
		catch( const com::sun::star::uno::Exception& )
		{
			OSL_ENSURE( xCfgMgr.is()," cant instantiate the special config manager " );
		}
    }
	
	OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" );
	
	if( xCfgMgr.is() )
        instpath = xCfgMgr->substituteVariables( instpath );
}


//===================================================================
// class ExtensionIteratorBase

static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) );
static rtl::OUString aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) );
static rtl::OUString aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) );

ExtensionIteratorBase::ExtensionIteratorBase( const rtl::OUString& aLanguage )
		: m_eState( USER_EXTENSIONS )
		, m_aLanguage( aLanguage )
{
	init();
}

void ExtensionIteratorBase::init()
{
	Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
	Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
	OSL_ASSERT( xProps.is() );
	if (xProps.is())
	{
		xProps->getPropertyValue(
			::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext;
		OSL_ASSERT( m_xContext.is() );
	}
	if( !m_xContext.is() )
	{
		throw RuntimeException(
			::rtl::OUString::createFromAscii( "ExtensionIteratorBase::init(), no XComponentContext" ),
			Reference< XInterface >() );
	}

	Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
	m_xSFA = Reference< ucb::XSimpleFileAccess >( 
		xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
		m_xContext ), UNO_QUERY_THROW );

	m_bUserPackagesLoaded = false;
	m_bSharedPackagesLoaded = false;
    m_bBundledPackagesLoaded = false;
	m_iUserPackage = 0;
	m_iSharedPackage = 0;
    m_iBundledPackage = 0;
}

Reference< deployment::XPackage > ExtensionIteratorBase::implGetHelpPackageFromPackage
	( Reference< deployment::XPackage > xPackage, Reference< deployment::XPackage >& o_xParentPackageBundle )
{
	o_xParentPackageBundle.clear();

	Reference< deployment::XPackage > xHelpPackage;
	if( !xPackage.is() )
		return xHelpPackage;

	// Check if parent package is registered
    beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered
		( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
	bool bRegistered = false;
    if( option.IsPresent )
    {
        beans::Ambiguous<sal_Bool> const & reg = option.Value;
        if( !reg.IsAmbiguous && reg.Value )
			bRegistered = true;
    }
	if( !bRegistered )
		return xHelpPackage;

	if( xPackage->isBundle() )
	{
		Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle
			( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
		sal_Int32 nPkgCount = aPkgSeq.getLength();
		const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray();
		for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg )
		{
			const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
			const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType();
			rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
			if( aMediaType.equals( aHelpMediaType ) )
			{
				xHelpPackage = xSubPkg;
				o_xParentPackageBundle = xPackage;
				break;
			}
		}
	}
	else
	{
		const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
		rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
		if( aMediaType.equals( aHelpMediaType ) )
			xHelpPackage = xPackage;
	}

	return xHelpPackage;
}

Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextUserHelpPackage
	( Reference< deployment::XPackage >& o_xParentPackageBundle )
{
	Reference< deployment::XPackage > xHelpPackage;

	if( !m_bUserPackagesLoaded )
	{
		Reference< XPackageManager > xUserManager =
			thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("user") );
		m_aUserPackagesSeq = xUserManager->getDeployedPackages
			( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );

		m_bUserPackagesLoaded = true;
	}

	if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
	{
		m_eState = SHARED_EXTENSIONS;		// Later: SHARED_MODULE
	}
	else
	{
		const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
		Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage++ ];
		VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" );
		xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
	}

	return xHelpPackage;
}

Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPackage
	( Reference< deployment::XPackage >& o_xParentPackageBundle )
{
	Reference< deployment::XPackage > xHelpPackage;

	if( !m_bSharedPackagesLoaded )
	{
		Reference< XPackageManager > xSharedManager =
			thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("shared") );
		m_aSharedPackagesSeq = xSharedManager->getDeployedPackages
			( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );

		m_bSharedPackagesLoaded = true;
	}

	if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
	{
		m_eState = BUNDLED_EXTENSIONS;
	}
	else
	{
		const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
		Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage++ ];
		VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" );
		xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
	}

	return xHelpPackage;
}

Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextBundledHelpPackage
	( Reference< deployment::XPackage >& o_xParentPackageBundle )
{
	Reference< deployment::XPackage > xHelpPackage;

	if( !m_bBundledPackagesLoaded )
	{
		Reference< XPackageManager > xBundledManager =
			thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("bundled") );
		m_aBundledPackagesSeq = xBundledManager->getDeployedPackages
			( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );

		m_bBundledPackagesLoaded = true;
	}

	if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
	{
		m_eState = END_REACHED;
	}
	else
	{
		const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
		Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage++ ];
		VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextBundledHelpPackage(): Invalid package" );
		xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
	}

	return xHelpPackage;
}

inline bool isLetter( sal_Unicode c )
{
	bool bLetter = ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
	return bLetter;
}

void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv,
	com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage )
{
	rv.clear();
	rtl::OUString aExtensionPath = xPackage->getURL();
	Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true );

	const rtl::OUString* pSeq = aEntrySeq.getConstArray();
    sal_Int32 nCount = aEntrySeq.getLength();
	for( sal_Int32 i = 0 ; i < nCount ; ++i )
	{
		rtl::OUString aEntry = pSeq[i];
		if( m_xSFA->isFolder( aEntry ) )
		{
			sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' );
			if( nLastSlash != -1 )
			{
				rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 );

				// Check language sceme
				int nLen = aPureEntry.getLength();
				const sal_Unicode* pc = aPureEntry.getStr();
				bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) );
				bool bIsLanguage = bStartCanBeLanguage &&
					( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) );
				if( bIsLanguage )
					rv.push_back( aPureEntry );
			}
		}
	}
}


//===================================================================
// class TreeFileIterator

rtl::OUString TreeFileIterator::nextTreeFile( sal_Int32& rnFileSize )
{
	rtl::OUString aRetFile;

	while( !aRetFile.getLength() && m_eState != END_REACHED )
	{
		switch( m_eState )
		{
			case USER_EXTENSIONS:
			{
				Reference< deployment::XPackage > xParentPackageBundle;
				Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle );
				if( !xHelpPackage.is() )
					break;

				aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage );
				break;
			}

			case SHARED_EXTENSIONS:
			{
				Reference< deployment::XPackage > xParentPackageBundle;
				Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle );
				if( !xHelpPackage.is() )
					break;

				aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage );
				break;
			}
			case BUNDLED_EXTENSIONS:
			{
				Reference< deployment::XPackage > xParentPackageBundle;
				Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( xParentPackageBundle );
				if( !xHelpPackage.is() )
					break;

				aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage );
				break;
			}

        case END_REACHED:
				VOS_ENSURE( false, "DataBaseIterator::nextTreeFile(): Invalid case END_REACHED" );
				break;
		}
	}

	return aRetFile;
}

rtl::OUString TreeFileIterator::expandURL( const rtl::OUString& aURL )
{
	static Reference< util::XMacroExpander > xMacroExpander;
	static Reference< uri::XUriReferenceFactory > xFac;

	osl::MutexGuard aGuard( m_aMutex );

	if( !xMacroExpander.is() || !xFac.is() )
	{
		Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );

		xFac = Reference< uri::XUriReferenceFactory >(
			xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii(
			"com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY );
		if( !xFac.is() )
		{
			throw RuntimeException(
				::rtl::OUString::createFromAscii( "Databases::expand(), could not instatiate UriReferenceFactory." ),
				Reference< XInterface >() );
		}

		xMacroExpander = Reference< util::XMacroExpander >(
			m_xContext->getValueByName(
			::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ),
			UNO_QUERY_THROW );
 	}

	rtl::OUString aRetURL = aURL;
	if( xMacroExpander.is() )
	{
		Reference< uri::XUriReference > uriRef;
		for (;;)
		{
			uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY );
			if ( uriRef.is() )
			{
				Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY );
				if( !sxUri.is() )
					break;

				aRetURL = sxUri->expand( xMacroExpander );
			}
		}
 	}
	return aRetURL;
}

rtl::OUString TreeFileIterator::implGetTreeFileFromPackage
	( sal_Int32& rnFileSize, Reference< deployment::XPackage > xPackage )
{
	rtl::OUString aRetFile;
	rtl::OUString aLanguage = m_aLanguage;
	for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass )
	{
		rtl::OUStringBuffer aStrBuf;
		aStrBuf.append( xPackage->getURL() );
		aStrBuf.append( aSlash );
		aStrBuf.append( aLanguage );
		aStrBuf.append( aSlash );
		aStrBuf.append( aHelpFilesBaseName );
		aStrBuf.appendAscii( ".tree" );

		aRetFile = expandURL( aStrBuf.makeStringAndClear() );
		if( iPass == 0 )
		{
			if( m_xSFA->exists( aRetFile ) )
				break;

			::std::vector< ::rtl::OUString > av;
			implGetLanguageVectorFromPackage( av, xPackage );
			::std::vector< ::rtl::OUString >::const_iterator pFound = av.end();
			try
			{
				pFound = ::comphelper::Locale::getFallback( av, m_aLanguage );
			}
			catch( ::comphelper::Locale::MalFormedLocaleException& )
			{}
			if( pFound != av.end() )
				aLanguage = *pFound;
		}
	}

	rnFileSize = 0;
	if( m_xSFA->exists( aRetFile ) )
		rnFileSize = m_xSFA->getSize( aRetFile );
	else
		aRetFile = rtl::OUString();

	return aRetFile;
}



