#ifndef NamTbl_H
#define NamTbl_H

#ifndef ComBas_H
#include <OI/ComBas.H>
#endif /* ComBas_H */

/*
 ******************************************************************************
 *
 *	ParcPlace Systems, Inc.
 *	Copyright (c) 1990, ParcPlace Systems, Inc. USA   All rights reserved.
 *
 ****************************************************************************
 *
 *	File:	NamTbl.H
 *
 *	Description:
 *		Header for the following classes:
 *			NameTable
 *			NameTableEle
 *			NameTableEleWithId
 *			NameTableEleWithCommonBasePtr
 *
 *	NameTable:
 *
 *		This class implements a lookup method for named objects,
 *		assuming the name space is unique in terms of the CommonBaseNameId
 *		given to each object which will be tracked.  It does not deal
 *		with the character form of the name for an object, except to possibly
 *		convert an id to character form if so requested and it knows how.
 *
 *		The constructor is passed a table size and a function or
 *		(object, member function) pair used to generate CommonBaseNameId's
 *		from names.  In addition, it is optionally passed a function or
 *		(object, member function) pair capable of reversing the process.
 *		Since there may be cases where the id is generated via some irreversible
 *		process, the reversal functions are not mandatory.
 *
 *	NameTableEle:
 *
 *		This class implements an entry for a named object in a NameTable.
 *		It stores only that information needed by the NameTable, and provides
 *		a virtual member function to get at the object itself.
 *		The object may be a derived class of NameTableEle,
 *		some other unrelated object derived from CommonBase,
 *		or a totally unrelated object.
 *
 *	NameTableEleWithId:
 *
 *		This class implements an entry for a named object in a NameTable
 *		which stores the CommonBaseNameId in the object itself.
 *
 *	NameTableEleWithCommonBasePtr:
 *
 *		This class implements an entry for a named object in a NameTable
 *		where the object is not itself derived from NameTableEle, but is
 *		instead derived from CommonBase.
 *
 *	RCSid = "$Id: NamTbl.H,v 1.1.1.1 1993/06/01 22:52:03 mth Exp $"
 *
 ****************************************************************************
 */

class	NameTable;
class	NameTableEle;
class	NameTableEleWithId;
class	NameTableEleWithCommonBasePtr;

	typedef	CommonBaseNameId	(*OI_id_generator_fnp)(const char*) ;
	typedef	CommonBaseNameId	(CommonBase::*OI_id_generator_memfnp)(const char*) ;

	typedef	const char*		(*OI_id_convertor_fnp)(CommonBaseNameId) ;
	typedef	const char*		(CommonBase::*OI_id_convertor_memfnp)(CommonBaseNameId) ;

class	NameTable : public CommonBase	{					// Name table
 private:
			int			sz;				// Table size
			int			n_used;				// Number entries actually used
			NameTableEle		**tblp;				// Ptr to actual table
			OI_id_generator_fnp	id_fp ;				// ptr to function to generate id from name
			CommonBase		*id_objp ;			// ptr to object for id_mfp
			OI_id_generator_memfnp	id_mfp ;			// ptr to function to generate id from name
			OI_id_convertor_fnp	nam_fp ;			// ptr to function to convert id to name
			CommonBase		*nam_objp ;			// ptr to object for nam_mfp
			OI_id_convertor_memfnp	nam_mfp ;			// ptr to function to convert id to name
 private:
			NameTableEle		*first_entry();
			int			hash(CommonBaseNameId);
			void			init(int);			// initialize the table
			int			num_used()			{ return(n_used); }
						NameTable(int,OI_id_generator_fnp,CommonBase*,OI_id_generator_memfnp,
							OI_id_convertor_fnp,CommonBase*,OI_id_convertor_memfnp);
			NameTableEle		*search(CommonBaseNameId);	// Returns 0 if not found
 public:
						NameTable(int, OI_id_generator_fnp, OI_id_convertor_fnp=0);
						NameTable(int, CommonBase*, OI_id_generator_memfnp, OI_id_convertor_fnp=0);
						NameTable(int, OI_id_generator_fnp, CommonBase*, OI_id_convertor_memfnp);
						NameTable(int, CommonBase*, OI_id_generator_memfnp, CommonBase*, OI_id_convertor_memfnp);
						~NameTable();
			int			add(NameTableEle*);		// Returns non-zero if successful
			int			add(CommonBase*,const char*);	// Returns non-zero if successful
			int			add(CommonBase*,CommonBaseNameId);	// Returns non-zero if successful
			CommonBaseNameId	generate_id(const char*);	// Generate id from name
		const	char			*name(CommonBaseNameId);	// Generate name from id if possible
			CommonBase		*lookup(CommonBaseNameId);	// Returns 0 if not found
			void			remove(CommonBaseNameId);	// No-op if not found
			void			remove(NameTableEle*);		// No-op if not found
	};

class	NameTableEle : public CommonBaseWithName	{			// Element in NameTable
	friend	class	NameTable;
			NameTable		*ovf_tblp;			// Ptr to overflow table
 private:
			void			delete_overflow()		{ delete ovf_tblp; ovf_tblp=0; }
			NameTable		*overflow_table()		{ return(ovf_tblp); }
			void			set_overflow(NameTable *t)	{ ovf_tblp=t; }
 public:
						NameTableEle() : CommonBaseWithName()	{ }
	virtual					~NameTableEle();
	virtual		CommonBase		*object();			// Get ptr to actual object stored in table
	// Note!
	// Deriving a subclass requires implementing the virtuals id(), and name()
};

class	NameTableEleWithId : public NameTableEle	{			// NameTableEle with stored id
			CommonBaseNameId	_cb_id;				// short, efficient form for object name
 protected:
			void			set_id(CommonBaseNameId i)		{ _cb_id = i; }
 public:
						NameTableEleWithId(CommonBaseNameId i) : NameTableEle()	{ _cb_id=i; }
	virtual					~NameTableEleWithId();
	virtual		CommonBaseNameId	id();
	// Note!
	// Deriving a subclass requires implementing the virtual name()
	// Do NOT use set_id() once the object has been inserted in a name table!
};

class	NameTableEleWithCommonBasePtr : public NameTableEle	{		// NameTableEle with stored CommonBase object ptr
 private:
			CommonBase		*objp;				// ptr to actual object
 public:
						NameTableEleWithCommonBasePtr(CommonBase *p) : NameTableEle()	{ objp=p; }
	virtual					~NameTableEleWithCommonBasePtr();
	virtual		CommonBase		*object();
	// Note!
	// Deriving a subclass requires implementing the virtuals id(), and name()
};

#endif /* NamTbl_H */
