/*
    module: icg.cc
  synopsis: internal GENESYS update routine for engine.cc

    author: Kevin Seidule and Marc Wolfgram

    Copyright 1989, 1990
    Simple Software Systems International, inc.

    ALL RIGHTS RESERVED
*/

#include "genesys.h"
#include <quickdraw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <control.h>
#include <memory.h>
#include <misctool.h>
#include <qdaux.h>
#include <window.h>
#include <intmath.h>

#define CancelID      0x00000002L          /* Cancel button ID              */

#define SetUpShop    -1                    /* calls from the engine         */
#define InitDialog    0
#define NewResType    1
#define NewResItem    2
#define ItemComplete  3
#define ProcessDone   4
#define UserAbort     5
#define ProcessError  6
#define NullUpdate    7
#define ReadUpdate    8
#define HeadUpdate    9
#define TailUpdate   10

#define ErrorThreshold 3                  /* total allowable errors       */

void    ThermoBar(word, word);
extern void PaulElseth(void);

char   *get_name(word, int);

typedef struct NewWindow2Template {
    Word        paramLength,
                wFrameBits;
    LongWord    wTitle,
                wRefCon;
    Rect        wZoom;
    LongWord    wColor;
    Integer     wYOrigin,
                wXOrigin;
    Word        wDataH,
                wDataW,
                wMaxH,
                wMaxW,
                wScrollVer,
                wScrollHor,
                wPageVer,
                wPageHor;
    LongWord    wInfoRefCon;
    Word        wInfoHeight;
    LongWord    wFrameDefProc,
                wInfoDefProc,
                wContDefProc;
    Rect        wPosition;
    LongWord    wPlane,
                wCtlList;
    Word        verb;
} NewWindow2Template;

/*-GLOBALS------------------------------------------------------------------*/
Rect clearRect   = { 1, 1, 70, 348 };
Rect typesRect   = { 32, 28, 42, 332 };    /* rect to % type done meter     */
Rect emptyRect   = { 33, 30, 41, 330 };    /* rect to clear % type done     */
Rect fileRect    = { 57, 28, 67, 332 };    /* rect to % file done meter     */
Rect cancelRect  = { 5, 258, 18, 338 };    /* rect for the cancel button    */

GrafPortPtr dlogWinPtr;                    /* ptr to "dialog" window        */
GrafPortPtr savedPort;                     /* make sure we restore life...  */

NewWindow2Template dlogTmplt = {           /* window template for fake dlg  */
   0x50, 0x2020, 0L, 0L, 0, 0, 0, 0, 0L, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0L, 0, 0L, 0L, 0L, 48, 140, 120, 500, -1L, 0L, 0 };
                         /*  ^----^----^----^- window = 76 H x 342 W center */

CtlRecHndl cancelHandle;                   /* control handle for cancel     */

SimpleButtonTemplate CancelButt = {        /* control template              */
   7, CancelID, 5, 258, 18, 338, 0x80000000L, 0, 0x1000, 0L, (Ref) "\pStop" };

int errorCounter, flag;
long    TB_offset;
char    space[] = "                                                  ";

int update(word currResType,        /* res type being processed         */
           long currResID,          /* res ID     "       "             */
           int  typeCount,          /* total # types in the file        */
           int  itemCount,          /* total # items for above type     */
           int  typeNum,            /* curr type # 1..                  */
           int  itemNum,            /* curr item # 1.. of above type    */
           int  updateCommand,      /* type of update to perform        */
           long *eTable,
           long ePointer)
{
    char *cp;
    int Hit;
    Point tempPoint;
    switch(updateCommand) {
    case SetUpShop:                     /* get ready to generate!       */
        flag = itemNum;                 /* $0000 source, $8000 equates  */
        errorCounter = 0;               /* init errors allowed ctr      */
        savedPort = GetPort();          /* save to restore later        */
        WaitCursor();                   /* load templates, etc...       */
        dlogWinPtr = NewWindow2(0L, 0L, 0L, 0L, 0, &dlogTmplt, 0x800E);
        SetPort(dlogWinPtr);            /* ensure drawing in our window */
        MoveTo(19, 15);                 /* draw main prompt             */
        DrawCString("Preparing data...");
        break;

    case InitDialog:                    /* call up "fake" dialog        */
        EraseRect(&clearRect);
        SetPenSize(5, 2);               /* frame inside outline         */
        MoveTo(19, 15);                 /* draw main prompt             */
        if (flag == 0)
            DrawCString("Generating source...");
        else
            DrawCString("Generating equates...");
        cancelHandle = NewControl2(dlogWinPtr, 0, &CancelButt);
        ShowControl(cancelHandle);
        DrawControls(dlogWinPtr);
        SetPenSize(2, 1);               /* do the % types stuff         */
        FrameRect(&typesRect);
        FrameRect(&fileRect);
        PenNormal();
        MoveTo(19, 55);
        DrawCString("Total file");     /* filename prompt              */
        break;

    case NewResType:
        MoveTo(19, 30);
        cp = get_name(currResType,0);
        DrawCString(cp);
        DrawCString(&space[strlen(cp)]);
        EraseRect(&emptyRect);
        TB_offset = 0;
        break;

    case NewResItem:
        TB_offset = (300 * (itemNum - 1)) / itemCount;
        break;

    case ItemComplete:
        ThermoBar(33, (word) (300*itemNum)/itemCount);
        ThermoBar(58, (word) ((300*(typeNum-1))/typeCount)+
                             (((300*itemNum)/typeCount)/itemCount));
        break;

    case ProcessDone:                       /* done with code generation*/
        CloseWindow(dlogWinPtr);            /* close up the fucker!     */
        SetPort(savedPort);                 /* restore original port    */
        InitCursor();                       /* restore cursor           */
        break;

    case UserAbort:                         /* user requested abort!    */

           /********** SHOULD DO ALERT WINDOW CALL HERE!!!! **********/

        return -2;                          /* tell engine to abort!    */

    case ProcessError:                       /* engine reports error!    */

           /********** CALL UP ALERT WINDOW WITH OK BUTTON *************/

        errorCounter++;
        if (errorCounter > ErrorThreshold)
            return -2;

    case NullUpdate:
        Hit = 0;
        while (Button(0)) {
            GetMouse(&tempPoint);
            if (PtInRect(&tempPoint, &cancelRect)) {
                if (Hit == 0) {
                    HiliteControl(1, cancelHandle);
                    Hit = -1;
                }
            }
            else {
                if (Hit == -1) {
                    HiliteControl(0, cancelHandle);
                    Hit = 0;
                }
            }
        }
        if (Hit == -1) {
            HiliteControl(0, cancelHandle);
            InitCursor();
            return -1;
        }
        break;

    case ReadUpdate:
        ThermoBar(33, (word)
            (((300/eTable[18])*(ePointer-eTable[11]))/eTable[12])+TB_offset);
        break;

    case HeadUpdate:
        MoveTo(19, 30);
        DrawCString("Writing output header                             ");
        break;

    case TailUpdate:
        EraseRect(&typesRect);
        MoveTo(19, 30);
        DrawCString("Generation complete                               ");
        MoveTo(19, 39);
        DrawCString("Please stand by...                                ");
        ThermoBar(58, 300);
        break;

    default:
        break;
    } /* switch */
   return 0;                                /* tell engine all is OK    */

} /* update function */

void ThermoBar(word top, word left_300)
{
    Rect    redRect;

    left_300 = (left_300 < 300) ? left_300 : 300; /* fix for random calc bug */

    SetRect(&redRect, 30, top, 30 + left_300, top + 8);
    SpecialRect(&redRect, 0x4444, 0x4444);

}
