#ifndef BOOPSI_BOOPSILIB_H
#define BOOPSI_BOOPSILIB_H

// Einige immer wieder benötigte Funktionen für BOOPSI Implementationen
//
// Autor: Jochen Becher
//
// Historie:
// Version 1.0 am 15. Mai 94

#ifndef EXEC_TYPES_H
#include <exec/types.h>
#endif

#ifndef UTILITY_TAGITEM_H
#include <utility/tagitem.h>
#endif

#ifndef INTUITION_CLASSUSR_H
#include <intuition/classusr.h>
#endif

#ifndef INTUITION_CLASSES_H
#include <intuition/classes.h>
#endif

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

#ifndef INTUITION_IMAGECLASS_H
#include <intuition/imageclass.h>
#endif

// SuperDrawImageState zeichnet Images unter Verwendung von DrawImage
// und DrawImageState. Dabei werden sowohl BOOPSI Images wie auch
// "normale" Images geeignet gezeichnet.
// Das Image wird in das umfassende Rechteck (dx,dy,width,height) zentriert
// gezeichnet.
VOID SuperDrawImageState(struct RastPort *rp, struct Image *image,
	struct Image *select, LONG dx, LONG dy, LONG width, LONG height,
	ULONG state, struct DrawInfo *drawinfo);

// Setzen von Attributen eines Gadgets aus einem Gadget mit bekannter
// GadgetInfo
ULONG SetGInfoAttrs(Object *, struct GadgetInfo *, Tag tag1type, ...);

// Setzen von Attributen des Elterngadgets aus einem Gadget mit bekannter
// GadgetInfo
ULONG SetSuperGInfoAttrs(Class *, Object *, struct GadgetInfo *,
	Tag tag1type, ...);

// Schickt eine Update Nachricht mit bekannter GadgetInfo
ULONG UpdateGInfoAttrs(Object *, struct GadgetInfo *, ULONG flags,
	Tag tag1type, ...);

// Die SetGadgetAttrs Routine der amiga.lib ist "broken"
ULONG SetGadgetAttrsJB(struct Gadget *g, struct Window *w,
	struct Requester *r,	Tag tag1type, ...);

// Für umrahmte Gadgets, deren Rahmen im Gadget drin liegen, kann man
// hiermit die Größe und Position des inneren Bereichs ausmessen.
VOID GetInnerFrame(struct Gadget *g, Object *frame, struct IBox *framebox,
	WORD *frameright, WORD *framebottom);

// Ausgabe eines Labels mit Unterstreichung ohne Clipping.
#define STADJUST_Left     0
#define STADJUST_Center   1
#define STADJUST_Right    2

struct LabelText {
	struct IntuiText itext;
	ULONG memsize;
	LONG markpos;
	WORD length;
	WORD markX;
	WORD markWidth;
};

struct LabelText *AllocLText(STRPTR str, struct TextAttr *tattr,
	UBYTE apen, UBYTE bpen = 0, UBYTE drmd = JAM1, UBYTE mark = 0);
VOID FreeLText(struct LabelText *);
WORD MeasureLText(struct LabelText *);
VOID ChangeLTextFont(struct LabelText *, struct TextAttr *);
VOID ChangeLTextPens(struct LabelText *, UBYTE apen, UBYTE bpen, UBYTE drmd);
VOID ChangeLText(struct LabelText *, STRPTR , UBYTE mark = 0);
VOID PrintLText(struct RastPort *, struct LabelText *,
	WORD x, WORD y, WORD width, WORD height, WORD adjust = STADJUST_Left);

// Einige Textroutinen
WORD MeasureTextLength(STRPTR s, struct TextAttr *);
VOID PrintClipped(struct RastPort *, STRPTR s,
	WORD x, WORD y, WORD width, WORD height, WORD adjust = STADJUST_Left);

// Eine einfache Drawengine für skalierbare Symbole
#define DRAWCMD_End    0
#define DRAWCMD_Move   1
#define DRAWCMD_Draw   2
#define DRAWCMD_Attr   3
#define DRAWCMD_Fill   4
#define DRAWCMD_Image  5

struct DrawData {
	WORD command;
	union {
		struct {
			WORD x;
			WORD y;
		} move;
		struct {
			WORD x;
			WORD y;
		} draw;
		struct {
			WORD pen;
			WORD planepen;
		} attr;
		struct {
			WORD pen;
			WORD planepen;
		} fill;
		struct {
			struct Image *image;
		} image;
	} c;
};

VOID drawOutlineImage(struct RastPort *rp, struct DrawData *v,
	WORD x, WORD y, WORD w, WORD h, struct DrawInfo *di,
	BOOL outline, BOOL plane, BOOL recessed, LONG state);

#endif
