/*************************************************************************
 *
 *  $RCSfile: hashcont.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000/09/18 16:59:01 $
 *
 *  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 _SVTOOLS_HASHCONT_HXX
#define _SVTOOLS_HASHCONT_HXX 1

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef _CONTNR_HXX //autogen
#include <tools/contnr.hxx>
#endif

#ifndef _SVTOOLS_HASHTAB_HXX
#include <svtools/hashtab.hxx>
#endif

#ifndef _DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif

//==================================================================
//  SvStringMap:
//	Hash List fuer Strings
//==================================================================
class SvStringMap : private StringHashTab
{
public:
	SvStringMap(HASHTYPE nMaxSlots = 17)
				:StringHashTab(nMaxSlots){}

	void			Clear();
	ULONG			Count() const;
	void			SetAt(const String& _rKey, void* _pObj);
	void*			RemoveAt(const String& _rKey);
	void*			Remove(void* _pObj);

	String			GetKey(void* _pObj) const;
	void*			Lookup(const String& _rKey) const;

	void*			First()
					{return StringHashTab::Derefer(StringHashTab::First());}
	void*			Next()
					{return StringHashTab::Derefer(StringHashTab::Next());}
private:
	HASHSYMPTR		Find(void* _pObj) const;
};

#define DECL_SV_STRING_MAP( ClassName, Type ) 					\
class ClassName : private SvStringMap							\
{																\
public:															\
	SvStringMap::Clear;											\
	SvStringMap::Count;											\
																\
	ClassName(HASHTYPE _nMaxSlots = 17)							\
			:SvStringMap(_nMaxSlots){}							\
																\
	void			SetAt(const String& _rKey, Type _pObj)		\
		{SvStringMap::SetAt(_rKey, _pObj);}						\
	Type			Remove(Type _pObj)							\
		{return (Type)SvStringMap::Remove(_pObj);}				\
	Type			RemoveAt(const String& _rKey)				\
		{return (Type)SvStringMap::RemoveAt(_rKey);}			\
	String			GetKey(Type _pObj) const 					\
		{return SvStringMap::GetKey(_pObj);}					\
	Type			Lookup(const String& _rKey) const			\
		{return (Type)SvStringMap::Lookup(_rKey);}				\
	Type			First()										\
		{return (Type)SvStringMap::First();}					\
	Type			Next()										\
		{return (Type)SvStringMap::Next();}						\
};

//==================================================================
//  SvStringMapContainer:
//	Container, der Zugriff sowohl ueber einen Key (String) von Objecten
//	als auch ueber die Position erlaubt
//==================================================================
#ifdef MAC
class SvStringMapContainer : public Container
#else
class SvStringMapContainer : protected Container
#endif
{
private:
	SvStringMap	aMap;

public:
	SvStringMapContainer(HASHTYPE _nMaxSlots = 17, USHORT _nInitSize = 16, USHORT _nReSize = 16)
		:Container(1024, _nInitSize, _nReSize)
		,aMap(_nMaxSlots){}

	SvStringMapContainer(HASHTYPE _nMaxSlots, USHORT _nBlockSize, USHORT _nInitSize, USHORT _nReSize)
		:Container(_nBlockSize, _nInitSize, _nReSize)
		,aMap(_nMaxSlots){}

	Container::Count;
	Container::GetObject;
	Container::GetPos;

	inline void		Clear();
	void			InsertAt(const String& _rKey,
							 void* _pObj,
							 ULONG _nIndex = CONTAINER_APPEND);
	void*			ReplaceAt(const String& _rOldKey,
							  const String& _rKey,
							  void* _pObj);
	void*			ReplaceAt(ULONG _nOldIndex,
							  const String& _rKey,
							  void* _pObj);
	void*			Replace(void* _pOldObj,
							const String& _rKey,
							void* _pObj);

	String			GetKey(void* _pObj) const
						{return aMap.GetKey(_pObj);}

	void*			Lookup(const String& _rKey) const
						{return aMap.Lookup(_rKey);}

	void*			RemoveAt(const String& _rKey);
	void*			RemoveAt(ULONG _nIndex);
	void*			Remove(void* _pObj);
};

#define DECL_SV_STRING_MAP_CONTAINER( ClassName, Type )					\
class ClassName : private SvStringMapContainer							\
{																		\
public:																	\
	SvStringMapContainer::Clear;										\
	SvStringMapContainer::Count;										\
																		\
    ClassName( HASHTYPE _nMaxSlots = 17,								\
			   USHORT _nInitSize = 16,									\
               USHORT _nReSize = 16 ) 									\
		:SvStringMapContainer(_nMaxSlots, _nInitSize, _nReSize ) {}		\
																		\
	ClassName( HASHTYPE _nMaxSlots, USHORT _nBlockSize,					\
			   USHORT _nInitSize, USHORT _nReSize)						\
		:SvStringMapContainer(_nMaxSlots, _nBlockSize,					\
						 _nInitSize,_nReSize) {}						\
                                                                        \
    Type GetObject(ULONG _nIndex) const									\
		{return (Type) SvStringMapContainer::GetObject(_nIndex);}		\
																		\
	ULONG GetPos(Type _pObj) const										\
		{return SvStringMapContainer::GetPos((void*)_pObj);}			\
																		\
	void InsertAt(const String& _rKey,									\
			      Type _pObj,											\
				  ULONG _nIndex = CONTAINER_APPEND)						\
		{SvStringMapContainer::InsertAt(_rKey, (void*) _pObj,			\
												 _nIndex);}				\
	Type ReplaceAt(const String& _rOldKey,const String& _rKey,			\
				   Type _pObj)											\
		{return (Type) SvStringMapContainer::ReplaceAt(_rOldKey,		\
												  _rKey,				\
												  (void*) _pObj);}		\
	Type ReplaceAt(ULONG _nIndex, const String& _rKey, Type _pObj)		\
		{return (Type) SvStringMapContainer::ReplaceAt(_nIndex,			\
												  _rKey,				\
												  (void*) _pObj);}		\
	Type Replace(Type _pOldObj, const String& _rKey, Type _pObj)		\
		{return (Type) SvStringMapContainer::Replace((void*) _pOldObj,	\
												_rKey, (void*) _pObj);}	\
																		\
	String GetKey(Type _pObj) const										\
		{return SvStringMapContainer::GetKey((void*)_pObj);}			\
	Type Lookup(const String& _rKey) const								\
		{return (Type) SvStringMapContainer::Lookup(_rKey);}			\
																		\
	Type RemoveAt(const String& _rKey)									\
		{return (Type) SvStringMapContainer::RemoveAt(_rKey);}			\
	Type RemoveAt(ULONG _nIndex)										\
		{return (Type) SvStringMapContainer::RemoveAt(_nIndex);}		\
	Type Remove(Type _pObj)												\
		{return (Type) SvStringMapContainer::Remove((void*)_pObj);}		\
};

//------------------------------------------------------------------
inline void SvStringMapContainer::Clear()
{
	Container::Clear();
	aMap.Clear();
}

#endif
