#ifndef CPP_INTUITION_WINDOW_H
#define CPP_INTUITION_WINDOW_H

// Eine Window Klasse
//
// Autor: Jochen Becher
//
// Historie:
// Version 1.0, am 8. Januar 94
//

#ifndef CPP_UTILITY_TAGITEM_H
#include <classes/utility/tagitem.h>
#endif

#ifndef INTUITION_INTUITION_H
#include <intuition/intuition.h>
#endif

#ifndef CPP_INTUITION_IDCMP_H
#include <classes/intuition/idcmp.h>
#endif

#ifndef CPP_EXCEPTIONS_EXCEPTIONS_H
#include <classes/exceptions/exceptions.h>
#endif

class WindowSnapshotC {
public:
	WindowSnapshotC();
	VOID setTop(WORD t) { wTop = t; };
	WORD top() const { return wTop; };
	VOID setLeft(WORD l) { wLeft = l; };
	WORD left() const { return wLeft; };
	VOID setWidth(WORD w) { wWidth = w; };
	WORD width() const { return wWidth; };
	VOID setHeight(WORD h) { wHeight = h; };
	WORD height() const { return wHeight; };
	VOID setBusy(BOOL b) { wBusy = b; };
	BOOL busy() const { return wBusy; };
private:
	WORD wTop,wLeft,wWidth,wHeight;
	BOOL wBusy;
};

// **************************************************************

class WindowC : protected NodeC {
friend class WindowListC;
public:
	WindowC(IDCMPortC &, Tag tag1Type, ...) throw (MemoryX);
	WindowC(IDCMPortC &, struct TagItem *tags = NULL) throw (MemoryX);
	WindowC(const WindowC &) throw (MemoryX);
	virtual ~WindowC();
	WindowC &operator= (const WindowC &) throw (MemoryX);
	BOOL isOpen() const { return window_ob != NULL; };
	struct Window *window() const { return window_ob; };
	struct RastPort *rastPort() const
		{ return window_ob ? window_ob->RPort : NULL; };
	IDCMPortC &idcmPort() const { return idcmport; };
	TagItemC &creationTags() const { return (TagItemC &) inittags; };
	virtual VOID open(Tag tag1Type, ...) throw (WindowX, MemoryX)
		{ WindowC::open((struct TagItem *) &tag1Type); };
	virtual VOID open(struct TagItem *tagList = NULL) throw (WindowX, MemoryX);
	virtual VOID close(BOOL snapshot = FALSE);
	virtual VOID setIDCMP(ULONG idcmpFlags);
	VOID addIDCMP(ULONG idcmpFlags);
	VOID subIDCMP(ULONG idcmpFlags);
	virtual BOOL setMenuStrip(class MenuC &);
	virtual BOOL resetMenuStrip();
	virtual VOID clearMenuStrip(BOOL forget = FALSE);
	virtual BOOL setGadgetList(class GadgetListC &);
	virtual VOID resetGadgetList(BOOL refresh = TRUE);
	virtual VOID clearGadgetList(BOOL forget = FALSE, BOOL refresh = TRUE);
	virtual VOID refreshGadgets();
	virtual BOOL setBusy(BOOL state);
	BOOL isBusy() const { return busy; };
	virtual BOOL snapshot(WindowSnapshotC &);
	virtual BOOL stamp(WindowSnapshotC &);
// die Methoden zur "alten" Gadgetverwaltung sind nicht kompatibel zur
// GadgetList
	BOOL addGadget(struct Gadget *gadget);
	BOOL addGadgets(struct Gadget *gadgets);
	BOOL remGadget(struct Gadget *gadget);
	BOOL remGadgets(struct Gadget *gadgets, WORD number = ~0);
	BOOL refreshGadgets(struct Gadget *gadgets, WORD number = ~0);
	virtual VOID activate();
	virtual BOOL changeSize(WORD Width, WORD Height);
	virtual VOID move(WORD LeftEdge, WORD TopEdge);
	virtual VOID change(WORD LeftEdge, WORD TopEdge, WORD Width, WORD Height);
	virtual BOOL limits(WORD MinWidth, WORD MinHeight, WORD MaxWidth, WORD MaxHeight);
	virtual BOOL limitMin(WORD MinWidth, WORD MinHeight);
	virtual BOOL limitMax(WORD MaxWidth, WORD MaxHeight);
	virtual VOID toBack();
	virtual VOID toFront();
	virtual VOID moveInFrontOf(struct Window *BehindWindow);
	virtual VOID moveInFrontOf(const WindowC &BehindWindow);
	virtual VOID zip();
	virtual VOID setTitles(STRPTR WindowTitle, STRPTR ScreenTitle);
	virtual VOID setWindowTitle(STRPTR WindowTitle);
	virtual VOID setScreenTitle(STRPTR ScreenTitle);
	virtual VOID setPointer(UWORD *Pointer,
		WORD Height, WORD Width, WORD XOffset, WORD YOffset);
	virtual VOID clearPointer();
	virtual VOID disableMenu(ULONG number, BOOL v);
	virtual VOID beginRefresh();
	virtual VOID endRefresh(BOOL Complete = TRUE);
	virtual VOID refreshFrame();
protected:
	virtual VOID freeIDCMP();
private:
	VOID clearBusy();
	IDCMPortC &idcmport;
	struct Window *window_ob;
	TagItemC inittags;
	BOOL menuattached;
	class MenuC *menu;
	ULONG idcmps;
	BOOL gadgetlistattached;
	class GadgetListC *gadgets;
	BOOL busy;
	struct Requester *busyReq;
	UWORD *busyPointer;
	BYTE busyHeight, busyWidth, busyXOffset, busyYOffset;
};

// **************************************************************

class WindowListC : protected ListC {
public:
	WindowListC();
	VOID add(WindowC &w) { ListC::addTail(w); };
	VOID close(BOOL snapshot = FALSE);
	BOOL setBusy(BOOL state, WindowC *except = NULL);
};

// **************************************************************

class WindowEventHandlerC : public IDCMPEventHandlerC {
public:
	WindowEventHandlerC(WindowC &, ULONG IDCMPclass);
	WindowEventHandlerC(class WindowEventHandlerChainC &);
	WindowC *window() const { return cWindow; };
protected:
	BOOL _forMe(IntuiMessageC &);
	WindowC *cWindow;
};

class WindowEventHandlerChainC : public WindowEventHandlerC,
	public HandlerChainC {
public:
	WindowEventHandlerChainC(WindowC &, ULONG IDCMPclass);
	VOID add(WindowEventHandlerC &h) { HandlerChainC::add(h); };
	BOOL handle(MessageC &msg) { return HandlerChainC::handle(msg); };
	BOOL exit() { return HandlerChainC::exit(); };
};

// **************************************************************

class WindowCloseHandlerC : public WindowEventHandlerC {
public:
	WindowCloseHandlerC(WindowC &);
	virtual VOID close() { _exit = TRUE; };
	BOOL exit() { return _exit };
protected:
	BOOL _handle(IntuiMessageC &);
	BOOL _exit;
};

// **************************************************************

class WindowActiveHandlerC : public WindowEventHandlerC {
public:
	WindowActiveHandlerC(WindowC &);
	virtual VOID activated() { };
protected:
	BOOL _handle(IntuiMessageC &);
};

// **************************************************************

class WindowInactiveHandlerC : public WindowEventHandlerC {
public:
	WindowInactiveHandlerC(WindowC &);
	virtual VOID inactivated() { };
protected:
	BOOL _handle(IntuiMessageC &);
};

// **************************************************************

class WindowRefreshHandlerChainC : public WindowEventHandlerChainC {
public:
	WindowRefreshHandlerChainC(WindowC &);
	BOOL handle(MessageC &);
};

class WindowRefreshHandlerC : public WindowEventHandlerC {
public:
	WindowRefreshHandlerC(WindowRefreshHandlerChainC &);
	virtual VOID refresh() { };
protected:
	BOOL _handle(IntuiMessageC &);
};

// **************************************************************

class WindowNewsizeHandlerC : public WindowEventHandlerC {
public:
	WindowNewsizeHandlerC(WindowC &);
	virtual VOID newsize() { };
protected:
	BOOL _handle(IntuiMessageC &);
};

// **************************************************************

class WindowSizeverifyHandlerC : public WindowEventHandlerC {
public:
	WindowSizeverifyHandlerC(WindowC &);
	virtual VOID verify() { };
protected:
	BOOL _handle(IntuiMessageC &);
};

// **************************************************************

class WindowChangeHandlerC : public WindowEventHandlerC {
public:
	WindowChangeHandlerC(WindowC &);
	virtual VOID change() { };
protected:
	BOOL _handle(IntuiMessageC &);
};

#endif
