/*-----------------------------------------*
 | File: SETUP.c - MLO 900131 V1.00        |
 | Setup of RPN windows, menus and gadgets |
 *-----------------------------------------*/

#include "rpn.h"
#include "proto.h"
#include "setup.h"
#include "gadget.h"
#include "menu.h"
#include <string.h>
#include <exec/memory.h>

extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern struct Window *Wrpn;
extern struct Window *Wreg;
extern struct RastPort *pRP;
extern struct Menu *MenuStrip;
extern struct Gadget *FirstGadget;
extern struct Gadget *pIG;
extern struct StringInfo *pIS;

/*--------------------------------------*
 | Pointers to copies in chip memory of |
 | the image nibbles, and their length  |
 *--------------------------------------*/

static USHORT *ChipSqrImageBits = NULL;
static USHORT *ChipX2ImageBits = NULL;
static USHORT *ChipE10ImageBits = NULL;
static USHORT *ChipL10ImageBits = NULL;
static USHORT *ChipYXImageBits = NULL;
static USHORT *ChipExpImageBits = NULL;
static USHORT *ChipSplImageBits = NULL;
static USHORT *ChipSmiImageBits = NULL;
static USHORT *ChipXXYImageBits = NULL;
static USHORT *ChipRleImageBits = NULL;
static USHORT *ChipPigImageBits = NULL;

static int ChipSqrImageLen;
static int ChipX2ImageLen;
static int ChipE10ImageLen;
static int ChipL10ImageLen;
static int ChipYXImageLen;
static int ChipExpImageLen;
static int ChipSplImageLen;
static int ChipSmiImageLen;
static int ChipXXYImageLen;
static int ChipRleImageLen;
static int ChipPigImageLen;

static void *libOpen(char *name, int rev);
static USHORT *imageBuild(USHORT *ImageBits, int ImageBitsLen, int *pLen);

void setup(void)
{
  struct NewWindow rpnWind = {
    RPN_LEFT, RPN_TOP, RPN_WIDTH, RPN_HEIGHT,
    BLUE_PEN, WHITE_PEN,
    RPN_IDCMP1 | RPN_IDCMP2, RPN_FLAG1 | RPN_FLAG2,
    &SinGadget, NULL,
    (UBYTE *) "RPN Pocket Calculator V1.00",
    NULL, NULL,
    0, 0, 0, 0,
    WBENCHSCREEN
  };

  struct NewWindow regWind = {
    REG_LEFT, REG_TOP, REG_WIDTH, REG_HEIGHT,
    BLUE_PEN, WHITE_PEN,
    REG_IDCMP, REG_FLAG1 | REG_FLAG2,
    NULL, NULL,
    (UBYTE *) "RPN Registers and Stack",
    NULL, NULL,
    0, 0, 0, 0,
    WBENCHSCREEN
  };

  int y;
  char x;

/*----------------*
 | Open libraries |
 *----------------*/

  IntuitionBase = libOpen("intuition.library", REVISION);
  GfxBase = libOpen("graphics.library", REVISION);

/*----------------------------------*
 | Builds in the chip memory copies |
 | of the gadget image nibbles      |
 *----------------------------------*/

  SqrImage.ImageData = ChipSqrImageBits =
      imageBuild(SqrImageBits, sizeof(SqrImageBits), &ChipSqrImageLen);
  X2Image.ImageData = ChipX2ImageBits =
      imageBuild(X2ImageBits, sizeof(X2ImageBits), &ChipX2ImageLen);
  E10Image.ImageData = ChipE10ImageBits =
      imageBuild(E10ImageBits, sizeof(E10ImageBits), &ChipE10ImageLen);
  L10Image.ImageData = ChipL10ImageBits =
      imageBuild(L10ImageBits, sizeof(L10ImageBits), &ChipL10ImageLen);
  YXImage.ImageData = ChipYXImageBits =
      imageBuild(YXImageBits, sizeof(YXImageBits), &ChipYXImageLen);
  ExpImage.ImageData = ChipExpImageBits =
      imageBuild(ExpImageBits, sizeof(ExpImageBits), &ChipExpImageLen);
  SplImage.ImageData = ChipSplImageBits =
      imageBuild(SplImageBits, sizeof(SplImageBits), &ChipSplImageLen);
  SmiImage.ImageData = ChipSmiImageBits =
      imageBuild(SmiImageBits, sizeof(SmiImageBits), &ChipSmiImageLen);
  XXYImage.ImageData = ChipXXYImageBits =
      imageBuild(XXYImageBits, sizeof(XXYImageBits), &ChipXXYImageLen);
  RleImage.ImageData = ChipRleImageBits =
      imageBuild(RleImageBits, sizeof(RleImageBits), &ChipRleImageLen);
  PigImage.ImageData = ChipPigImageBits =
      imageBuild(PigImageBits, sizeof(PigImageBits), &ChipPigImageLen);

  FirstGadget = &SinGadget;

/*----------------------------------*
 | Open windows and initialises     |
 | pointers to Intuition structures |
 *----------------------------------*/

  if ( (Wrpn = (struct Window *) OpenWindow(&rpnWind)) == NULL) {
    fprintf(stderr, "Can't open RPN main window ...\n");
    cleanup(SYS_ERROR);
  }

  if ( (Wreg = (struct Window *) OpenWindow(&regWind)) == NULL) {
    fprintf(stderr, "Can't open RPN stack window ...\n");
    cleanup(SYS_ERROR);
  }
  pRP = Wreg->RPort;
  pIG = &InGadget;
  pIS = &InInfo;

  SetMenuStrip(Wrpn, (MenuStrip = &GeneralMenu));

/*------------------------------------------------*
 | Prints initial stack and register values (0's) |
 *------------------------------------------------*/

  SetAPen(pRP, WHITE_PEN);
  RectFill(pRP, 0, 0, REG_WIDTH, REG_HEIGHT);
  SetAPen(pRP, BLUE_PEN);
  Move(pRP, REG_LINE, 0);
  Draw(pRP, REG_LINE, REG_HEIGHT);

  SetAPen(pRP, BLUE_PEN);
  SetBPen(pRP, WHITE_PEN);
  for (y=0; y<NREGS; y++) {
    Move(pRP, REG_X0-ARS_OFFSET, REG_Y0+y*REG_DY);
    x = '0'+y;
    Text(pRP, &x, 1);
    outReg(y);
  }

  SetAPen(pRP, BLACK_PEN);
  for (y=0; y<NACCS; y++) {
    Move(pRP, ACC_X0-ARS_OFFSET, ACC_Y0+y*ACC_DY);
    x = 'A'+y;
    Text(pRP, &x, 1);
    outAcc(y);
  }

  SetAPen(pRP, RED_PEN);
  for (y=NSTM1; y>=0; y--) {
    Move(pRP, STK_X0-ARS_OFFSET, STK_Y0-y*STK_DY);
    x = (y == NSTM1) ? 'T' : 'X'+y;
    Text(pRP, &x, 1);
  }
  outStk();
}

static void *libOpen(
  char *name,                   /* Library name */
  int rev                       /* Required revision (or 0) */
)
{/*--------------------------------------------*
  | Local function: opens the required library |
  *--------------------------------------------*/

  void *p;

  if ( (p = (void *) OpenLibrary(name, rev)) == NULL) {
    fprintf(stderr, "Can't open library \"%s\"", name);
    if (rev) fprintf(stderr, " revision %d", rev);
    fprintf(stderr, ".\n");
    cleanup(SYS_ERROR);
  }
  return p;
}

void deallMem(void)
{/*-----------------------------*
  | Deallocates all chip memory |
  *-----------------------------*/

  if (ChipSqrImageBits != NULL) {
    FreeMem(ChipSqrImageBits, ChipSqrImageLen);
  }
  if (ChipX2ImageBits != NULL) {
    FreeMem(ChipX2ImageBits, ChipX2ImageLen);
  }
  if (ChipE10ImageBits != NULL) {
    FreeMem(ChipE10ImageBits, ChipE10ImageLen);
  }
  if (ChipL10ImageBits != NULL) {
    FreeMem(ChipL10ImageBits, ChipL10ImageLen);
  }
  if (ChipYXImageBits != NULL) {
    FreeMem(ChipYXImageBits, ChipYXImageLen);
  }
  if (ChipExpImageBits != NULL) {
    FreeMem(ChipExpImageBits, ChipExpImageLen);
  }
  if (ChipSplImageBits != NULL) {
    FreeMem(ChipSplImageBits, ChipSplImageLen);
  }
  if (ChipSmiImageBits != NULL) {
    FreeMem(ChipSmiImageBits, ChipSmiImageLen);
  }
  if (ChipXXYImageBits != NULL) {
    FreeMem(ChipXXYImageBits, ChipXXYImageLen);
  }
  if (ChipRleImageBits != NULL) {
    FreeMem(ChipRleImageBits, ChipRleImageLen);
  }
  if (ChipPigImageBits != NULL) {
    FreeMem(ChipPigImageBits, ChipPigImageLen);
  }
}

static USHORT *imageBuild(
  USHORT *ImageBits,
  int ImageBitsLen,
  int *pLen
)
{/*---------------------------------------*
  | Local function: builds an image from  |
  | the specific bits for this gadget and |
  | the fixed parts (first and last two   |
  | lines, and the second bit plane)      |
  *---------------------------------------*/

  UBYTE *p, *p0;

  *pLen = ImageBitsLen + sizeof(CommonImageBits1) +
          sizeof(CommonImageBits2);
  if ( (p = p0 = (UBYTE *) AllocMem(*pLen, MEMF_CHIP)) == NULL) {
    cleanup(SYS_ERROR);
  }
  memcpy(p, CommonImageBits1, sizeof(CommonImageBits1));
  p += sizeof(CommonImageBits1);
  memcpy(p, ImageBits, ImageBitsLen);
  p += ImageBitsLen;
  memcpy(p, CommonImageBits2, sizeof(CommonImageBits2));
  return (USHORT *) p0;
}
