#ifndef CPP_BOOPSI_POPUPMENUCLASS_H
#define CPP_BOOPSI_POPUPMENUCLASS_H

// Eine Klasse für Popup Menüs.
//
// Gadgets dieser Klasse können (und sollten) komplett von anderen Gadgets
// gesteuert werden: Diese schicken bei Bedarf ein GM_GOACTIVE, daraufhin
// öffnet sich das Menü. Dann können die InputEvents mittels GM_HANDLEINPUT
// an das Menü geschickt werden, bis dieses nicht mehr mit GM_MEACTIVE
// antwortet. Zum Ausblenden muß GM_GOINACTIVE an das Menü geschickt werden.
//
// Zwischen GM_GOACTIVE und GM_GOINACTIVE ist die LayerInfo gelockt, also
// dürfen solange keine weiteren Zeichenroutinen benutzt werden.
//
// Autor: Jochen Becher
//
// Historie:
// Version 1.0 am 2. März 94

#ifndef CPP_BOOPSI_BOOPSICLASS_H
#include <classes/boopsi/boopsiclass.h>
#endif

#ifndef CPP_BOOPSI_GADGETCLASS_H
#include <classes/boopsi/gadgetclass.h>
#endif

#define MA_Active     (TAG_USER+1)  // (ISG)
#define MA_Labels     (TAG_USER+2)  // (IS.)
#define MA_Font       (TAG_USER+3)  // (IS.)
#define MA_MaxHeight  (TAG_USER+4)  // (I..)

class PopupMenuClass : public BoopsiClass {
public:
	PopupMenuClass();
private:
	static ULONG dispatcher(Class *cl, Object *o, Msg msg);
	static ULONG renderPopupMenu(Class *cl, struct Gadget *g,
		struct gpRender *msg, struct InstanceData *);
	static UWORD countLabels(STRPTR *labels);
	static VOID cutActive(struct InstanceData *data);
	static BOOL InitPopupMenu(struct InstanceData *, struct Gadget *,
			struct GadgetInfo *);
	static VOID FinishPopupMenu(struct InstanceData *, struct GadgetInfo *);
	static VOID renderLabels(struct InstanceData *data,
		struct GadgetInfo *ginfo);
	static VOID invertActive(struct InstanceData *data,
		struct GadgetInfo *ginfo);
	static VOID renderArrowUp(struct InstanceData *data,
		struct GadgetInfo *ginfo);
	static VOID renderArrowDown(struct InstanceData *data,
		struct GadgetInfo *ginfo);
	static VOID scrollUp(struct InstanceData *data,
		struct GadgetInfo *ginfo);
	static VOID scrollDown(struct InstanceData *data,
		struct GadgetInfo *ginfo);
	static VOID renderPopupMenuFrame(struct RastPort *, UWORD left, UWORD top,
			UWORD width, UWORD height, UWORD *pens);
};

class BPopupMenuC : public BGadgetC {
public:
	BPopupMenuC(GadgetEventC *ev,WindowC &w, Tag tag1type, ...)
		: BGadgetC(ev,pmc.boopsiclass(),NULL,w,(struct TagItem *) &tag1type) { };
	BPopupMenuC(GadgetEventC *ev,WindowC &w, struct TagItem *tags)
		: BGadgetC(ev,pmc.boopsiclass(),NULL,w,tags) { };
	static PopupMenuClass *boopsiclass() { return &pmc; };
protected:
	BPopupMenuC(GadgetEventC *ev, struct IClass *c, STRPTR pubclass,
		WindowC &w, struct TagItem *tags)
		: BGadgetC(ev,NULL,pubclass,w,tags) { };
private:
	static PopupMenuClass pmc;
};

#endif
