/*
    module: misc.cc - real global data and misc Genesys routines in ORCA/C.
    author: Marc Wolfgram
      date: 10March90
*/
#include "genesys.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <types.h>
#include <quickdraw.h>
#include <qdaux.h>
#include <control.h>
#include <lineedit.h>
#include <list.h>
#include <gsos.h>
#include <intmath.h>
#include <memory.h>
#include <resources.h>
#include <window.h>
#include <usrlib.h>
#include "smurf.h"

GrafPortPtr FindEdWin(word, long);
int   DelItem(Word, long);
char *get_label(Word, long, int);
char *get_name(word, int);
void  rebuildType(void);
void  refreshType(word);
void  rebuildItem(word, word);
void  refreshItem(long);
int   saveNames(word);
long  SetResAccess(word, word);
word  EndResAccess(long);
void  shError(int, int);
int   toolerror(void);
void  AddChild(word, long);
int   jsl_Editor(void);
int   SetPrefs(void);
ResDepRecHndl Dependents(word, word, long, ResDepRecHndl);

extern GrafPortPtr RootWPtr;
extern Smurf SMURF;
extern char aParams[3][TMAX];
extern int ResFileID, ImportDefType, MasterID, GenFileID;
extern int ChangedFlag, RHidingFlag, CoordOnFlag, XHairOnFlag, NewFileFlag;
extern long attrCtrl, DrawProc, EditAttrWin, Params[3];
extern struct iCtlRec **ItemHandle;

/*****************************************************************************
 * RefConSetup is called to determine what the window's Resource Type and ID
 * for subsequent editor dispatching.  It is based on Kevin's "GetWRefCon"
 * assembly code (but is less obtuse).
 *
 * The return value is the winKind field or -1 if the window wasn't ours.
 *****************************************************************************/
int RefConSetup(GrafPortPtr fwPtr)
{
    int         rv;
    Word    rt;
    long        ri;
    WRefConHndl fwHndl;

    rv = -1;
    rt = 0;
    ri = 0L;

    if (fwPtr) {
        if (GetSysWFlag(fwPtr) == 0) {
            fwHndl = (WRefConHndl) GetWRefCon(fwPtr);
            shError(toolerror(), 0x9302);
            if ((**fwHndl).winResType != 0) {
                rt = (**fwHndl).winResType;
                ri = (**fwHndl).winResID;
            }
            rv = (**fwHndl).winKind;
        }
    }
    SMURF.ResourceType = rt;
    SMURF.ResourceID = ri;
    return rv;
}

word bitFlags[] = { 0x100, 0x200, 0x300, 0x4000, 0x800,
                    0x80, 0x40, 0x10, 0x8, 0x4, 0x8000 };

char nameTextI[IMAX], nameTextO[IMAX], TypeText[5], IDText[9];

/*****************************************************************************
 * EditAttr(rType, rID)
 *****************************************************************************/
int EditAttr(Word rType, long rID)
{
    int ctl, rAttr, rDepth, tCode, rPurge, nameLen;
    int i, j, LEnameHit, LEidHit, result, Done;
    long iCount, oID, rav;
    GrafPortPtr dWin, pWin, tempW;
    EventRecord tmRec;
    Rect dRect;
    Handle      tempHandle, tempLEHan, idHan;
    CtlRecHndl  tempCtlHandle;

    tmRec.wmTaskMask = 0x1B2006L;

    Done = LEnameHit = LEidHit = FALSE;

    rav = SetResAccess(ResFileID, 1) ;
    rAttr = GetResourceAttr(rType, rID);
    shError(toolerror(), 0x9004);
    iCount = CountResources(rType);
    EndResAccess(rav);

    pWin = GetPort();

    Int2Hex(rType, TypeText, 4);

    Long2Hex(rID, IDText, 8);

    strncpy(nameTextI, get_label(rType, rID, 0), IMAX-1);

    dWin = NewWindow2(NULL, NULL, &DrawProc, NULL, 2, 0xffeL, 0x800e);
    shError(toolerror(), 0x9006);
    SetPort(dWin);

    tempCtlHandle = GetCtlHandleFromID(dWin, 4L);
    tempLEHan = (Handle)(**tempCtlHandle).ctlData;
    LESetText(&IDText[0], 8, tempLEHan);

    tempCtlHandle = GetCtlHandleFromID(dWin, 3L);
    tempLEHan = (Handle)(**tempCtlHandle).ctlData;
    nameLen = strlen(nameTextI);
    LESetText(nameTextI, nameLen, tempLEHan);
    LESetSelect(0, nameLen, tempLEHan);

    rPurge = rAttr & 0x0300;
    if (rPurge == 0x0000)
        SetCtlValue(1,GetCtlHandleFromID(dWin, 0x05L));
    else if (rPurge == 0x0100)
        SetCtlValue(1,GetCtlHandleFromID(dWin, 0x06L));
    else if (rPurge == 0x0200)
        SetCtlValue(1,GetCtlHandleFromID(dWin, 0x07L));
    else
        SetCtlValue(1,GetCtlHandleFromID(dWin, 0x08L));

    for (ctl = 9;  ctl < 17; ctl++)
        if (rAttr & bitFlags[ctl-6])
            SetCtlValue(1,GetCtlHandleFromID(dWin, (long) ctl));


    do {
        tCode = TaskMaster(0xffff, &tmRec);
        if (tCode == activateEvt) {
            MoveTo(136, 18);
            DrawText(TypeText, 4);
        }
        else if (tCode == wInDrag) {
            SetRect(&dRect, 0, 0, 639, 199);
            DragWindow(0,tmRec.where.h,tmRec.where.v,8,&dRect,tmRec.wmTaskData);
            shError(toolerror(), 0x9020);
        }
        else if (tCode == wInControl) {
            if (tmRec.wmTaskData4 == 0x01L) { /* ok button */
                Done = TRUE;
                rAttr = 0;

                for (ctl = 6; ctl < 17; ctl++) {
                    if (GetCtlValue(GetCtlHandleFromID(dWin, (long) ctl))) {
                        rAttr |= bitFlags[ctl-6];
                        ChangedFlag = -1;
                    }
                }
                if (LEidHit == TRUE) {
                    tempCtlHandle = GetCtlHandleFromID(dWin, 4L);
                    tempLEHan = (Handle)(**tempCtlHandle).ctlData;
                    tempHandle = LEGetTextHand(tempLEHan);
                    j = LEGetTextLen(tempLEHan);
                    oID = Hex2Long(*tempHandle, j);

                    if (rID != oID) {
                        if (oID==0L || oID&0xf8000000L || toolerror()!=0) {
                            result = AlertWindow(4, Params, 21L);
                            Done = LEidHit = FALSE;
                        }

                        else if (tempW = FindEdWin(rType, rID)) {
                            result = AlertWindow(4, Params, 20L);
                            Done = LEidHit = FALSE;
                        }

                        else {
                            for (i = 0; i < (int) iCount; i++) {
                                if ((**ItemHandle).ctlList[i].rID == oID) {
                                    strcpy(aParams[0], get_name(rType, 0));
                                    sprintf(aParams[1], "%0.8lX", oID);
                                    result = AlertWindow(4, Params, 19L);
                                    Done = LEidHit = FALSE;
                                    break;
                                }
                            }
                        }

                        if (LEidHit == TRUE) {

                            result = AlertWindow(4, Params, 16L);
                            if (result)  {
                                SetCurResourceFile(ResFileID);
                                shError(toolerror(), 0x9032);
                                rDepth = SetResourceFileDepth(1);
                                shError(toolerror(), 0x9033);
                                SetResourceAttr(0, rType, rID);
                                shError(toolerror(), 0x9034);
                                idHan = LoadResource(rType, rID);
                                shError(toolerror(), 0x9035);
                                DetachResource(rType, rID);
                                HLock(idHan);
                                AddResource(idHan, 0, rType, oID);
                                shError(toolerror(), 0x9038);
                                WriteResource(rType, oID);
                                shError(toolerror(), 0x9039);
                                RemoveResource(rType, rID);
                                shError(toolerror(), 0x903A);

                                for (i = 0; i < (int) iCount; i++) {
                                    if ((**ItemHandle).ctlList[i].rID == rID) {
                                        ((**ItemHandle).ctlList[i].rID = oID);
                                        rID = oID;
                                        break;
                                    }
                                }
                            }
                            else {
                                Done = LEidHit = FALSE;
                            }
                        }
                        if (LEidHit == FALSE) {
                            Long2Hex(rID, IDText, 8);
                            LESetText(&IDText[0], 8, tempLEHan);
                            dRect.v1 = (**tempCtlHandle).ctlRect.v1;
                            dRect.h1 = (**tempCtlHandle).ctlRect.h1;
                            dRect.v2 = (**tempCtlHandle).ctlRect.v2;
                            dRect.h2 = (**tempCtlHandle).ctlRect.h2;
                            InvalRect(&dRect);
                        }
                    }
                }

                if (LEnameHit == TRUE && Done == TRUE) {
                    tempCtlHandle = GetCtlHandleFromID(dWin, 3L);
                    tempLEHan = (Handle)(**tempCtlHandle).ctlData;
                    tempHandle = LEGetTextHand(tempLEHan);
                    j = LEGetTextLen(tempLEHan);
                    strncpy(nameTextO, *tempHandle, j);
                    nameTextO[j] = 0x00;
                    if (strcmp(nameTextI, nameTextO) != 0) {
                        pstrcpy(nameTextO, c2pstr(nameTextO));

                        for (i = 0; i < (int) iCount; i++) {
                            if ((**ItemHandle).ctlList[i].rID == rID)
                                continue;

                            if (pstrucmp((**ItemHandle).ctlList[i].text,
                                nameTextO) == 0) {

                                strcpy(aParams[0], get_name(rType, 0));
                                strcpy(aParams[1], p2cstr(nameTextO));
                                result = AlertWindow(4, Params, 18L);

                                Done = LEnameHit = FALSE;
                                break;
                            }
                        }

                        if (LEnameHit == TRUE) {
                            for (i = 0; i < (int) iCount; i++) {
                                if ((**ItemHandle).ctlList[i].rID == rID) {
                                    (**ItemHandle).ctlList[i].alias = 1;
                                    pstrcpy((**ItemHandle).ctlList[i].text,
                                        nameTextO);
                                    break;
                                }
                            }
                        }
                    }
                }

                if (Done) {
                    if (LEnameHit == TRUE || LEidHit == TRUE) {
                        saveNames(rType);
                        rebuildType();
                        refreshType(rType);
                        rebuildItem(rType, 0);
                        refreshItem(rID);
                        ChangedFlag = -1;
                    }
                    rav = SetResAccess(ResFileID, 1);
                    SetResourceAttr(rAttr, rType, rID);
                    shError(toolerror(), 0x9044);
                    EndResAccess(rav);
                }
            }
            else if (tmRec.wmTaskData4 == 0x02) /* cancel button */
                Done = TRUE;

            else if (tmRec.wmTaskData4 == 0x03) /* name line edit */
                LEnameHit = TRUE;

            else if (tmRec.wmTaskData4 == 0x04) /* id line edit */
                LEidHit = TRUE;

        }
    } while(!Done);

    CloseWindow(dWin);
    shError(toolerror(), 0x9050);
    SetPort(pWin);
    return 0;
}

/*****************************************************************************
 * EditKill(rType, rID)
 *****************************************************************************/
int EditKill(word rType, long rID)
{
    int result, rDepth, i;
    long rav;
    GrafPortPtr tempW;
    ResDepRecPntr depPntr;
    ResDepRecHndl depHndl;
    DepChild *ChildPntr;

    tempW = FindEdWin(rType, rID);

    if (tempW)
        result = AlertWindow(4, NULL, 9L);
    else {
        depHndl = Dependents(ResFileID, rType, rID, (ResDepRecHndl) 0L);
        HLock(depHndl);
        depPntr = *depHndl;
        i = depPntr->Count;

        if (i == 1)
            result = AlertWindow(4, NULL, 23L);
        else
            result = AlertWindow(4, NULL, 10L);
    }
    if (result != 0) {
        rav = SetResAccess(ResFileID, 1) ;
        if (result == 1) {
            RemoveResource(rType, rID);
            shError(toolerror(), 0x9104);
            DelItem((Word) rType, rID);
        }
        else if (result == 2) {
            while (i > 0) {
                ChildPntr = &(depPntr->Child[--i]);
                rType = ChildPntr->rType;
                rID = ChildPntr->rID;
                tempW = FindEdWin(rType, rID);
                if (tempW) {
                    BringToFront(tempW);
                    RefConSetup(tempW);
                    SMURF.EditCommand = 4;  /* shutdown */
                    jsl_Editor();
                }
                SetResAccess(ResFileID, 1);
                RemoveResource(rType, rID);
                DelItem((Word) rType, rID);
            }
        }
        ChangedFlag = -1;
        EndResAccess(rav);
        HUnlock(depHndl);
        DisposeHandle(depHndl);
    }
    return result;
}

/*****************************************************************************
 * CheckAttrWP(rType, rID)
 *****************************************************************************/
int CheckAttrWP(Word rType, long rID)
{
    int rAttr, rDepth;
    long rav;

    rav = SetResAccess(ResFileID, 1);
    rAttr = GetResourceAttr(rType, rID);
    shError(toolerror(), 0x9204);
    if (rAttr & 0x80) {
        SetResAccess(GenFileID, -1);
        if (AlertWindow(4, NULL, 8L) == 0)
            return -1;
        rAttr &= 0xff7f;
        rav = SetResAccess(ResFileID, 1);
        SetResourceAttr(rAttr, rType, rID);
        shError(toolerror(), 0x9214);
    }
    EndResAccess(rav);
    return 0;
}

/*****************************************************************************
 * FatalStart()    ...Thanks to Doni Grande!
 *****************************************************************************/
void FatalStart(void)
{
 GrafOff();
 puts("A fatal error occurred while starting Genesys.\nPress RETURN to exit: ");
 getchar();
}

/*****************************************************************************
 * ImportRez(GSString255Ptr, GSString32Ptr)
 *****************************************************************************/
int ImportRez(GSString255Ptr file, GSString32Ptr name)
{
    char        cType[4], cAuxT[6], cSize[12], cSizeEnd, TypeText[4];
    int         rDepth, Done, result, tCode, impType;
    long        impID, rav;
    Rect        dRect;
    Handle      tempHandle, tempLEHan, impH;
    CtlRecHndl  tempCtlHandle;
    EventRecord tmRec;
    GrafPortPtr dWin, pWin;

    FileInfoRecGS   impGetInfo = { 9, file, 1 };
    OpenRecGS       impOpen = { 2, 0, file };
    IORecGS         impRead;

    tmRec.wmTaskMask = 0x1B2006L;

    Done = FALSE;
    result = 0;

    pWin = GetPort();

    GetFileInfoGS(&impGetInfo);
    shError(toolerror(), 0x9E02);

    cSizeEnd = (impGetInfo.eof == 1L) ? ' ' : 's';
    sprintf(cType, "$%0.2X", impGetInfo.fileType);
    sprintf(cAuxT, "$%0.4lX", impGetInfo.auxType);
    sprintf(cSize, "%lu byte%c", impGetInfo.eof, cSizeEnd);

    Int2Hex(ImportDefType, TypeText, 4);

    dWin = NewWindow2(NULL, NULL, &DrawProc, NULL, 2, 0xffcL, 0x800e);
    shError(toolerror(), 0x9E04);
    SetPort(dWin);

    tempCtlHandle = GetCtlHandleFromID(dWin, 3L);
    tempLEHan = (Handle)(**tempCtlHandle).ctlData;
    LESetText(TypeText, 4, tempLEHan);
    LESetSelect(0, 4, tempLEHan);

    do {
        tCode = TaskMaster(0xffff, &tmRec);
        if (tCode == wInDrag) {
            SetRect(&dRect, 0, 0, 639, 199);
            DragWindow(0,tmRec.where.h,tmRec.where.v,8,&dRect,tmRec.wmTaskData);
        }
        else if (tCode == wInControl) {
            if (tmRec.wmTaskData4 == 0x01L) { /* ok button */
                Done = TRUE;

                tempCtlHandle = GetCtlHandleFromID(dWin, 3L);
                tempLEHan = (Handle)(**tempCtlHandle).ctlData;
                tempHandle = LEGetTextHand(tempLEHan);
                impType = Hex2Int(*tempHandle, LEGetTextLen(tempLEHan));

                if (impType == 0 || toolerror()!=0) {
                    result = AlertWindow(4, Params, 22L);
                    Int2Hex(ImportDefType, TypeText, 4);
                    LESetText(&TypeText[0], 4, tempLEHan);
                    LESetSelect(0, 4, tempLEHan);
                    dRect.v1 = (**tempCtlHandle).ctlRect.v1;
                    dRect.h1 = (**tempCtlHandle).ctlRect.h1;
                    dRect.v2 = (**tempCtlHandle).ctlRect.v2;
                    dRect.h2 = (**tempCtlHandle).ctlRect.h2;
                    InvalRect(&dRect);
                    tCode = activateEvt;  /* force redraw of the file text */
                    Done = FALSE;
                }
                else {
                    WaitCursor();
                    ImportDefType = impType;
                    impH = NewHandle(impGetInfo.eof, MasterID, 0xc018, 0L);
                    result = toolerror();
                    if (result == 0) {
                        HLock(impH);

                        OpenGS(&impOpen);
                        shError(toolerror(), 0x9E30);

                        impRead.pCount = 4;
                        impRead.refNum = impOpen.refNum;
                        impRead.dataBuffer = (Pointer) *impH;
                        impRead.requestCount = impGetInfo.eof;
                        ReadGS(&impRead);
                        shError(toolerror(), 0x9E31);

                        impRead.pCount = 1;
                        CloseGS(&impRead);
                        shError(toolerror(), 0x9E32);

                        rav = SetResAccess(ResFileID, 1);

                        impID = UniqueResourceID(-1, impType);
                        shError(toolerror(), 0x9E42);
                        AddResource(impH, 0, impType, impID);
                        shError(toolerror(), 0x9E43);
                        WriteResource(impType, impID);
                        shError(toolerror(), 0x9E44);
                        ReleaseResource(-1, impType, impID);
                        shError(toolerror(), 0x9E45);

                        rebuildType();
                        refreshType(impType);
                        rebuildItem(impType, 0);
                        refreshItem(impID);

                        EndResAccess(rav);
                        ChangedFlag = -1;
                    }
                }
            }
            else if (tmRec.wmTaskData4 == 0x02) /* cancel button */
                Done = TRUE;
        }
        if (tCode == activateEvt) {
            MoveTo(106, 12);
            DrawText(name->text, name->length);
            MoveTo(106, 21);
            DrawCString(cType);
            MoveTo(106, 30);
            DrawCString(cAuxT);
            MoveTo(106, 39);
            DrawCString(cSize);
        }
    } while(!Done);

    CloseWindow(dWin);
    shError(toolerror(), 0x9E50);
    SetPort(pWin);
    InitCursor();
    return result;
}

/*****************************************************************************
 * ExportRez(GSString255Ptr, Word, long)
 *****************************************************************************/
int ExportRez(GSString255Ptr path, Word rType, long rID)
{
    int result, rAttr;
    long rav;
    Handle expH;

    NameRecGS   expDestroy  = {1, path};
    CreateRecGS expCreate   = {4, path, 0xc3, 0x06, 0L};
    OpenRecGS   expOpen = {3, 0, path, 3};
    IORecGS     expWrite;

    WaitCursor();

    rav = SetResAccess(ResFileID, 1);
    rAttr = GetResourceAttr(rType, rID);
    shError(toolerror(), 0x9F04);
    SetResourceAttr(0, rType, rID);
    shError(toolerror(), 0x9F05);

    expH = LoadResource(rType, rID);
    result = toolerror();

    SetResourceAttr(rAttr, rType, rID);
    shError(toolerror(), 0x9F07);

    EndResAccess(rav);

    if (result == 0) {
        DetachResource(rType, rID);
        HLock(expH);

        DestroyGS(&expDestroy);
        CreateGS(&expCreate);
        if ((result = toolerror()) == 0) {

            OpenGS(&expOpen);
            shError(toolerror(), 0x9F10);

            expWrite.pCount = 4;
            expWrite.refNum = expOpen.refNum;
            expWrite.dataBuffer = (Pointer) *expH;
            expWrite.requestCount = GetHandleSize(expH);
            WriteGS(&expWrite);
            shError(toolerror(), 0x9F20);

            expWrite.pCount = 1;
            CloseGS(&expWrite);
        }
    }

    DisposeHandle(expH);
    InitCursor();
    return result;
}

GSString32 ExportName32;

/*****************************************************************************
 * ExportName(Word, long)
 *****************************************************************************/
Pointer ExportName(Word rType, long rID)
{
    strncpy(ExportName32.text, get_label(rType, rID, 0x2e), 15);
    ExportName32.text[15] = 0x00;
    ExportName32.length = strlen(ExportName32.text);
    return (Pointer) &ExportName32;
}

int SetPrefs(void)
{

    return 0;

}
