/*
 *  NewLook.H
 *
 *  (c)Copyright 1992,93 by Tobias Ferber,  All Rights Reserved
 */

#ifndef NEWLOOK_H
#define NEWLOOK_H

/****** newlook.lib/--background-- ******************************************
*
*   NEWLOOK
*	The amiga newlook.lib has been designed to simplify the development
*	of intuition based applications with os2.0 look even for os1.3
*	users.
*
*   NOTES
*	Wenn eine Funktion der newlook.lib eine andere Funktion der
*	newlook.lib aufruft und diese fehlschlägt, so wird durch den
*	SmartFreeAll(PRIVATE_HANDLE) in der aufgerufenen Funktion auch
*	all der Speicher freigegeben der von der aufrufenden Funktion
*	erfolgreich über das PRIVATE_HANDLE allokiert wurde.
*	Das heißt, das man sich (solage dies nicht geändert ist) an
*	folgende Konvention halten muß:
*
*	Wenn eine Funktion der newlook.lib fehlschlägt, so darf nur dann
*	die Funktion SmartFreeAll(PRIVATE_HANDLE) aufgerufen werden, wenn
*	das UserHandle != dem PRIVATE_HANDLE ist.
*
*	Allgemein sollte eine newlook Funktion etwa so aufgebaut sein:
*
*	<type> NewLook_Function( <parameters> )
*	....
*	{
*	  if( <parameters are valid> )
*	  {
*	    ULONG UserHandle= SetNewLookHandle(PRIVATE_HANDLE);
*
*	    if( <pointer 1>= SmartAllocate(<bytesize>) )
*	    {
*	      if( <pointer 2>= SmartAllocate(<bytesize>) )
*	      {
*	        ...
*
*	        <initialize all data>
*
*	        MakePrivateHandlePublic(UserHandle);
*	        return <pointer N>;
*	      }
*	    }
*
*	    if(UserHandle != PRIVATE_HANDLE)
*	    { SmartFreeAll(PRIVATE_HANDLE);
*	      (void)SetNewLookHandle(UserHandle);
*	    }
*	  }
*	  return NULL;
*	}
*
*   BUGS
*	manche funktionen hängen noch dieselbe border struct sowohl an
*	Gadget->GadgetRender als auch an Gadget->SelectRender
*	UND DAS IST NICHT SOO GUT!
*	weil es dann nur einen Border->NextBorder gibt!
*
*	GadgetRender suggeriert zwar, daß diese Borders auch im select
*	state gerendert werden, tun sie aber nicht.  Man muß also
*	zwei borders haben, einen für den select state und einen für den
*	nicht-select state.
*
*	wenn das gadget im nicht-select state gerendert wurde und dann
*	selektiert wird, so werden natürlich die gadgetrender borders nicht
*	automatisch gelöscht...
*
*	Konvention: border, die an SelectRender angehängt werden heißen b1,
*	die anderen entweder b oder b0.
*
*   TODO
*	alle funktionen, die als parameter ein window bekommen, aber
*	eigentlich nur deren RPort benötigen müssen auf den Parameter RastPort
*	umgestellt werden.
*
*	zu überprüfen sind:
*	  SetScalebar(), ToggleButton(), DoCycleButton(),
*	  SetPaletteButtonPen(), RemoveGadgetSafely(), SetGFlags(),
*
*   IDEAS
*	newlook bietet checkmark in windows?
*	ScrollListView()
*	Menu support ?
*	vielleicht: Martin's Pop-Up button (x-window like)
*	NewLookRequest() mit dem DCMP requester?
*
******************************************************************************
*
*	Headers taken from the Autodoc style guide as of June 1990
*/

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/rastport.h>

#ifdef __GNUC__
/* suggest parentheses around assignment used as truth value */
#define if(assignment) if((assignment))
#endif /* __GNUC__ */

/* smartmem.c */

#define SMARTMEMTYPE      (MEMF_PUBLIC|MEMF_CLEAR)
#define MAGIC_HANDLE      -1L
#define PRIVATE_HANDLE    270970L

extern ULONG SetNewLookHandle(ULONG);
extern void MakePrivateHandlePublic(ULONG);  /* NewLook PRIVATE !!! */

extern void *SmartAllocMem(ULONG,ULONG);
extern void *SmartFree(void *);
extern void *SmartFreeAll(ULONG);

#define SmartAllocate(numbytes)  SmartAllocMem( (numbytes),SMARTMEMTYPE )

#define CHECKBOX_WIDTH      26
#define CHECKBOX_HEIGHT     11

#define RADIOBUTTON_WIDTH   17
#define RADIOBUTTON_HEIGHT   9

#define SCALEBARHMIN        16
#define SCALEBARVMIN        12
#define SCALEBARPEN          3

/* CycleInfo will be linked to the CycleButton's UserData entry */
struct CycleInfo {
  APTR ci_UserData;                /* still available */
  struct IntuiText *ci_IntuiText;  /* copy of struct IntuiText pointer */
  STRPTR *ci_Items;                /* Array of strings w/ last STRPTR == NULL */
  SHORT ci_CurrentIndex;           /* index of currently visible text */
};

/* The structure returned by CreateScalebar() */
struct ScalebarInfo {
  struct Border *outline;   /* outline bevel box */
  struct Image *scalebar;   /* 3 images */
  LONG nmin, nmax;          /* numeric range */
  LONG wmin, wmax;          /* graphic range */
};

#define BORDERSIZE         (sizeof(struct Border))
#define BORDERXYSIZE       (2*5*sizeof(SHORT))
#define GFRAMEXYSIZE       (2*6*sizeof(SHORT))
#define GADGETSIZE         (sizeof(struct Gadget))
#define ITEXTSIZE          (sizeof(struct IntuiText))
#define STRINGINFOSIZE     (sizeof(struct StringInfo))
#define PROPINFOSIZE       (sizeof(struct PropInfo))
#define IMAGESIZE          (sizeof(struct Image))
#define CYCLEINFOSIZE      (sizeof(struct CycleInfo))
#define SCALEBARINFOSIZE   (sizeof(struct ScalebarInfo))
#define NEWWINDOWSIZE      (sizeof(struct NewWindow))

extern struct TextAttr Topaz80;

extern struct Border *CreateBorder(SHORT,SHORT, SHORT,SHORT, BOOL);
extern struct IntuiText *CreateIText(SHORT, SHORT, STRPTR);
extern struct Border *CreateFrame(SHORT,SHORT, USHORT,USHORT, USHORT,USHORT);

extern struct Border *AddGBorder(struct Gadget *, struct Border *);
extern struct IntuiText *AddGText(struct Gadget *, STRPTR,STRPTR);

extern BOOL AddGGroupFrame(struct Gadget *, SHORT,SHORT, SHORT,SHORT, STRPTR);

extern struct ScalebarInfo *CreateScalebar(SHORT,SHORT, SHORT,SHORT, LONG,LONG);
extern void SetScalebar(struct Window *, struct ScalebarInfo *, LONG);

extern struct Gadget *CreateButton(SHORT,SHORT, SHORT,SHORT, STRPTR, USHORT);
extern struct Gadget *CreateArrowButton(SHORT,SHORT, STRPTR, USHORT);
extern struct Gadget *CreateRadioButton(SHORT,SHORT, BOOL, USHORT);
extern struct Gadget *CreatePaletteButton(WORD, WORD, WORD, WORD, UBYTE, USHORT);
extern struct Gadget *CreateCheckbox(SHORT,SHORT, BOOL, USHORT);
extern struct Gadget *CreateCycleButton(SHORT,SHORT,SHORT, STRPTR *, USHORT);
extern struct Gadget *CreateStrGadget(SHORT,SHORT,SHORT, SHORT, USHORT);
extern struct Gadget *CreateSlider(SHORT,SHORT,SHORT, STRPTR, USHORT);
extern struct Gadget *CreateListView(SHORT,SHORT, SHORT,SHORT, STRPTR *, USHORT);

extern void ToggleButton(struct Window *, struct Gadget *);
extern void DoCycleButton(struct Window *, struct Gadget *);
extern void SetPaletteButtonPen(struct Window *, struct Gadget *, UBYTE);

extern USHORT RemoveGadgetSafely(struct Window *, struct Gadget *);
extern void SetGFlags(struct Window *, struct Gadget *, USHORT);

#define OffGadgetSafely(w,g) SetGFlags(w,g,g->Flags | GADGDISABLED)
#define OnGadgetSafely(w,g) SetGFlags(w,g,g->Flags &~ GADGDISABLED)

extern struct Gadget *LastGadget(struct Gadget *);
extern struct Border *LastBorder(struct Border *);
extern struct IntuiText *LastIText(struct IntuiText *);

extern void MoveIText(struct IntuiText *, SHORT,SHORT);

#define GadStrVal(g) (((struct StringInfo *)((g)->SpecialInfo))->Buffer)
#define GadNumVal(g) (((struct StringInfo *)((g)->SpecialInfo))->LongInt)

/* PaletteButton's UserData entry is NewLook private !!! */
#define GetPaletteButtonPen(g)  (((struct Border *)((g)->UserData))->FrontPen)

extern struct NewWindow *InitNewWindow(struct NewWindow *, UBYTE *, WORD,WORD, ULONG,ULONG, struct Gadget *);

#endif /* !NEWLOOK_H */
