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

#if !defined(Z_EVTMGR_HPP)
#define Z_EVTMGR_HPP
#include <z_device.hpp>
#include <z_dsp.hpp>
#if defined(ZAF_RTOS)
#	include <z_sem.hpp>
#endif

// --------------------------------------------------------------------------
// ----- ZafQueueElement & ZafQueueBlock ------------------------------------
// --------------------------------------------------------------------------

class ZAF_EXPORT ZafQueueElement : public ZafElement
{
public:
	// --- General members ---
	ZafEventStruct event;

	ZafQueueElement(void);
	virtual ~ZafQueueElement(void);

	// --- Element members ---
	ZafQueueElement *Next(void) const { return((ZafQueueElement *)next); }
	ZafQueueElement *Previous(void) const { return((ZafQueueElement *)previous); }
};

class ZAF_EXPORT ZafQueueBlock : public ZafListBlock
{
public:
	// --- General members ---
	ZafQueueBlock(int noOfElements);
	virtual ~ZafQueueBlock(void);

	// --- List members ---
	ZafQueueElement *Current(void) const { return((ZafQueueElement *)current); }
	ZafQueueElement *First(void) const { return((ZafQueueElement *)first); }
	ZafQueueElement *Last(void) const { return((ZafQueueElement *)last); }
};

// --------------------------------------------------------------------------
// ----- ZafEventManager ----------------------------------------------------
// --------------------------------------------------------------------------

// --- ZafQFlags ---
typedef unsigned int ZafQFlags;
const ZafQFlags Q_NORMAL		= 0x0000;	// block, begin, destroy and poll
const ZafQFlags Q_BLOCK			= 0x0000;
const ZafQFlags Q_NO_BLOCK		= 0x0001;
const ZafQFlags Q_BEGIN			= 0x0000;
const ZafQFlags Q_END			= 0x0002;
const ZafQFlags Q_DESTROY		= 0x0000;
const ZafQFlags Q_NO_DESTROY	= 0x0004;
const ZafQFlags Q_POLL			= 0x0000;
const ZafQFlags Q_NO_POLL		= 0x0008;

class ZAF_EXPORT ZafEventManager : public ZafList
{
public:
	// --- General members ---
	ZafEventManager(int noOfQueueEvents = 100);
	virtual ~ZafEventManager(void);
	virtual ZafEventType Event(const ZafEventStruct &event, ZafDeviceType deviceType = E_DEVICE);
	virtual int Get(ZafEventStruct &event, ZafQFlags flags = Q_NORMAL);
	virtual ZafDevice *GetObject(ZafNumberID numberID);
	virtual ZafDevice *GetObject(const ZafIChar *stringID);
	virtual bool Put(const ZafEventStruct &event, ZafQFlags flags = Q_END);
	ZafEventType SetDeviceImage(ZafDeviceType deviceType, ZafDeviceImage deviceImage);
	ZafEventType SetDevicePosition(ZafDeviceType deviceType, int column, int line);
	ZafEventType SetDeviceState(ZafDeviceType deviceType, ZafDeviceState deviceState);
	void UnBlock(void);

	// --- Flag members ---
	bool Blocked(ZafQFlags qFlags) const { return ((qFlags & Q_NO_BLOCK) ? false : true); }
	bool ReadFromBeginning(ZafQFlags qFlags) const { return ((qFlags & Q_END) ? false : true); }
	bool ReadFromEnd(ZafQFlags qFlags) const { return ((qFlags & Q_END) ? true : false); }
	bool DestroyEvent(ZafQFlags qFlags) const { return ((qFlags & Q_NO_DESTROY) ? false : true); }
	bool PollDevices(ZafQFlags qFlags) const { return ((qFlags & Q_NO_POLL) ? false : true); }

	// --- List members ---
	virtual ZafDevice *Add(ZafDevice *device, ZafDevice *position = ZAF_NULLP(ZafDevice));
	ZafDevice *Current(void) const { return((ZafDevice *)current); }
	ZafDevice *First(void) const { return((ZafDevice *)first); }
	ZafDevice *Last(void) const { return((ZafDevice *)last); }
	virtual ZafDevice *Subtract(ZafDevice *device);

	ZafEventManager &operator+(ZafDevice *device) { Add(device); return(*this); }
	ZafEventManager &operator-(ZafDevice *device) { Subtract(device); return(*this); }
	ZafDevice *operator()(int index) { return((ZafDevice *)ZafList::Get(index)); }

	// --- Unicode support ---
#	if defined(ZAF_UNICODE)
	virtual ZafDevice *GetObject(const char *stringID);
#	endif

protected:
	ZafQueueBlock queueBlock;
#if defined(ZAF_MACINTOSH)
	bool blocking;
	RgnHandle mouseMovedRgn;
#elif defined(ZAF_RTOS)
	ZafSemaphore *blockingSemaphore;
	ZafSemaphore *exclusionSemaphore;
#endif

#if defined(ZAF_MOTIF)
private:
	bool blocking;
#endif
};

extern ZAF_EXPORT ZafEventManager *zafEventManager;

#endif // Z_EVTMGR_HPP

