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

#if !defined(Z_WIN_HPP)
#define Z_WIN_HPP
//	display, eventManager & dataManager
#include <z_scrdsp.hpp>
#include <z_evtmgr.hpp>
#include <z_data.hpp>
// 	miscellaneous identifications
#include <z_sysevt.hpp>
#include <z_logevt.hpp>
#include <z_notevt.hpp>
#include <z_appevt.hpp>
#include <z_dsnevt.hpp>
// language & locale
#include <z_cset.hpp>
#include <z_lang.hpp>
#include <z_loc.hpp>
// storage
#include <z_store.hpp>
// standard args
#include <z_stdarg.hpp>
// data objects
#include <z_str.hpp>
#include <z_pal1.hpp>

// --------------------------------------------------------------------------
// ----- ZafObjectPersistence -----------------------------------------------
// --------------------------------------------------------------------------

typedef ZafEventType (*ZafUserFunction)(ZafWindowObject *, ZafEventStruct &, ZafEventType);
typedef ZafEventType (*ZafExitFunction)(ZafDisplay *, ZafEventManager *, ZafWindowManager *);

struct ZAF_EXPORT ZafEventMap
{
	ZafLogicalEvent logicalValue;
	ZafEventType eventType;
	ZafRawCode rawCode;
	ZafRawCode modifiers;
};

#if defined(USE_ZAF_PERSISTENCE)
class ZAF_EXPORT ZafObjectPersistence;
class ZAF_EXPORT ZafWindowObject;
typedef ZafElement *(*ZafObjectConstructor)(const ZafIChar *, ZafObjectPersistence &);

class ZAF_EXPORT ZafObjectPersistence : public ZafDataPersistence
{
public:
	// --- Object constructors ---
	struct ObjectConstructor
	{
		ZafClassID classID;
		ZafClassName className;
		ZafObjectConstructor constructor;
	};

	// --- Compare functions --- 
	struct CompareFunction
	{
		ZafDataName name;
		ZafCompareFunction function;
	};

	// --- User functions --- 
	struct UserFunction
	{
		ZafDataName name;
		ZafUserFunction function;
	};

	// --- User objects --- 
	struct UserObject
	{
		ZafDataName name;
		void *object;
	};

	// --- General members ---
	ZafObjectPersistence(ZafFileSystem *fileSystem, DataConstructor *dataConstructor,
		ObjectConstructor *objectConstructor, UserFunction *userFunction = ZAF_NULLP(UserFunction),
		CompareFunction *compareFunction = ZAF_NULLP(CompareFunction),
		UserObject *userObject = ZAF_NULLP(UserObject));
	ZafObjectPersistence(const ZafObjectPersistence &copy);
	virtual ~ZafObjectPersistence(void);
	ZafObjectPersistence &PopLevel(void);
	ZafObjectPersistence &PushLevel(ZafClassName className, ZafClassID classID, ZafPersistEntryType type);

	virtual CompareFunction *AddCompareFunction(ZafDataName name, ZafCompareFunction function);
	virtual ObjectConstructor *AddObjectConstructor(ZafClassName className, ZafClassID classID, ZafObjectConstructor constructor);
	virtual UserFunction *AddUserCallback(ZafDataName name, ZafUserFunction function);
	virtual UserObject *AddUserObject(ZafDataName name, void *object);
	virtual void ClearCompareFunctions(void);
	virtual void ClearObjectConstructors(void);
	virtual void ClearUserCallbacks(void);
	virtual void ClearUserObjects(void);
	virtual ZafCompareFunction GetCompareFunction(ZafDataName name);
	virtual ZafObjectConstructor GetObjectConstructor(ZafClassID classID, ZafClassName className = 0);
	virtual ZafUserFunction GetUserCallback(ZafDataName name);
	virtual void *GetUserObject(ZafDataName name);
	bool Merge(ZafObjectPersistence &copy);
	virtual bool SetCompareFunctions(CompareFunction *compareFunction);
	virtual bool SetObjectConstructors(ObjectConstructor *objectConstructor);
	virtual bool SetUserCallbacks(UserFunction *userFunction);
	virtual bool SetUserObjects(UserObject *userObject);
	virtual bool SubtractCompareFunction(ZafDataName name);
	virtual bool SubtractObjectConstructor(ZafClassID classID, ZafClassName className = 0);
	virtual bool SubtractUserCallback(ZafDataName name);
	virtual bool SubtractUserObject(ZafDataName name);

	virtual ZafClassID CurrentClassID(void);
	virtual ZafClassName CurrentClassName(void);
	virtual ZafDataName GetClassName(ZafClassID classID);
	virtual ZafDataName GetCompareFunctionName(ZafCompareFunction function);
	virtual ZafDataName GetUserCallbackName(ZafUserFunction function);
	virtual ZafDataName GetUserObjectName(void *userObject);

protected:
	ObjectConstructor *objectConstructor;
	CompareFunction *compareFunction;
	UserFunction *userFunction;
	UserObject *userObject;
};

// --- global variable declarations ---
extern ZAF_EXPORT ZafObjectPersistence *zafObjectPersistence;
#endif

// --------------------------------------------------------------------------
// ----- ZafWindowObject ----------------------------------------------------
// --------------------------------------------------------------------------

enum ZafRegionType
{
	ZAF_INSIDE_REGION 		= 0,
	ZAF_OUTSIDE_REGION		= 1,
	ZAF_AVAILABLE_REGION	= 2
};

enum ZafScreenIDType
{
#	if defined(ZAF_MSWINDOWS)
	ZAF_SCREENID,
	ZAF_CLIENTID,
	ZAF_FRAMEID
#	elif defined(ZAF_MOTIF)
	ZAF_SCREENID,
	ZAF_CLIENTID,
	ZAF_FRAMEID,
	ZAF_SHELLID
#	elif defined(ZAF_INDEPENDENT)
	ZAF_SCREENID
#	elif defined(ZAF_MACINTOSH)
	ZAF_SCREENID,
	ZAF_WINDOWREF
#	endif
};

// Needed for borken version of GNU compiler supported by SCO
#if defined(EGCS_1)
class ZafWindowObject;
typedef ZafEventType (ZafWindowObject::*ZWO_MemberUserFunction)(const ZafEventStruct &event, ZafEventType ccode);
#endif

class ZAF_EXPORT ZafWindowObject : public ZafElement
{
public:
	// --- General members ---
	static ZafDisplay *display;
	static ZafEventManager *eventManager;
	static ZafWindowManager *windowManager;

	ZafWindowObject *parent;
	OSWindowID screenID;
	ZafRegionStruct zafRegion;

	virtual ~ZafWindowObject(void);
	virtual ZafEventType Event(const ZafEventStruct &event);
	virtual ZafWindowObject *GetObject(ZafNumberID numberID);
	virtual ZafWindowObject *GetObject(const ZafIChar *stringID);
	virtual ZafRegionStruct MaxRegion(ZafWindowObject *object,
		ZafVtJustify vWeight = ZAF_VT_TOP, ZafHzJustify hWeight = ZAF_HZ_LEFT);

	// --- Persistent members ---
	virtual ZafWindowObject *Duplicate(void);
#if defined(USE_ZAF_PERSISTENCE)
	static ZafElement *Read(const ZafIChar *name, ZafObjectPersistence &persist);
	virtual void Write(ZafObjectPersistence &persist);
#endif

	// --- Data access ---
	static ZafError UpdatePalettes(ZafWindowObject *object, ZafUpdateType type);
	// get
	ZafDisplay *Display(void) const { return (display); }
	virtual ZafWindowObject *FocusObject(void) const;
	const ZafIChar *HelpObjectTip(void) const;
	const ZafIChar *HelpContext(void) const;
	static int InitialDelay(void);
	ZafWindowObject *Parent(void) const;
	const ZafIChar *QuickTip(void) const;
	virtual ZafRegionStruct Region(void) const;
	static int RepeatDelay(void);
	virtual ZafWindowObject *RootObject(void) const;
	virtual const ZafIChar *Text(void);
	virtual void *UserInformation(ZafInfoRequest request, void *data, ZafClassID classID = ID_DEFAULT);
	ZafUserFunction UserFunction(void) const;
	// set
	virtual const ZafIChar *SetHelpObjectTip(const ZafIChar *helpObjectTip);
	virtual const ZafIChar *SetHelpContext(const ZafIChar *helpContext);
	static int SetInitialDelay(int initialDelay);
	ZafWindowObject *SetParent(ZafWindowObject *parent);
	virtual const ZafIChar *SetQuickTip(const ZafIChar *quickTip);
	virtual void SetRegion(const ZafRegionStruct &region);
	static int SetRepeatDelay(int repeatDelay);
	virtual ZafError SetText(const ZafIChar *text);
	virtual ZafUserFunction SetUserFunction(ZafUserFunction userFunction);

	// --- Attributes ---
	// get
	bool AcceptDrop(void) const;
	bool AutomaticUpdate(bool traverse = true) const;
	ZafLogicalColor BackgroundColor(ZafLogicalColor *color = ZAF_NULLP(ZafLogicalColor), ZafLogicalColor *mono = ZAF_NULLP(ZafLogicalColor));
	bool Bordered(void) const;
	virtual bool Changed(void) const;
	virtual bool CopyDraggable(void) const;
	bool Disabled(bool traverse = true) const;
	virtual bool Draggable(void) const;
	ZafError Error(void) const;
	bool Focus(void) const;
	ZafLogicalFont Font(void);
	ZafCoordinateType CoordinateType(void) const;
	virtual bool LinkDraggable(void) const;
	virtual bool MoveDraggable(void) const;
	bool Noncurrent(void) const;
	bool OSDraw(void) const;
	bool ParentDrawBorder(void) const;
	bool ParentDrawFocus(void) const;
	bool ParentPalette(void) const;
	ZafRegionType RegionType(void) const;
	bool Selected(void) const;
	virtual ZafStringData *StringData(void) const;
	ZafLogicalColor TextColor(ZafLogicalColor *color = ZAF_NULLP(ZafLogicalColor), ZafLogicalColor *mono = ZAF_NULLP(ZafLogicalColor));
	bool Visible(bool traverse = true) const;
	// set
	virtual bool SetAcceptDrop(bool acceptDrop);
	virtual bool SetAutomaticUpdate(bool automaticUpdate);
	virtual ZafLogicalColor SetBackgroundColor(ZafLogicalColor color, ZafLogicalColor mono = ZAF_MONO_NULL);
	virtual bool SetBordered(bool bordered);
	virtual bool SetChanged(bool changed);
	virtual bool SetCopyDraggable(bool copyDraggable);
	virtual bool SetDisabled(bool disabled);
	virtual ZafError SetError(ZafError error);
	virtual bool SetFocus(bool currentFocus);
	virtual ZafLogicalFont SetFont(ZafLogicalFont font);
	virtual bool SetLinkDraggable(bool linkDraggable);
	virtual bool SetMoveDraggable(bool moveDraggable);
	virtual bool SetNoncurrent(bool noncurrent);
	virtual bool SetOSDraw(bool osDraw);
	virtual bool SetParentDrawBorder(bool parentDrawBorder);
	virtual bool SetParentDrawFocus(bool parentDrawFocus);
	virtual bool SetParentPalette(bool parentPalette);
	virtual ZafRegionType SetRegionType(ZafRegionType regionType);
	virtual bool SetSelected(bool selected);
	virtual ZafError SetStringData(ZafStringData *stringData);
	virtual ZafLogicalColor SetTextColor(ZafLogicalColor color, ZafLogicalColor mono = ZAF_MONO_NULL);
	virtual bool SetVisible(bool visible);
	// toggle
	virtual bool ToggleSelected(void);

	// --- User information ---
	void *userObject;
	ZafFlags userFlags;
	ZafStatus userStatus;
	ZafIChar *userText;
	ZafPaletteData *userPaletteData;
	ZafUserFunction userFunction;
// Needed for borken version of GNU compiler supported by SCO
#if defined(EGCS_1)
	typedef ZWO_MemberUserFunction MemberUserFunction;
#else
	typedef ZafEventType (ZafWindowObject::*MemberUserFunction)(const ZafEventStruct &event, ZafEventType ccode);
#endif
	MemberUserFunction memberUserFunction;
	ZafEventType DefaultUserFunction(const ZafEventStruct &event, ZafEventType ccode);

	// --- User Palette ---
	virtual ZafError SetUserPaletteData(ZafPaletteData *paletteData);
	ZafPaletteData *UserPaletteData(void) const;

	// --- Advanced data access ---
	// get
	virtual void ConvertCoordinates(ZafCoordinateType coordinateType);
	virtual void ConvertRegion(ZafRegionStruct &region, ZafCoordinateType newType);
	virtual bool EditMode(void) const;
	bool SupportObject(void) const;
	bool SystemObject(void) const;
	// set
	virtual ZafCoordinateType SetCoordinateType(ZafCoordinateType coordinateType);
	virtual bool SetEditMode(bool editMode);
	virtual bool SetSupportObject(bool supportObject);
	virtual bool SetSystemObject(bool systemObject);

	// --- Advanced event handling ---
#	if defined(ZAF_MACINTOSH)
	virtual ZafEventType DispatchMouseEvent(const ZafEventStruct &event);
#	elif defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES)
	virtual ZafEventType DispatchMouseEvent(const ZafEventStruct &event);
	virtual ZafWindowObject *FindMouseObject(const ZafEventStruct &event);
#	endif
	virtual ZafEventType DragDropEvent(const ZafEventStruct &event);
	virtual ZafEventType Modify(const ZafEventStruct &event);
	virtual ZafEventType MoveEvent(const ZafEventStruct &event);
	virtual ZafWindowObject *NotifyFocus(ZafWindowObject *object, bool focus);
	virtual ZafWindowObject *NotifySelection(ZafWindowObject *object, bool selected);
	virtual bool RegisterMouse(bool view, bool leftMouse, bool rightMouse);
	virtual ZafEventType ScrollEvent(const ZafEventStruct &event);

	// --- Drawing ---
	virtual ZafRegionStruct BeginDraw(void);
	virtual ZafEventType Draw(const ZafEventStruct &event, ZafEventType ccode);
	virtual ZafEventType DrawBackground(ZafRegionStruct &region, ZafEventType ccode);
	virtual ZafEventType DrawBorder(ZafRegionStruct &region, ZafEventType ccode);
	virtual ZafEventType DrawFocus(ZafRegionStruct &region, ZafEventType ccode);
	virtual ZafEventType DrawShadow(ZafRegionStruct &region, int depth, ZafEventType ccode);
#	if defined(ZAF_TEXT_MODE)
	virtual void DrawText(ZafRegionStruct &region, const ZafIChar *text, int length = -1,
		ZafHzJustify hzJustify = ZAF_HZ_LEFT, ZafVtJustify vtJustify = ZAF_VT_CENTER,
		int hotKeyIndex = -1, bool fill = false);
#	endif   
	virtual void EndDraw(void);
	virtual void GetClip(ZafWindowObject *object, ZafRegionStruct &clip, ZafRegionStruct &viewPort);
	ZafLogicalEvent LogicalEvent(const ZafEventStruct &event);
	virtual ZafPaletteStruct LogicalPalette(ZafPaletteType type, ZafPaletteState state);
	void Redisplay(void);
	void RedisplayData(void);

	// --- Specialty functions ---
	virtual ZafRegionStruct ConvertToDrawRegion(const ZafWindowObject *object,
		const ZafRegionStruct *zafRegion = ZAF_NULLP(ZafRegionStruct)) const;
	virtual ZafPositionStruct ConvertToOSPosition(const ZafWindowObject *object,
		const ZafPositionStruct *zafPosition = ZAF_NULLP(ZafPositionStruct)) const;
	virtual ZafRegionStruct ConvertToOSRegion(const ZafWindowObject *object,
		const ZafRegionStruct *zafRegion = ZAF_NULLP(ZafRegionStruct)) const;
	virtual ZafPositionStruct ConvertToScreenPosition(const ZafPositionStruct objectPosition) const;
	virtual ZafPositionStruct ConvertToObjectPosition(const ZafPositionStruct screenPosition) const;
	virtual bool ConvertToZafEvent(ZafEventStruct &event);
	virtual ZafPositionStruct ConvertToZafPosition(const ZafWindowObject *object,
		const ZafPositionStruct *osPosition = ZAF_NULLP(ZafPositionStruct)) const;
	virtual ZafRegionStruct ConvertToZafRegion(const ZafWindowObject *object,
		const ZafRegionStruct *osRegion = ZAF_NULLP(ZafRegionStruct)) const;
	virtual ZafPaletteState PaletteState(void);

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

	// --- 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;

	// --- Special OS members ---
	virtual void OSMapPalette(ZafPaletteStruct &palette, ZafPaletteType type, ZafPaletteState state);
	virtual OSWindowID OSScreenID(ZafScreenIDType type = ZAF_SCREENID) const;
	virtual void OSSize(void);
	virtual ZafError OSUpdatePalettes(ZafPaletteType zafTypes, ZafPaletteType osTypes);

	// --- Unicode support ---
#	if defined(ZAF_UNICODE)
	ZafWindowObject *GetObject(const char *stringID);
	ZafError SetText(const char *text);
#	endif

#	if defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES)
	bool overlapped;
	void OSGetExposedRegionList(ZafRegionList &regionList);
	virtual void OSInvalidateRegion(ZafRegionStruct *region, bool immediateRedraw = false, bool client = false);
	virtual void OSUpdateRegions(ZafRegionList *region);
#	endif

protected:
	friend class ZAF_EXPORT OSWindowObject;

	// drag & drop
	bool acceptDrop;
	bool copyDraggable;
	bool linkDraggable;
	bool moveDraggable;
	// coordinates & orientation
	ZafCoordinateType coordinateType;
	ZafRegionType regionType;
	// status
	bool changed;
	bool editMode;
	bool focus;
	bool noncurrent;
	bool disabled;
	bool osDraw;
	bool parentDrawBorder;
	bool parentDrawFocus;
	bool parentPalette;
	bool selected;
	bool supportObject;
	bool systemObject;
	bool visible;
	// miscellaneous
	bool automaticUpdate;
	bool bordered;
	ZafError error;
	// help
	ZafIChar *helpContext;
	ZafIChar *quickTip;
	ZafIChar *helpObjectTip;

	// --- General members ---
	ZafWindowObject(int left, int top, int width, int height);
	ZafWindowObject(const ZafWindowObject &copy);
	virtual const ZafPaletteStruct *MapClassPalette(ZafPaletteType type, ZafPaletteState state);
	virtual ZafLogicalEvent MapEvent(ZafEventMap *mapTable, const ZafEventStruct &event);
	virtual const ZafPaletteStruct *MapPalette(const ZafPaletteMap *mapTable, ZafPaletteType type, ZafPaletteState state);
	virtual void RegisterObject(void);

	// --- Special OS members ---
	virtual ZafEventType OSEvent(const ZafEventStruct &event);
	virtual void OSRegisterObject(void);
	virtual ZafError OSSetText(void);

#if defined(USE_ZAF_PERSISTENCE)
	// --- Persistent members ---
	ZafWindowObject(const ZafIChar *name, ZafObjectPersistence &persist);
	virtual ZafObjectConstructor ReadFunction(void) { return (ZafWindowObject::Read); }
	void ReadData(ZafObjectPersistence &persist);
	void WriteData(ZafObjectPersistence &persist);

	virtual ZafDataName GetUserCallbackName(ZafUserFunction function, ZafObjectPersistence &persist);
	virtual ZafDataName GetUserObjectName(void *userObject, ZafObjectPersistence &persist);
#endif

	ZafRegionStruct oldRegion;
#if defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES)
	static ZafIChar *pasteBuffer;	// There is only one global paste buffer.
	static int pasteLength;

	// Moving and sizing.
	ZafEventType modifyMode;
	ZafRegionStruct modifyRegion;
	ZafRegionStruct lastRegion;
#endif

private:
	friend class ZAF_EXPORT ZafWindow;
	friend class ZAF_EXPORT ZafWindowManager;

	static ZafPaletteMap ZAF_FARDATA defaultPaletteMap[];
	static ZafEventMap ZAF_FARDATA defaultEventMap[];
	static ZafStringID genericFieldID;
	static int initialDelay;
	static int repeatDelay;

	// --- Flag members ---
	bool SizeLeft(ZafRawCode sizeFlags) const { return ((sizeFlags & ZAF_SIZE_LEFT) ? true : false); }
	bool SizeTop(ZafRawCode sizeFlags) const { return ((sizeFlags & ZAF_SIZE_TOP) ? true : false); }
	bool SizeRight(ZafRawCode sizeFlags) const { return ((sizeFlags & ZAF_SIZE_RIGHT) ? true : false); }
	bool SizeBottom(ZafRawCode sizeFlags) const { return ((sizeFlags & ZAF_SIZE_BOTTOM) ? true : false); }
};

// --- inline functions ---
inline bool ZafWindowObject::AcceptDrop(void) const { return (acceptDrop); }
inline bool ZafWindowObject::Bordered(void) const { return (bordered); }
inline ZafError ZafWindowObject::Error(void) const { return (error); }
inline bool ZafWindowObject::Focus(void) const { return (focus); }
inline ZafCoordinateType ZafWindowObject::CoordinateType(void) const { return (coordinateType); }
inline const ZafIChar *ZafWindowObject::HelpObjectTip(void) const { return (helpObjectTip); }
inline const ZafIChar *ZafWindowObject::HelpContext(void) const { return (helpContext); }
inline int ZafWindowObject::InitialDelay(void) { return (initialDelay); }
inline bool ZafWindowObject::OSDraw(void) const { return (osDraw); }
inline ZafWindowObject *ZafWindowObject::Parent(void) const { return (parent); }
inline bool ZafWindowObject::ParentDrawBorder(void) const { return (parentDrawBorder); }
inline bool ZafWindowObject::ParentDrawFocus(void) const { return (parentDrawFocus); }
inline bool ZafWindowObject::ParentPalette(void) const { return (parentPalette); }
inline const ZafIChar *ZafWindowObject::QuickTip(void) const { return (quickTip); }
inline void ZafWindowObject::Redisplay(void) { Event(S_REDISPLAY); }
inline void ZafWindowObject::RedisplayData(void) { Event(S_REDISPLAY_DATA); }
inline int ZafWindowObject::RepeatDelay(void) { return (repeatDelay); }
inline ZafRegionType ZafWindowObject::RegionType(void) const { return (regionType); }
inline bool ZafWindowObject::Selected(void) const { return (selected); }
inline ZafWindowObject *ZafWindowObject::SetParent(ZafWindowObject *tParent) { parent = tParent; return (parent); }
inline bool ZafWindowObject::SupportObject(void) const { return (supportObject); }
inline bool ZafWindowObject::SystemObject(void) const { return (systemObject); }
inline ZafUserFunction ZafWindowObject::UserFunction(void) const { return (userFunction); }
inline ZafPaletteData *ZafWindowObject::UserPaletteData(void) const { return (userPaletteData); }

// --------------------------------------------------------------------------
// ----- ZafWindow ----------------------------------------------------------
// --------------------------------------------------------------------------

class ZAF_EXPORT ZafBorder;
class ZAF_EXPORT ZafButton;
class ZAF_EXPORT ZafCloseButton;
class ZAF_EXPORT ZafGeometryManager;
class ZAF_EXPORT ZafIcon;
class ZAF_EXPORT ZafMaximizeButton;
class ZAF_EXPORT ZafMinimizeButton;
class ZAF_EXPORT ZafPopUpMenu;
class ZAF_EXPORT ZafPullDownMenu;
class ZAF_EXPORT ZafScrollBar;
class ZAF_EXPORT ZafSystemButton;
class ZAF_EXPORT ZafTitle;

enum ZafSelectionType
{
	ZAF_SINGLE_SELECTION 	= 0,
	ZAF_MULTIPLE_SELECTION	= 1,
	ZAF_EXTENDED_SELECTION	= 2
};

class ZAF_EXPORT ZafWindow : public ZafWindowObject, public ZafList
{
public:
	// --- General members ---
	ZafList support;

	ZafWindow(int left, int top, int width, int height);
	ZafWindow(const ZafWindow &copy);
	virtual ~ZafWindow(void);
	virtual void BroadcastEvent(const ZafEventStruct &event, int levels = 0);
	virtual ZafWindowObject *GetObject(ZafNumberID numberID);
	virtual ZafWindowObject *GetObject(const ZafIChar *stringID);

#if defined(USE_ZAF_PERSISTENCE)
	// --- Persistent members ---
	ZafWindow(const ZafIChar *name, ZafObjectPersistence &persist);
	static ZafElement *Read(const ZafIChar *name, ZafObjectPersistence &persist);
	virtual void Write(ZafObjectPersistence &persist);
#endif

	// --- Data access ---
	// get
	ZafBorder *Border(void) const;
	ZafRegionStruct ClientRegion(void) const;
	ZafScrollBar *CornerScrollBar(void) const;
	ZafButton *DefaultButton(bool defaultDefault = true) const;
	virtual ZafWindowObject *FocusObject(void) const;
	ZafGeometryManager *GeometryManager(void) const;
	ZafScrollBar *HorizontalScrollBar(void) const;
	ZafMinimizeButton *MinimizeButton(void) const;
	ZafMaximizeButton *MaximizeButton(void) const;
	ZafIcon *MinimizeIcon(void) const;
	ZafPullDownMenu *PullDownMenu(void) const;
	ZafSystemButton *SystemButton(void) const;
	ZafPopUpMenu *SystemButtonMenu(void) const;
	virtual const ZafIChar *Text(void);
	ZafTitle *Title(void) const;
	ZafScrollBar *VerticalScrollBar(void) const;
	// set
	ZafWindow *AddGenericObjects(const ZafIChar *title, ZafWindowObject *minObject = ZAF_NULLP(ZafWindowObject));
	ZafWindow *AddGenericObjects(ZafStringData *title, ZafWindowObject *minObject = ZAF_NULLP(ZafWindowObject));
	ZafButton *SetDefaultButton(ZafButton *button, bool defaultDefault = true);
	virtual ZafError SetText(const ZafIChar *text);

	// --- Attributes ---
	// get
	bool Destroyable(void) const;
	bool Locked(void) const;
	bool Maximized(void) const;
	bool Minimized(void) const;
	bool Modal(void) const;
	bool Moveable(void) const;
	bool NormalHotKeys(void) const;
	ZafWindow *Owner(void) const;
	ZafSelectionType SelectionType(void) const;
	bool Sizeable(void) const;
	bool Temporary(void) const;
	// set
	virtual bool SetDestroyable(bool destroyable);
	virtual bool SetDisabled(bool disabled);
	virtual bool SetLocked(bool locked);
	virtual bool SetMaximized(bool maximized);
	virtual bool SetMinimized(bool minimized);
	virtual bool SetModal(bool modal);
	virtual bool SetMoveable(bool moveable);
	virtual bool SetNormalHotKeys(bool normalHotKeys);
	virtual ZafWindow *SetOwner(ZafWindow *owner);
	virtual ZafSelectionType SetSelectionType(ZafSelectionType selectionType);
	virtual bool SetSizeable(bool sizeable);
	virtual bool SetTemporary(bool temporary);

	// --- Window object members ---
	virtual ZafRegionStruct BeginDraw(void);
	virtual bool Changed(void) const;
	virtual ZafPositionStruct ConvertToOSPosition(const ZafWindowObject *object,
		const ZafPositionStruct *zafPosition = ZAF_NULLP(ZafPositionStruct)) const;
	virtual bool ConvertToZafEvent(ZafEventStruct &event);
	virtual ZafPositionStruct ConvertToZafPosition(const ZafWindowObject *object,
		const ZafPositionStruct *osPosition = ZAF_NULLP(ZafPositionStruct)) const;
	virtual ZafEventType Draw(const ZafEventStruct &event, ZafEventType ccode);
	virtual ZafEventType DrawFocus(ZafRegionStruct &region, ZafEventType ccode);
	virtual ZafWindowObject *Duplicate(void);
	virtual ZafEventType Event(const ZafEventStruct &event);
	ZafLogicalEvent LogicalEvent(const ZafEventStruct &event);
	virtual bool SetAutomaticUpdate(bool automaticUpdate);
	virtual bool SetChanged(bool changed);
	virtual ZafCoordinateType SetCoordinateType(ZafCoordinateType coordinateType);
	virtual bool SetCopyDraggable(bool copyDraggable);
	virtual bool SetFocus(bool currentFocus);
	virtual bool SetLinkDraggable(bool linkDraggable);
	virtual bool SetMoveDraggable(bool moveDraggable);
	virtual bool SetParentDrawBorder(bool parentDrawBorder);
	virtual bool SetParentDrawFocus(bool parentDrawFocus);
	virtual bool SetSelected(bool selected);
	virtual void SetRegion(const ZafRegionStruct &region);
	virtual bool SetVisible(bool visible);

	// --- List members ---
	virtual ZafWindowObject *Add(ZafWindowObject *object, ZafWindowObject *position = ZAF_NULLP(ZafWindowObject));
	ZafWindowObject *Current(void) const { return ((ZafWindowObject *)current); }
	virtual void Destroy(void);
	ZafWindowObject *First(void) const { return ((ZafWindowObject *)first); }
	ZafWindowObject *Get(int index) { return ((ZafWindowObject *)ZafList::Get(index)); }
	ZafWindowObject *Last(void) const { return ((ZafWindowObject *)last); }
	virtual ZafWindowObject *Subtract(ZafWindowObject *object);
	ZafWindowObject *SupportCurrent(void) const { return ((ZafWindowObject *)support.Current()); }
	void SupportDestroy(void) { support.Destroy(); }
	ZafWindowObject *SupportFirst(void) const { return ((ZafWindowObject *)support.First()); }
	ZafWindowObject *SupportLast(void) const { return ((ZafWindowObject *)support.Last()); }

	ZafWindow &operator+(ZafWindowObject *object) { Add(object); return (*this); }
	ZafWindow &operator-(ZafWindowObject *object) { Subtract(object); return (*this); }
	ZafWindowObject *operator()(int index) { return ((ZafWindowObject *)ZafList::Get(index)); }

	// --- Element members ---
	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;

	// --- Special OS members ---
	virtual OSWindowID OSScreenID(ZafScreenIDType type = ZAF_SCREENID) const;
	virtual void OSSize(void);
	virtual ZafError OSUpdatePalettes(ZafPaletteType zafTypes, ZafPaletteType osTypes);

#	if defined(ZAF_MOTIF)
	long Decorations(void) const { return (decorations); }
	void ClearDecoration(long flag) { decorations &= ~flag; }
	void SetDecoration(long flag) { decorations |= flag; }
#	elif defined(ZAF_MACINTOSH)
	unsigned short Decorations(void) const { return (decorations); }
	void ClearDecoration(unsigned short flag) { decorations = (unsigned short)(decorations & ~flag); }
	void SetDecoration(unsigned short flag) { decorations |= flag; }
#	elif defined(ZAF_INDEPENDENT)
	virtual void OSInvalidateRegion(ZafRegionStruct *region, bool immediateRedraw = false, bool client = false);
	virtual void OSUpdateRegions(ZafRegionList *region);
#	endif

	// --- Advanced class members ---
#	if defined(ZAF_MACINTOSH)
	virtual ZafEventType DispatchMouseEvent(const ZafEventStruct &event);
#	elif defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES)
	virtual ZafEventType DispatchMouseEvent(const ZafEventStruct &event);
	virtual ZafWindowObject *FindMouseObject(const ZafEventStruct &event);
#	endif
	virtual ZafEventType Modify(const ZafEventStruct &event);
	virtual ZafWindowObject *NotifyFocus(ZafWindowObject *object, bool focus);
	virtual ZafWindowObject *NotifySelection(ZafWindowObject *object, bool selected);
	// get
	virtual void GetClip(ZafWindowObject *object, ZafRegionStruct &clip, ZafRegionStruct &viewPort);

	// --- Sorting functions ---
	static int CompareAscending(ZafWindowObject *object1, ZafWindowObject *object2);
	static int CompareDescending(ZafWindowObject *object1, ZafWindowObject *object2);

	// --- Unicode support ---
#	if defined(ZAF_UNICODE)
	ZafWindowObject *GetObject(const char *stringID);
	ZafError SetText(const char *text);
#	endif

protected:
	friend class ZAF_EXPORT OSWindow;
	friend class ZAF_EXPORT OSWindowShell;
	friend class ZAF_EXPORT OSWindowFrame;
	friend class ZAF_EXPORT OSWindowClient;

	// --- General members ---
	ZafButton *defaultButton;
	ZafButton *defaultDefaultButton;
	bool destroyable;
	bool locked;
	bool maximized;
	bool minimized;
	bool modal;
	bool moveable;
	bool normalHotKeys;
	ZafWindow *owner;
	ZafSelectionType selectionType;
	bool sizeable;
	bool temporary;
	ZafRegionStruct clientRegion;
	ZafRegionStruct restoreRegion;

	virtual const ZafPaletteStruct *MapClassPalette(ZafPaletteType type, ZafPaletteState state);
	virtual ZafRegionStruct MaxRegion(ZafWindowObject *object,
		ZafVtJustify vWeight = ZAF_VT_TOP, ZafHzJustify hWeight = ZAF_HZ_LEFT);
	virtual ZafEventType DragDropEvent(const ZafEventStruct &event);
	virtual ZafEventType ScrollEvent(const ZafEventStruct &event);

	// --- Special OS members ---
	virtual void OSDestroy(void);
	virtual ZafEventType OSEvent(const ZafEventStruct &event);
	virtual void OSMapPalette(ZafPaletteStruct &palette, ZafPaletteType type, ZafPaletteState state);
	virtual void OSRegisterObject(void);

#if defined(USE_ZAF_PERSISTENCE)
	// --- Persistent members ---
	void ReadChildren(ZafObjectPersistence &persist);
	void ReadData(ZafObjectPersistence &persist);
	virtual ZafObjectConstructor ReadFunction(void) { return (ZafWindow::Read); }
	virtual void WriteChildren(ZafObjectPersistence &persist);
	virtual void WriteSupportChildren(ZafObjectPersistence &persist);
	void WriteData(ZafObjectPersistence &persist);

	virtual ZafDataName GetCompareFunctionName(ZafCompareFunction function, ZafObjectPersistence &persist);
#endif

#	if defined(ZAF_INDEPENDENT)
	virtual ZafEventType DrawFrame(const ZafEventStruct &event, ZafEventType ccode);
	virtual ZafRegionStruct BeginDrawFrame(void);
	virtual void ModifyOSShift(ZafPositionStruct &osPosition);
	virtual void OSDrawChildren(ZafRegionList *regionList);
	virtual void OSDrawSupport(ZafRegionList *region);
#	endif

#	if defined(ZAF_MSWINDOWS)
	OSWindowID frameID;
#	endif 

private:
	bool sizeToClient;

	static ZafPaletteMap ZAF_FARDATA defaultPaletteMap[];
	static ZafEventMap ZAF_FARDATA defaultEventMap[];

	// --- Flag members ---
	bool SizeLeft(ZafRawCode sizeFlags) const { return ((sizeFlags & ZAF_SIZE_LEFT) ? true : false); }
	bool SizeTop(ZafRawCode sizeFlags) const { return ((sizeFlags & ZAF_SIZE_TOP) ? true : false); }
	bool SizeRight(ZafRawCode sizeFlags) const { return ((sizeFlags & ZAF_SIZE_RIGHT) ? true : false); }
	bool SizeBottom(ZafRawCode sizeFlags) const { return ((sizeFlags & ZAF_SIZE_BOTTOM) ? true : false); }

#	if defined(ZAF_MOTIF)
	long decorations;
#	elif defined(ZAF_MACINTOSH)
	unsigned short decorations;
#	endif
};

// --- inline functions ---
inline ZafRegionStruct ZafWindow::ClientRegion(void) const { return (clientRegion); }
inline bool ZafWindow::Destroyable(void) const { return (destroyable); }
inline bool ZafWindow::Locked(void) const { return (locked); }
inline bool ZafWindow::Maximized(void) const { return (maximized); }
inline bool ZafWindow::Minimized(void) const { return (minimized); }
inline bool ZafWindow::Modal(void) const { return (modal); }
inline bool ZafWindow::Moveable(void) const { return (moveable); }
inline bool ZafWindow::NormalHotKeys(void) const { return (normalHotKeys); }
inline ZafWindow *ZafWindow::Owner(void) const { return (owner); }
inline ZafSelectionType ZafWindow::SelectionType(void) const { return (selectionType); }
inline bool ZafWindow::Sizeable(void) const { return (sizeable); }
inline bool ZafWindow::Temporary(void) const { return (temporary); }

// --------------------------------------------------------------------------
// ----- ZafWindowManager ---------------------------------------------------
// --------------------------------------------------------------------------

class ZAF_EXPORT ZafWindowManager : public ZafWindow
{
public:
	ZafExitFunction exitFunction;
#if defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES)
	ZafWindowObject *cursorObject;
	ZafWindowObject *windowFocusObject;
#endif
	ZafWindowObject *defaultEventRoute;
	ZafWindowObject *dragObject;
	ZafWindowObject *focusObject;
	ZafWindowObject *helpObject;
	ZafWindowObject *mouseEventRoute;
	ZafWindowObject *mouseObject;
	ZafWindowObject *oldFocusObject;

	// --- General class members ---
	ZafWindowManager(ZafExitFunction exitFunction = ZAF_NULLF(ZafExitFunction));
	virtual ~ZafWindowManager(void);
	void Center(ZafWindowObject *object);

	// --- Data access ---
	// get
	ZafWindowObject *DefaultEventRoute(void) const;
	ZafExitFunction ExitFunction(void) const;
	virtual ZafWindowObject *FocusObject(void) const;
	ZafWindowObject *MouseEventRoute(void) const;
	// set
	ZafWindowObject *CaptureMouse(ZafWindowObject *mouseEventRoute);
	ZafWindowObject *SetDefaultEventRoute(ZafWindowObject *defaultEventRoute);
	ZafExitFunction SetExitFunction(ZafExitFunction exitFunction);
	ZafWindowObject *SetMouseEventRoute(ZafWindowObject *mouseEventRoute);

	// --- Window members ---
	virtual bool SetNormalHotKeys(bool normalHotKeys);
	virtual ZafSelectionType SetSelectionType(ZafSelectionType selectionType);
	virtual bool SetTemporary(bool temporary);

	// --- Window object members ---
	virtual ZafPositionStruct ConvertToOSPosition(const ZafWindowObject *object,
		const ZafPositionStruct *zafPosition = ZAF_NULLP(ZafPositionStruct)) const;
	virtual ZafPositionStruct ConvertToZafPosition(const ZafWindowObject *object,
		const ZafPositionStruct *osPosition = ZAF_NULLP(ZafPositionStruct)) const;
	virtual ZafRegionStruct ConvertToOSRegion(const ZafWindowObject *object,
		const ZafRegionStruct *zafRegion = ZAF_NULLP(ZafRegionStruct)) const;
	virtual ZafRegionStruct ConvertToZafRegion(const ZafWindowObject *object,
		const ZafRegionStruct *osRegion = ZAF_NULLP(ZafRegionStruct)) const;
#if defined(ZAF_INDEPENDENT)
	virtual ZafEventType Draw(const ZafEventStruct &event, ZafEventType ccode);
#endif
	virtual ZafWindowObject *Duplicate(void);
	virtual ZafEventType Event(const ZafEventStruct &event);
	virtual ZafWindowObject *GetObject(ZafNumberID numberID);
	virtual ZafWindowObject *GetObject(const ZafIChar *stringID);
	ZafLogicalEvent LogicalEvent(const ZafEventStruct &event);
	virtual ZafRegionStruct MaxRegion(ZafWindowObject *object,
		ZafVtJustify vWeight = ZAF_VT_TOP, ZafHzJustify hWeight = ZAF_HZ_LEFT);
	virtual bool SetAcceptDrop(bool acceptDrop);
	virtual bool SetAutomaticUpdate(bool automaticUpdate);
	virtual bool SetBordered(bool bordered);
	virtual bool SetOSDraw(bool osDraw);
	virtual bool SetParentDrawBorder(bool parentDrawBorder);
	virtual bool SetParentDrawFocus(bool parentDrawFocus);
	virtual bool SetParentPalette(bool parentPalette);
	virtual ZafRegionType SetRegionType(ZafRegionType regionType);

	// --- List members ---
	virtual ZafWindowObject *Add(ZafWindowObject *object, ZafWindowObject *position = ZAF_NULLP(ZafWindowObject));
	virtual ZafWindowObject *Subtract(ZafWindowObject *object);

	ZafWindowManager &operator+(ZafWindowObject *object) { Add(object); return (*this); }
	ZafWindowManager &operator-(ZafWindowObject *object) { Subtract(object); return (*this); }

	// --- 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;

	// --- Special OS members ---
#	if defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES)
	static OSWindowID currentScreenID;
#	endif
	virtual void OSMapPalette(ZafPaletteStruct &palette, ZafPaletteType type, ZafPaletteState state);

	// --- Advanced class members ---
#	if defined(ZAF_MACINTOSH)
	virtual ZafEventType DispatchMouseEvent(const ZafEventStruct &event);
#	elif defined(ZAF_INDEPENDENT) || defined(ZAF_CURSES)
	virtual ZafEventType DispatchMouseEvent(const ZafEventStruct &event);
	virtual void GetDrawRegionList(ZafWindowObject *object, ZafRegionList &regionList);
	virtual void OSInvalidateRegion(ZafRegionStruct *region, bool immediateRedraw = false,
		bool client = false);
	virtual void OSInvalidateObject(ZafRegionStruct *region, ZafWindowObject *object);
	virtual void OSValidateObject(ZafWindowObject *object);
	void RepairDamage(void);
#	endif
	virtual ZafWindowObject *NotifyFocus(ZafWindowObject *object, bool focus);

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

protected:
	// --- Event handling ---
	virtual ZafEventType ApplicationEvent(const ZafEventStruct &event);

	// --- Special OS members ---
	virtual ZafEventType OSEvent(const ZafEventStruct &event);

#if defined(ZAF_INDEPENDENT)
	ZafUpdateRegionList damageList;
#endif

private:
	static ZafEventMap ZAF_FARDATA defaultEventMap[];
	static ZafPaletteMap ZAF_FARDATA defaultPaletteMap[];

	ZafWindowManager(const ZafWindowManager &copy);
	virtual const ZafPaletteStruct *MapClassPalette(ZafPaletteType type, ZafPaletteState state);

#if defined(ZAF_MOTIF)
	class ZAF_EXPORT ZafModalList : public ZafList
	{
	public:
		class ZAF_EXPORT ZafModalElement : public ZafElement
		{
		public:
			ZafWindowObject *modalObject;

			ZafModalElement(ZafWindowObject *object);
			virtual ~ZafModalElement(void);
			ZafModalElement *Next(void) const { return ((ZafModalElement *)next); }
			ZafModalElement *Previous(void) const { return ((ZafModalElement *)previous); }
		};

		virtual ZafWindowObject *Add(ZafWindowObject *object, 
			ZafWindowObject *position = ZAF_NULLP(ZafWindowObject));
		ZafModalElement *First(void) const { return ((ZafModalElement *)first); }
		ZafModalElement *Last(void) const { return ((ZafModalElement *)last); }	
		virtual ZafWindowObject *Subtract(ZafWindowObject *object); 
	};
	ZafModalList modalList;
public:
	ZafWindow *modalWindow;	
#endif
};

// --- inline functions ---
inline ZafWindowObject *ZafWindowManager::DefaultEventRoute(void) const { return (defaultEventRoute); }
inline ZafExitFunction ZafWindowManager::ExitFunction(void) const { return (exitFunction); }
inline ZafWindowObject *ZafWindowManager::MouseEventRoute(void) const { return (mouseEventRoute); }
inline ZafWindowObject *ZafWindowManager::SetDefaultEventRoute(ZafWindowObject *tDefaultEventRoute) { defaultEventRoute = tDefaultEventRoute; return (defaultEventRoute); }
inline ZafWindowObject *ZafWindowManager::SetMouseEventRoute(ZafWindowObject *tMouseEventRoute) { mouseEventRoute = tMouseEventRoute; return (mouseEventRoute); }
inline ZafWindowObject *ZafWindowManager::CaptureMouse(ZafWindowObject *tMouseEventRoute) { return (SetMouseEventRoute(tMouseEventRoute)); }

// --- global variable declarations ---
extern ZAF_EXPORT ZafWindowManager *zafWindowManager;

#endif // Z_WIN_HPP

