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



#ifndef _DATABASES_HXX_
#define _DATABASES_HXX_

#ifndef INCLUDED_STL_SET
#include <set>
#define INCLUDED_STL_SET
#endif
#ifndef INCLUDED_STL_VECTOR
#include <vector>
#define INCLUDED_STL_VECTOR
#endif
#include <hash_map>
#include <hash_set>
#include <osl/mutex.hxx>
#include <rtl/ustring.hxx>
#include <rtl/string.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/ucb/XContent.hpp>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/i18n/XCollator.hpp>
#include <com/sun/star/deployment/XPackage.hpp>
#include "com/sun/star/ucb/XSimpleFileAccess.hpp" 

// Forward declaration


namespace helpdatafileproxy {
    
    class Hdf;
    
}


namespace chelp {

    
	class Databases;
	class URLParameter;
	
	class StaticModuleInformation
	{
	private:
		
		rtl::OUString m_aStartId;
		rtl::OUString m_aProgramSwitch;
		rtl::OUString m_aTitle;
		rtl::OUString m_aHeading;
		rtl::OUString m_aFulltext;
		int m_nOrder;
        
		
	public:

		StaticModuleInformation( rtl::OUString aTitle,
								 rtl::OUString aStartId,
								 rtl::OUString aProgramSwitch,
								 rtl::OUString aHeading,
								 rtl::OUString aFulltext,
                                 rtl::OUString aOrder )
			: m_aStartId( aStartId ),
			  m_aProgramSwitch( aProgramSwitch ),
			  m_aTitle( aTitle ),
			  m_aHeading( aHeading ),
			  m_aFulltext( aFulltext ),
              m_nOrder( aOrder.toInt32() )
		{
		}
        
		~StaticModuleInformation() { }

		rtl::OUString get_title()     { return m_aTitle; }
		rtl::OUString get_id()        { return m_aStartId; }
		rtl::OUString get_program()   { return m_aProgramSwitch; }
		rtl::OUString get_heading()   { return m_aHeading; }
		rtl::OUString get_fulltext()  { return m_aFulltext; }
        int get_order() { return m_nOrder; }
	};  // end class StaticModuleInformation
	
	

	class KeywordInfo
	{
	public:
		
		class KeywordElement
		{
            friend struct KeywordElementComparator;
            friend class KeywordInfo;
			
		public:
			
			KeywordElement( Databases* pDatabases,
							helpdatafileproxy::Hdf* pHdf,
							rtl::OUString& key,
							rtl::OUString& ids );
			
		private:			
            
			rtl::OUString key;
			com::sun::star::uno::Sequence< rtl::OUString > listId;
			com::sun::star::uno::Sequence< rtl::OUString > listAnchor;
			com::sun::star::uno::Sequence< rtl::OUString > listTitle;

			void init( Databases *pDatabases,helpdatafileproxy::Hdf* pHdf,const rtl::OUString& ids );
		};

		
		KeywordInfo( const std::vector< KeywordElement >& aVector );
        
        ~KeywordInfo() { };
		
		com::sun::star::uno::Sequence< rtl::OUString >&
		getKeywordList() { return listKey; }
		
		com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > >&
		getIdList() { return listId; }
		
		com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > >&
		getAnchorList() { return listAnchor; }
		
		com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > >&
		getTitleList() { return listTitle; }
		
	private:
		
		com::sun::star::uno::Sequence< rtl::OUString > listKey;
		com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > > listId,listAnchor,listTitle;
	};  // end class KeywordInfo


	
	class Databases
	{
	public:

		struct eq
		{
			bool operator()( const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
			{
				return rKey1.compareTo( rKey2 ) == 0;
			}
		};
		
		struct ha
		{
			size_t operator()( const rtl::OUString& rName ) const
			{
				return rName.hashCode();
			}
		};
		
		
		/**
		 *  Input is the installdirectory in system dependent notation
		 */
	  
		Databases( sal_Bool showBasic,
				 const rtl::OUString& instPath,
				 const com::sun::star::uno::Sequence< rtl::OUString >& imagesZipPaths,
				 const rtl::OUString& productName,
				 const rtl::OUString& productVersion,
				 const rtl::OUString& styleSheet,
				 com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext );
	  
		~Databases();

        rtl::OString getImagesZipFileURL();
        
		rtl::OUString getInstallPathAsSystemPath();
		
		rtl::OUString getInstallPathAsURL();

		const std::vector< rtl::OUString >& getModuleList( const rtl::OUString& Language );
		
		StaticModuleInformation* getStaticInformationForModule( const rtl::OUString& Module,
																const rtl::OUString& Language );
		
		bool checkModuleMatchForExtension( const rtl::OUString& Database, const rtl::OUString& doclist );
		KeywordInfo* getKeyword( const rtl::OUString& Module,
								 const rtl::OUString& Language );
		
		helpdatafileproxy::Hdf* getHelpDataFile( const rtl::OUString& Module,
						 const rtl::OUString& Language, bool helpText = false,
						 const rtl::OUString* pExtensionPath = NULL );


		/**
		 *  The following method returns the Collator for the given language-country combination
		 */
		
		com::sun::star::uno::Reference< com::sun::star::i18n::XCollator >
		getCollator( const rtl::OUString& Language,
					 const rtl::OUString& System );   // System not used by current implementation
		//                                            // of XCollator
		
		/**
		 *  Returns a copy of the popupfile
		 */
		
		void popupDocument( URLParameter* urlPar,char **buffer,int *byteCount );


		/**
		 *  Returns the cascading stlye sheet used to format the HTML-output.
		 *  First try is language directory, second try is main installation directory.
		 */
		
		void cascadingStylesheet( const rtl::OUString& Language,
								  char** buffer,
								  int* byteCount );
		

		/**
		 *  Changes the the stylesheet for further reads.
		 */
		
		void changeCSS(const rtl::OUString& newStyleSheet);


		/**
		 *  Returns the active help text for the given module, language and id.
		 */
		
		void setActiveText( const rtl::OUString& Module,
							const rtl::OUString& Language,
							const rtl::OUString& Id,
							char** buffer,
							int* byteCount );
		
		/**
		 *  Has the purpose of forcing the the jarfile to stay open
		 */
		
		com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess >
		jarFile( const rtl::OUString& jar,
				 const rtl::OUString& Language );
		
		com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess >
		findJarFileForPath( const rtl::OUString& jar, const rtl::OUString& Language,
			const rtl::OUString& path, rtl::OUString* o_pExtensionPath = NULL,
            rtl::OUString* o_pExtensionRegistryPath = NULL );
		
		/**
		 *  Maps a given language-locale combination to language.
		 */
		
		rtl::OUString processLang( const rtl::OUString& Language );

		
		/**
		 *  Maps a given language-locale combination to locale.
		 *  The returned string maybe empty
		 */
		
		rtl::OUString country( const rtl::OUString& Language );
		
		
		void replaceName( rtl::OUString& oustring ) const;

		rtl::OUString getProductName() const { return m_vReplacement[0]; }
		rtl::OUString getProductVersion() const { return m_vReplacement[1]; }
		
		rtl::OUString expandURL( const rtl::OUString& aURL );

		static rtl::OUString expandURL( const rtl::OUString& aURL,
			com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext );

	private:
		
		osl::Mutex                                                                     m_aMutex;
		com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >       m_xContext;
		com::sun::star::uno::Reference< com::sun::star::lang::XMultiComponentFactory > m_xSMgr;
		com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess >	   m_xSFA;

	    sal_Bool m_bShowBasic;
		int    m_nErrorDocLength;
		char*  m_pErrorDoc;

		int    m_nCustomCSSDocLength;
		char*  m_pCustomCSSDoc;
		rtl::OUString m_aCSS;
        
#define PRODUCTNAME    0
#define PRODUCTVERSION 1
#define VENDORNAME     2
#define VENDORVERSION  3
#define VENDORSHORT    4
#define NEWPRODUCTNAME    5
#define NEWPRODUCTVERSION 6
        
		int                    m_vAdd[7];
		rtl::OUString          m_vReplacement[7];
		rtl::OUString          newProdName,newProdVersion,
            prodName,prodVersion,vendName,vendVersion,vendShort;
		
		rtl::OUString          m_aInstallDirectory;                // Installation directory
		com::sun::star::uno::Sequence< rtl::OUString > m_aImagesZipPaths;
        rtl::OString           m_aImagesZipFileURL;
		sal_Int16              m_nSymbolsStyle;
		rtl::OUString          m_aInstallDirectoryWithoutEncoding; // a work around for a Sablot bug.
		rtl::OUString          m_aInstallDirectoryAsSystemPath;    // Installation directory
		
		std::vector< rtl::OUString >	m_avModules;
		
		typedef std::hash_map< rtl::OUString,helpdatafileproxy::Hdf*,ha,eq >   DatabasesTable;
		DatabasesTable m_aDatabases;         // Language and module dependent databases
		
		typedef  std::hash_map< rtl::OUString,rtl::OUString,ha,eq > LangSetTable; 
		LangSetTable m_aLangSet;   // Mapping to of lang-country to lang
		
		typedef std::hash_map< rtl::OUString,StaticModuleInformation*,ha,eq > ModInfoTable;
		ModInfoTable m_aModInfo;   // Module information
		
		typedef std::hash_map< rtl::OUString,KeywordInfo*,ha,eq > KeywordInfoTable;
		KeywordInfoTable m_aKeywordInfo;   // Module information

		typedef
		std::hash_map<
		rtl::OUString,
			 ::com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess >,
			ha,
			eq >         ZipFileTable;
		ZipFileTable m_aZipFileTable;   // No closing of an once opened jarfile

		typedef
		std::hash_map<
		rtl::OUString,
			 ::com::sun::star::uno::Reference< com::sun::star::i18n::XCollator >,
			ha,
			eq >      CollatorTable;
		CollatorTable    m_aCollatorTable;


		struct ostring_eq
		{
			bool operator()( const rtl::OString& rKey1, const rtl::OString& rKey2 ) const
			{
				return rKey1.compareTo( rKey2 ) == 0;
			}
		};
		
		struct ostring_ha
		{
			size_t operator()( const rtl::OString& rName ) const
			{
				return rName.hashCode();
			}
		};

		typedef
		std::hash_set<
			rtl::OString,
			ostring_ha,
			ostring_eq >      EmptyActiveTextSet;
		EmptyActiveTextSet	m_aEmptyActiveTextSet;
		
		
		// methods 
		
		void setInstallPath( const rtl::OUString& aInstallDirectory );
		
	}; // end class Databases


	//===================================================================
	enum IteratorState
	{
		INITIAL_MODULE,
		//SHARED_MODULE,		// Later, avoids redundancies in help compiling
		USER_EXTENSIONS,
		SHARED_EXTENSIONS,
        BUNDLED_EXTENSIONS,
		END_REACHED
	};

	// Hashtable to cache extension help status
	typedef std::hash_map
	<
		::rtl::OUString,
		bool,
		Databases::ha,
		Databases::eq
	>
	ExtensionHelpExistanceMap;


	class ExtensionIteratorBase
	{
		static ExtensionHelpExistanceMap	aHelpExistanceMap;

	public:
		ExtensionIteratorBase( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, 
			Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage );
		ExtensionIteratorBase( Databases& rDatabases, const rtl::OUString& aInitialModule, 
			const rtl::OUString& aLanguage );
		void init( void );

	private:
		com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetHelpPackageFromPackage
			( const com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage,
			  com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle );

	protected:
		com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextUserHelpPackage
			( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle );
		com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextSharedHelpPackage
			( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle );
        com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextBundledHelpPackage
        ( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle );
		rtl::OUString implGetFileFromPackage( const rtl::OUString& rFileExtension,
			com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage );
		void implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv,
			com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage );

		com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >	m_xContext;
		com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess >	m_xSFA;
		Databases&																	m_rDatabases;

		IteratorState																m_eState;
		rtl::OUString																m_aExtensionPath;

		rtl::OUString																m_aInitialModule;
		rtl::OUString																m_aLanguage;

		com::sun::star::uno::Sequence< com::sun::star::uno::Reference
			< com::sun::star::deployment::XPackage > >								m_aUserPackagesSeq;
		bool																		m_bUserPackagesLoaded;

		com::sun::star::uno::Sequence< com::sun::star::uno::Reference
			< com::sun::star::deployment::XPackage > >								m_aSharedPackagesSeq;
		bool																		m_bSharedPackagesLoaded;

        com::sun::star::uno::Sequence< com::sun::star::uno::Reference
            < com::sun::star::deployment::XPackage > >                              m_aBundledPackagesSeq;
		bool																		m_bBundledPackagesLoaded;

		int																			m_iUserPackage;
		int																			m_iSharedPackage;
        int																			m_iBundledPackage;

	}; // end class ExtensionIteratorBase

	
	//===================================================================
	class DataBaseIterator : public ExtensionIteratorBase
	{
	public:
		DataBaseIterator( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, 
			Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage, bool bHelpText )
				: ExtensionIteratorBase( xContext, rDatabases, aInitialModule, aLanguage )
				, m_bHelpText( bHelpText )
		{}
		DataBaseIterator( Databases& rDatabases, const rtl::OUString& aInitialModule, 
			const rtl::OUString& aLanguage, bool bHelpText )
				: ExtensionIteratorBase( rDatabases, aInitialModule, aLanguage )
				, m_bHelpText( bHelpText )
		{}

		helpdatafileproxy::Hdf* nextHdf( rtl::OUString* o_pExtensionPath = NULL, rtl::OUString* o_pExtensionRegistryPath = NULL );


	private:
		helpdatafileproxy::Hdf* implGetHdfFromPackage(
			com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage,
			rtl::OUString* o_pExtensionPath, rtl::OUString* o_pExtensionRegistryPath );

		bool																		m_bHelpText;

	}; // end class DataBaseIterator
	
	//===================================================================
	class KeyDataBaseFileIterator : public ExtensionIteratorBase
	{
	public:
		KeyDataBaseFileIterator( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, 
			Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage )
				: ExtensionIteratorBase( xContext, rDatabases, aInitialModule, aLanguage )
		{}
        //Returns a file URL
		rtl::OUString nextDbFile( bool& o_rbExtension );

	private:
		rtl::OUString implGetDbFileFromPackage(
			com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage );

	}; // end class KeyDataBaseFileIterator
	
	//===================================================================
	class JarFileIterator : public ExtensionIteratorBase
	{
	public:
		JarFileIterator( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, 
			Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage )
				: ExtensionIteratorBase( xContext, rDatabases, aInitialModule, aLanguage )
		{}

		com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess >
			nextJarFile( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle,
							rtl::OUString* o_pExtensionPath = NULL, rtl::OUString* o_pExtensionRegistryPath = NULL );

	private:
		com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess >
			implGetJarFromPackage(com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage,
				rtl::OUString* o_pExtensionPath = NULL, rtl::OUString* o_pExtensionRegistryPath = NULL );

	}; // end class JarFileIterator
	
	//===================================================================
	class IndexFolderIterator : public ExtensionIteratorBase
	{
	public:
		IndexFolderIterator( Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage )
			: ExtensionIteratorBase( rDatabases, aInitialModule, aLanguage )
		{}

		rtl::OUString nextIndexFolder( bool& o_rbExtension, bool& o_rbTemporary );
		void deleteTempIndexFolder( const rtl::OUString& aIndexFolder );

	private:
		rtl::OUString implGetIndexFolderFromPackage( bool& o_rbTemporary,
			com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage );

	}; // end class KeyDataBaseFileIterator
	
	//===================================================================

}      // end namespace chelp


#endif
