//	Zinc Application Framework - Z_LIST.HPP
//	COPYRIGHT (C) 1990-1999.  All Rights Reserved.
//	Zinc Software Incorporated.  Pleasant Grove, Utah  USA

#if !defined(Z_LIST_HPP)
#define Z_LIST_HPP
#include <z_env.hpp>
#include <z_objid.hpp>
#include <z_numid.hpp>

// --------------------------------------------------------------------------
// ----- ZafElement ---------------------------------------------------------
// --------------------------------------------------------------------------

class ZAF_EXPORT ZafElement
{
public:
	// --- General members ---
	ZafElement(void);
	ZafElement(const ZafElement &copy);
	virtual ~ZafElement(void);
	virtual ZafElement *Find(ZafNumberID numberID);
	virtual ZafElement *Find(ZafStringID stringID);
	int ListIndex(void) const;
	ZafElement *Next(void) const { return (next); }
	ZafElement *Previous(void) const { return (previous); }

	// --- Attributes ---
	// get
	ZafNumberID NumberID(void) const { return (numberID); }
	ZafStringID StringID(void) const { return (stringID); }
	// set
	ZafNumberID SetNumberID(ZafNumberID numberID);
	ZafStringID SetStringID(ZafStringID stringID);

	// --- Class identification ---
	static ZafClassID classID;
	static ZafClassNameChar ZAF_FARDATA className[];
	virtual ZafClassID ClassID(void) const { return (classID); }
	virtual ZafClassName ClassName(void) const { return (className); }
	virtual bool IsA(ZafClassID compareID) const;
	virtual bool IsA(ZafClassName compareName) const;
	static ZafElement *EvaluateIsA(ZafElement *element, ZafClassID compareID);

	// --- Unicode support ---
#	if defined(ZAF_UNICODE)
	ZafStringID SetStringID(const char *stringID);
#	endif

protected:
	friend class ZAF_EXPORT ZafList;

	// --- General members ---
	ZafElement *previous, *next;
	ZafNumberID numberID;
	ZafStringID stringID;
};

// --- DynamicPtrCast ---
#if !defined(USE_ZAF_RTTI) && ((defined(__BCPLUSPLUS__) || \
	defined(__TCPLUSPLUS__)) && __BORLANDC__ >= 0x460) || \
	(defined(_MSC_VER) && defined(_CPPRTTI)) || defined(__MWERKS__)
#	define DynamicPtrCast(arg, type) dynamic_cast<type *>(arg)
#else
#	define DynamicPtrCast(arg, type) ((type *)ZafElement::EvaluateIsA(arg, type::classID))
#endif

// --------------------------------------------------------------------------
// ----- ZafList ------------------------------------------------------------
// --------------------------------------------------------------------------

typedef int (*ZafCompareFunction)(ZafElement *, ZafElement *);

class ZAF_EXPORT ZafList
{
public:
	// --- General members ---
	ZafList(ZafCompareFunction compareFunction = ZAF_NULLF(ZafCompareFunction));
	virtual ~ZafList(void);
	ZafElement *Add(ZafElement *newElement);
	ZafElement *Add(ZafElement *element, ZafElement *position);
	int Count(void) const { return (count); }
	virtual void Destroy(void);
	ZafElement *Find(ZafNumberID numberID);
	ZafElement *Find(const ZafIChar *stringID);
	ZafElement *First(void) const { return (first); }
	ZafElement *Get(int index);
	ZafElement *Get(int (*findFunction)(ZafElement *element, ZafElement *matchData), ZafElement *matchData);
	int Index(ZafElement const *element) const;
	ZafElement *Last(void) const { return (last); }
	virtual void Sort(void);
	ZafElement *Subtract(ZafElement *element);

	// --- Attributes ---
	// get
	virtual ZafCompareFunction CompareFunction(void) const;
	ZafElement *Current(void) const { return (current); }
	// set
	virtual ZafCompareFunction SetCompareFunction(ZafCompareFunction compareFunction);
	void SetCurrent(ZafElement *element) { current = element; }

	ZafList &operator+(ZafElement *element) { Add (element); return (*this); }
	ZafList &operator-(ZafElement *element) { Subtract (element); return (*this); }
	ZafElement *operator()(int index) { return ((ZafElement *)ZafList::Get(index)); }

protected:
	friend class ZAF_EXPORT ZafListBlock;

	// --- General members ---
	ZafCompareFunction compareFunction;
	ZafElement *first, *last, *current;
	int count;
};

// --------------------------------------------------------------------------
// ----- ZafListBlock -------------------------------------------------------
// --------------------------------------------------------------------------

class ZAF_EXPORT ZafListBlock : public ZafList
{
public:
	// --- General members ---
	ZafListBlock(int noOfElements, ZafCompareFunction compareFunction = ZAF_NULLF(ZafCompareFunction));
	virtual ~ZafListBlock(void);
	ZafElement *Add(void);
	ZafElement *Add(ZafElement *element);
	ZafElement *Subtract(ZafElement *element);

	// --- Attributes ---
	bool Full(void) const { return (freeList.First() ? false : true); }

protected:
	int noOfElements;
	void *elementArray;
	ZafList freeList;
};

#endif // Z_LIST_HPP

