/*************************************************************************
 *
 *	$RCSfile: resmgr.hxx,v $
 *
 *	$Revision: 1.3 $
 *
 *	last change: $Author: th $ $Date: 2000/12/05 19:19:20 $
 *
 *	The Contents of this file are made available subject to the terms of
 *	either of the following licenses
 *
 *		   - GNU Lesser General Public License Version 2.1
 *		   - Sun Industry Standards Source License Version 1.1
 *
 *	Sun Microsystems Inc., October, 2000
 *
 *	GNU Lesser General Public License Version 2.1
 *	=============================================
 *	Copyright 2000 by Sun Microsystems, Inc.
 *	901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License version 2.1, as published by the Free Software Foundation.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *	MA	02111-1307	USA
 *
 *
 *	Sun Industry Standards Source License Version 1.1
 *	=================================================
 *	The contents of this file are subject to the Sun Industry Standards
 *	Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *	Software provided under this License is provided on an "AS IS" basis,
 *	WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *	WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *	MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *	See the License for the specific provisions governing your rights and
 *	obligations concerning the Software.
 *
 *	The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *	Copyright: 2000 by Sun Microsystems, Inc.
 *
 *	All Rights Reserved.
 *
 *	Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _TOOLS_RESMGR_HXX
#define _TOOLS_RESMGR_HXX

#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif
#ifndef _REF_HXX
#include <tools/ref.hxx>
#endif

#ifndef _TOOLS_RESID_HXX
#include <tools/resid.hxx>
#endif

#define CREATEVERSIONRESMGR_NAME( Name )   #Name MAKE_NUMSTR( SUPD )
#define CREATEVERSIONRESMGR( Name ) 	   ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( Name ) )

class SvStream;
class List;
class InternalResMgr;
class ResMgr;
struct ImplSVResourceData
{
	List*				pInternalResMgrList;
	ResMgr* 			pAppResMgr;
	ImplSVResourceData()
		: pInternalResMgrList( NULL )
		, pAppResMgr( NULL )
		{}
};

// -----------------
// - RSHEADER_TYPE -
// -----------------

// Definition der Struktur, aus denen die Resource aufgebaut ist
struct RSHEADER_TYPE
{
private:
	USHORT					nId;		// Identifier der Resource
	RESOURCE_TYPE			nRT;		// Resource Typ
	USHORT					nGlobOff;	// Globaler Offset
	USHORT					nLocalOff;	// Lokaler Offset

public:
	inline USHORT		   GetId(); 	   // Identifier der Resource
	inline RESOURCE_TYPE   GetRT(); 	   // Resource Typ
	inline USHORT		   GetGlobOff();   // Globaler Offset
	inline USHORT		   GetLocalOff();  // Lokaler Offset
};

// ----------
// - ResMgr -
// ----------

struct ImpContent;
class InternalResMgr : public SvRefBase
{
	friend class ResMgr;
	friend class SimpleResMgr;

	ImpContent *			pContent;
	UINT32					nOffCorrection;
	BYTE *					pStringBlock;
	SvStream *				pStm;
	BOOL					bEqual2Content;
	UINT32					nEntries;
	UniString				aFileName;
	UniString				aShortFileName;
	class Table *			pResUseDump;

							InternalResMgr();
							~InternalResMgr();
	BOOL					Create();

	static void 			GetResMgrPath( InternalResMgr* pThis,
										   const UniString& rFileName,
										   const UniString* pAppName = NULL,
										   const UniString* pResPath = NULL );
	static InternalResMgr*	Create( const UniString& rName,
									const UniString* pAppName = NULL,
									const UniString* pResPath = NULL );
	static InternalResMgr*	GetInternalResMgr( const String & rFileName, const String * pAppName = NULL, const String * pResPath = NULL );
	static void 			FreeInternalResMgr( InternalResMgr* pFreeInternalResMgr );

	BOOL					IsGlobalAvailable( RESOURCE_TYPE nRT, USHORT nId ) const;
	void *					LoadGlobalRes( RESOURCE_TYPE nRT, USHORT nId,
										   void **pResHandle );
public:
	void					FreeGlobalRes( void *, void * );

	SvStream *				GetBitmapStream( USHORT nResId );
};

typedef void (*ResHookProc)( UniString& rStr );

// ----------
// - ResMgr -
// ----------

// Initialisierung
#define RC_NOTYPE				0x0
// Globale Resource
#define RC_GLOBAL				0x1
#define RC_AUTORELEASE			0x2

class Resource;
class ResMgr;
struct ImpRCStack
{
	// pResource und pClassRes gleich Null, dann wurde Resource nicht
	// gelagen
	RSHEADER_TYPE * pResource;		// pointer to resource
	void		  * pClassRes;		// pointer to class specified init data
	short			Flags;			// resource status
	void *			aResHandle; 	// Platz fuer Resource-Identifier
	const Resource* pResObj;		// Zeiger des Resource Object
	USHORT			nId;			// Resource Id fuer Fehlermeldung
	ResMgr *		pResMgr;		// Ressource-Manager zur Ressource

	void			Clear();
	void			Init( ResMgr * pMgr, const Resource * pObj, USHORT nId );
};

#define MAX_RC_STACK	32

class ResMgr
{
// Wegen ImpRscBox, Icon, Bitmap, Pointer, .... public
public:
	InternalResMgr* 	pImpRes;
	ImpRCStack			aStack[MAX_RC_STACK];	// Keller vom Resource Kontext
	short				nTopRes;				// top of the resource stack

	static void 		DestroyAllResMgr();  // Wird gerufen, wenn App beendet wird
	void				Init( const UniString& rFileName );

public:
						// Resource-Datei-Name
						ResMgr( InternalResMgr * pImp );
						ResMgr( const UniString* pFileName = NULL );	// nur in VCL
						ResMgr( const UniString& rFileName,
								const UniString* pAppName = NULL,
								const UniString* pResPath = NULL );
						~ResMgr();

						// Sprachabhaengige Ressource Library
	static const sal_Char*	GetLang( USHORT nPrio = 0 ); // nur in VCL
#ifdef WTC
	static const sal_Char*	GetLang( LanguageType& eLanguage, USHORT nPrio );
#else
	static const sal_Char*	GetLang( LanguageType& eLanguage, USHORT nPrio = 0 );
#endif
	static ResMgr*		CreateResMgr( const sal_Char* pPrefixName,
									  LanguageType eLanguage,
									  const UniString* pAppName,
									  const UniString* pResPath );
	static ResMgr*		CreateResMgr( const sal_Char* pPrefixName,
									  LanguageType eLanguage = LANGUAGE_DONTKNOW ); // nur in VCL
	static ResMgr*		SearchCreateResMgr( const sal_Char* pPrefixName,
											LanguageType& rLanguageReturn );

	// Testet ob Resource noch da ist
	void				TestStack( const Resource * );
	const ImpRCStack *	StackTop( USHORT nOff = 0 ) const
						{
							// nTopRes == 0 ist leer !
							return (((short)nOff >= nTopRes) ? NULL : &aStack[nTopRes-nOff]);
						}

	// ist Resource verfuegbar
	BOOL				IsAvailable( const ResId& rId,
									 const Resource* = NULL) const;

	// Resource suchen und laden
	BOOL				GetResource( const ResId& rId, const Resource * = NULL );
	static void *		GetResourceSkipHeader( const ResId& rResId, ResMgr ** ppResMgr );
	// Kontext freigeben
	void				PopContext( const Resource* = NULL );

	// Resourcezeiger erhoehen
	void*				Increment( USHORT nSize );

	// Groesse ein Objektes in der Resource
	static USHORT		GetObjSize( RSHEADER_TYPE* pHT )
							{ return( pHT->GetGlobOff() ); }

	// Liefert einen String aus der Resource
	static USHORT		GetString( UniString& rStr, const BYTE* pStr );

	// Groesse eines Strings in der Resource
	static USHORT		GetStringSize( USHORT nLen )
							{ nLen++; return (nLen + nLen%2); }
	static USHORT		GetStringSize( const BYTE* pStr );

	// Gibt einen long zurueck
	static INT32		GetLong( void * pLong );
	// return a short
	static INT16		GetShort( void * pShort );

	// Gibt einen Zeiger auf die Resource zurueck
	void *				GetClass()
							{ return( aStack[nTopRes].pClassRes ); }

	RSHEADER_TYPE * 	CreateBlock( const ResId & rId );

	// Gibt die verbleibende Groesse zurueck
	USHORT				GetRemainSize();

	const UniString&	GetFileName() const { return pImpRes->aFileName; }

	INT16				ReadShort();
	INT32				ReadLong();
	UniString			ReadString();

	static void 		SetReadStringHook( ResHookProc pProc );
	static ResHookProc	GetReadStringHook();
};

inline USHORT RSHEADER_TYPE::GetId()
{
	return (USHORT)ResMgr::GetShort( &nId );
}
inline RESOURCE_TYPE RSHEADER_TYPE::GetRT()
{
	return (RESOURCE_TYPE)ResMgr::GetShort( &nRT );
}
inline USHORT RSHEADER_TYPE::GetGlobOff()
{
	return (USHORT)ResMgr::GetShort( &nGlobOff );
}
inline USHORT RSHEADER_TYPE::GetLocalOff()
{
	return (USHORT)ResMgr::GetShort( &nLocalOff );
}

#endif // _SV_RESMGR_HXX
