/* include not needed for Aztec C using provided makefile */
#include	"sb:sb.h"

#define		CHOICEWIDTH 280
#define		CHOICEHEIGHT 8
#define		SPACING 9
#define		TOPGADG 30
#define		PUTTEXT(text, x, y) { Move(rp, (long)x, (long)y); \
                	              Text(rp, text, (long)strlen(text)); }
struct	IntuitionBase 	*IntuitionBase = NULL;
struct	GfxBase		*GfxBase = NULL;
struct	Window 		*OpenWindow(), *MainWindow = NULL;
struct	RastPort 	*rp;
extern	int 		level;
APTR	OpenLibrary();
struct	IntuiText 	ChoiceText[MAXGADG + 1];
struct	Gadget 		ChoiceGadg[MAXGADG + 1];
extern	void 		CloseOut(), Redisplay();

struct IntuiText BackIText = {
        3, 2, JAM2,
        5, 2,
        NULL, NULL, NULL
    };
struct IntuiText MoreIText = {
        2, 3, JAM2,
        5, 2,
        NULL,
        (UBYTE *)"(MORE)",
        NULL
    };
struct Gadget BackGadg = {
        NULL,
        10, -12, 140, 12,
        GADGHCOMP | GRELBOTTOM,
        RELVERIFY,
        BOOLGADGET,
        NULL, NULL, &BackIText,
        NULL, NULL,
        0, NULL /* gadget ID is zero */
    };
struct Gadget MoreGadg = {
        NULL,
        300, -12, 59, 12,
        GADGHCOMP | GRELBOTTOM,
        RELVERIFY,
        BOOLGADGET,
        NULL, NULL, &MoreIText,
        NULL, NULL,
        MOREGADG, NULL
    };
struct NewWindow NWindow = {
        0, 10, 640, 189,        /* left, top, width, height */
        -1, -1,                 /* use screen colours */
        GADGETUP                /* IDCMP flags */
         | CLOSEWINDOW,
        WINDOWDEPTH             /* window flags */
         | WINDOWCLOSE
         | WINDOWDRAG
         | RMBTRAP
         | ACTIVATE
         | NOCAREREFRESH
         | SMART_REFRESH,
        &BackGadg,              /* first gadget in list */
        NULL,
        (UBYTE *)"The Transactor Structure Browser V 1.0",
        NULL, NULL,
        0, 0, 0, 0,             /* sizing limits (non-resizable) */
        WBENCHSCREEN
    };


void SetupGadg()
{
int i;
  for (i = 0; i < MAXGADG; i++) {
    ChoiceText[i].BackPen     = 0;
    ChoiceText[i].DrawMode    = JAM2;
    ChoiceText[i].LeftEdge    = 0;
    ChoiceText[i].TopEdge     = 0;
    ChoiceText[i].ITextFont   = NULL;
    ChoiceText[i].IText       = NULL;
    ChoiceText[i].NextText    = NULL;
    ChoiceGadg[i].LeftEdge    = 20;
    ChoiceGadg[i].TopEdge     = i * SPACING + TOPGADG;
    ChoiceGadg[i].Width       = CHOICEWIDTH;
    ChoiceGadg[i].Height      = CHOICEHEIGHT;
    ChoiceGadg[i].Flags       = GADGHCOMP;
    ChoiceGadg[i].Activation  = RELVERIFY;
    ChoiceGadg[i].GadgetType  = BOOLGADGET;
    ChoiceGadg[i].GadgetText  = &ChoiceText[i];
    ChoiceGadg[i].GadgetID    = i + 1;  /* gadget IDs start at 1 */
  }
}


int GetChoice (num) int num;
{
struct IntuiMessage *GetMsg(), *message;
ULONG msgclass;         	/* message class from IDCMP */
APTR IAddr;			/* pointer to gadget from IDCMP */
  Redisplay(num);		/* put up choices in windows */
  FOREVER {			/*** main event loop ***/
    Wait (1L << MainWindow->UserPort->mp_SigBit);
    while (message = GetMsg(MainWindow->UserPort)) {
				/* get what we need from the message port */
      msgclass = message->Class;
      IAddr    = message->IAddress;
      ReplyMsg(message);	/* reply to message right away */
				/* check for gadget selected */
      if (msgclass == GADGETUP)
        return ( (int)((struct Gadget *)IAddr)->GadgetID );
				/* finish up if the close gadget is clicked */
      else if (msgclass == CLOSEWINDOW)
        CloseOut(); /* clean up and exit */
    }
  }
  return(0);			/* dummy to stop warning */
}


void putHeader(string, ptr) char *string; APTR ptr;
/* put title and pointer at top of screen -
 * if ptr is NULL, put string only. */
{
char buf[80];
  SetAPen(rp, 0L);
  RectFill(rp, 1L, 10L, (long)MainWindow->Width-25, 27L);
  SetAPen(rp, 3L);
  if (ptr) {
    sprintf(buf, "%d: %s (address $%lx):", level, string, ptr);
    PUTTEXT(
     " Member         Type                   Value (hex/decimal)",
     20L, 10L + 2 * rp->TxHeight);
  }
  else
    sprintf(buf, "%d: %s:", level, string);
  PUTTEXT(buf, 20L, 10L + rp->TxHeight);
}


void OpenStuff ()
{
  /* open intuition & graphics libraries and window */
  if (!(IntuitionBase = (struct IntuitionBase *)
                 OpenLibrary("intuition.library", 0L) ) )
    CloseOut();
  if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L) ) )
    CloseOut();
  /* now attempt to open the main window */
  if (!(MainWindow = OpenWindow(&NWindow)) )
    CloseOut();
  rp = MainWindow->RPort; /* rastport for graphics routines */
}


void CloseOut()
{
  /* close everything up before ending */
  if (MainWindow)    CloseWindow(MainWindow);
  if (IntuitionBase) CloseLibrary(IntuitionBase);
  if (GfxBase)       CloseLibrary(GfxBase);
  exit(0); /* exit program - we may be deeply nested */
}


void Redisplay(num) int num;
/* clear window, remove old gadgets, prepare and add new ones */
{
struct Gadget *gadg;
BOOL MoreFlag = FALSE;
int i, c;
  SetAPen(rp, 0L); /* rectfill with background colour to clear */
  RectFill(rp, 1L, (long)TOPGADG, (long)MainWindow->Width - 2,
           (long)MainWindow->Height - 2);
  if (num > MAXGADG) {
    num = MAXGADG;
    MoreFlag = TRUE; /* put up "more" gadget */
  }
  /* remove all choice gadgets */
  gadg = &BackGadg;
  while (gadg = gadg->NextGadget)
    RemoveGadget(MainWindow, gadg);
  /* render gadgets according to single-digit code at
   * the start of the gadget's intuitext */
  for (i = 0; i < num; i++) {
    ChoiceText[i].FrontPen = 1;
    if ((c = *ChoiceText[i].IText) == '-' || c == '(') {
      if (c == '-') {
        *ChoiceText[i].IText = ' ';
        ChoiceText[i].FrontPen = 2;
      }
      PrintIText(rp, &ChoiceText[i],
                (long)ChoiceGadg[i].LeftEdge,
                (long)ChoiceGadg[i].TopEdge);
    }
    else
      AddGadget(MainWindow, &ChoiceGadg[i], -1L);
  }
  if (MoreFlag)
    AddGadget(MainWindow, &MoreGadg, -1L);
  /* display gadget imagery (the text) */
  RefreshGadgets(&BackGadg, MainWindow, NULL);
}


void SetBackText (sflag) int sflag;
{
  BackIText.IText = (UBYTE *)(sflag ?
             " Previous  Page " : " Previous Level ");
}
