/***********************************************\
*                                               *
*                     Snap                      *
*          Mikael Karlsson 1988-1991           *
*                                               *
\***********************************************/
/* Auto: make "CCEXTRA=-wq -qf"
*/

#ifdef SNAPREXX
#include "minrexx.h"
#endif SNAPREXX
#include <stdio.h>

#define ARGVAL() ((*argv && *++(*argv)) || (--argc && *++argv))

static char Version[] = "$VER: 1.61  1991 Mikael Karlsson & Absolut Software\n";

BOOL Kick36;

/* signals */
LONGBITS startsignal, insertsignal, cancelsignal;
LONGBITS donesignal, movesignal, clicksignal;
LONGBITS timersignal, initsignal, cwsignal, ticksignal;
ULONG startsignum = -1L;
ULONG insertsignum = -1L;
ULONG cancelsignum = -1L;
ULONG donesignum = -1L;
ULONG movesignum = -1L;
ULONG clicksignum = -1L;
ULONG initsignum = -1L;
ULONG cwsignum = -1L;
ULONG ticksignum = -1L;
ULONG WaitSignal;

/* program */
struct SnapRsrc *SnapRsrc = NULL;
struct Task *MyTask;

/* Snap state machine */
WORD action;
WORD state;

/* clipboard */
struct IOClipReq *ClipReq = NULL;
struct MsgPort *ClipPort = NULL;

/* timer device */
struct MsgPort *TimerPort = NULL;
struct timerequest MyTR;

/* input device */
struct MsgPort *inputDevPort = NULL;
struct Interrupt handlerStuff;
struct IOStdReq *inputRequestBlock = NULL;
struct InputEvent SimEvent;
WORD textqual;
WORD gfxqual;
WORD insertkey;
WORD cwkey;
WORD modinsert;

UBYTE *CharData = NULL;
UBYTE TrueUnderscore;

/* console */
struct MsgPort *ConPort = NULL;
struct IOStdReq *ConIOR = NULL;
struct KeyMap keymap;

/* windows */
#ifdef SNAPGFX
struct MsgPort *Sharedport = NULL;
SHORT Sharedrefs;
IMPORT struct Window *ControlWindow;
struct Window *SaveWin = NULL;
IMPORT struct Gadget SaveGad;
IMPORT struct Gadget NameGad;
struct GfxSnap *SwapGS = NULL;
IMPORT struct StringInfo TranspSI;
IMPORT struct Image ActiveDiskImage;
IMPORT struct Image InactiveDiskImage;
IMPORT struct Image ActiveClipImage;
IMPORT struct Image InactiveClipImage;
#endif SNAPGFX
IMPORT UBYTE *WindowTitle;

/* libraries */
IMPORT struct ExecBase *SysBase;
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase       *GfxBase = NULL;
struct LayersBase    *LayersBase = NULL;
struct DiskFontBase  *DiskfontBase = NULL;
struct Library       *IconBase = NULL;
#ifdef SNAPGFX
#ifdef REQLIB
struct ReqBase       *ReqBase = NULL;
#endif REQLIB
#ifdef ASLLIB
struct Library       *AslBase = NULL;
#endif ASLLIB
#endif SNAPGFX

/* graphics */
struct Screen *theScreen;
struct Layer *theLayer;
struct RastPort rp, TempRp, MyRP;
struct BitMap TempBM, MyBM;
UBYTE *TempRaster = NULL;

#ifdef SNAPGFX
#ifdef REQLIB
struct ReqFileRequester *NameFR = NULL;
#endif REQLIB
#ifdef ASLLIB
struct FileRequester *AslNameFR = NULL;
#endif ASLLIB
char SaveName[DSIZE+FCHARS+2];
BPTR SnapFile;
#endif SNAPGFX

/* ARexx stuff */
#ifdef SNAPREXX
ULONG rexxsignal;
IMPORT struct rexxCommandList rcl[];
WORD disp();
#endif SNAPREXX

#ifdef AZTEC_C
int stricmp(char *s1, char *s2 )
{
   char c1, c2;

   while (*s1 && *s2) {
      if ((c1 = *(s1++)) >= 'a' && c1 <= 'z') {
         c1 -= 32;
      }
      if ((c2 = *(s2++)) >= 'a' && c2 <= 'z') {
         c2 -= 32;
      }

      if ( c1 != c2 ) {
         return( c1 - c2 );
      }
   }

   return( *s1 - *s2 );
}


int strnicmp(char *s1, char *s2, int n)
{
   char c1, c2;

   while (*s1 && *s2 && --n > 0) {
      c1 = *(s1++);
      c2 = *(s2++);

      if (c1 >= 'a' && c1 <= 'z') {
         c1 -= 32;
      }
      if (c2 >= 'a' && c2 <= 'z') {
         c2 -= 32;
      }

      if (c1 != c2) {
         return(c1 - c2);
      }
   }

   c1 = *s1;
   c2 = *s2;

   if (c1 >= 'a' && c1 <= 'z') {
      c1 -= 32;
   }
   if (c2 >= 'a' && c2 <= 'z') {
      c2 -= 32;
   }

   return(c1 - c2);
}
#endif

LONG dectoint(REGISTER char *str)
{
    REGISTER long val = 0;
    REGISTER char c;
    while ((c = *str) >= '0' && c <= '9') {
        val = (((val<<2)+val)<<1) + c-'0';
        str++;
    }
    return(val);
}

LONG hextoint(REGISTER char *str)
{
    REGISTER long val = 0;
    REGISTER char c;

    if (!strnicmp(str, "0x", 2)) {
        str += 2;
    }
    while (c = *str) {
        val <<= 4;
        val |= (c & 15) + ((c>='0' && c<='9') ? 0 : 9);
        str++;
    }
    return(val);
}

WORD insertcount;

VOID InsertAscii(ULONG ascii)
{
    if (insertcount == 1) {   /* Time for second char */
          /* Not necessary to patch here but it guarantees
             that all inserted chars end up in the same window. */
        SafePatch();
    }
    if (AsciiToInputEvent(ascii, &SimEvent, &keymap)) {
        DoIO((struct IORequest *)inputRequestBlock);
        if (SnapRsrc->chardelay) {
            MyTR.tr_node.io_Command = TR_ADDREQUEST;
            MyTR.tr_time.tv_micro = SnapRsrc->chardelay;
            MyTR.tr_time.tv_secs = 0;
            DoIO((struct IORequest *)&MyTR);
        }
    }
    ++insertcount;
}

#ifdef SNAPGFX
VOID GadText(struct Gadget *Gad, char *Str, LONG Len)
{
    char temp[256];
    SHORT i;

    SetDrMd(ControlWindow->RPort, JAM2);
    SetAPen(ControlWindow->RPort, 0L);
    RectFill(ControlWindow->RPort, (LONG)Gad->LeftEdge, (LONG)Gad->TopEdge,
      (LONG)Gad->LeftEdge + Gad->Width - 1, (LONG)Gad->TopEdge + Gad->Height - 1);
    SetAPen(ControlWindow->RPort, 1L);
    SetBPen(ControlWindow->RPort, 0L);
    Move(ControlWindow->RPort,
      (LONG)Gad->LeftEdge + 1,
      (LONG)Gad->TopEdge + ControlWindow->RPort->Font->tf_Baseline + 1);
    if (TextLength(ControlWindow->RPort, Str, Len) > Gad->Width) {
        i = Len;
        strncpy(temp, Str, i - 3);
        strcat(temp, "...");
        while (TextLength(ControlWindow->RPort, temp, (LONG)i) > Gad->Width) {
            --i;
            temp[i] = '\0';
            temp[i-3] = '.';
        }
        Text(ControlWindow->RPort, temp, (LONG)i);
    } else {
        Text(ControlWindow->RPort, Str, Len);
    }
}

VOID SwapColorMap(struct GfxSnap *GS)
{
    struct ViewPort *vp = &GS->window->WScreen->ViewPort;
    LONG i = (GS->viewmode & HAM ? 16 : 1L << GS->depth);
    ULONG col;

    while (i-- && (col = GetRGB4(vp->ColorMap, i)) != -1L) {
        SetRGB4(vp, i,
          (LONG)GS->rgb[i][0] >> 4,
          (LONG)GS->rgb[i][1] >> 4,
          (LONG)GS->rgb[i][2] >> 4);
        GS->rgb[i][0] = ((col >> 8) & 0x0f) << 4;
        GS->rgb[i][1] = ((col >> 4) & 0x0f) << 4;
        GS->rgb[i][2] = ((col >> 0) & 0x0f) << 4;
    }
}

VOID CheckWindowMsgs()
{
    struct IntuiMessage *Msg;
    struct IntuiMessage *QdMsg = NULL;
    ULONG Class;
    USHORT Code;
    struct Window *Win;
    struct Gadget *Gad;

    while (Sharedport &&
      (QdMsg || (Msg = (struct IntuiMessage *)GetMsg(Sharedport)))) {
        if (QdMsg) {
            Msg = QdMsg;
            QdMsg = NULL;
        }
        Class = Msg->Class;
        Code  = Msg->Code;
        Win   = Msg->IDCMPWindow;
        Gad   = (struct Gadget *)Msg->IAddress;
        ReplyMsg((struct Message *)Msg);
        switch (Class) {
            case CLOSEWINDOW: {
                struct GfxSnap *GS = NULL;
                if (Win == ControlWindow) {
                    ControlWindow = NULL;
                    if (SaveWin) {
                        SetWindowTitles(SaveWin, (char *)WindowTitle, (char *)-1);
                        SaveWin = NULL;
                    }
                } else {
                    GS = (struct GfxSnap *)Win->UserData;
                    FreePlanes(&GS->BM, GS->width, GS->height);
                    if (Win == SaveWin || Sharedrefs == 1) {
                        if (ControlWindow) {
                            OffGadget(&SaveGad, ControlWindow, NULL);
                        }
                        SaveWin = NULL;
                    }
                }
                closesharedwindow(Win);
                if (GS) {
                    Kill(GS);
                }
                break;
            }
            case NEWSIZE: {
                AdjustSize((struct GfxSnap *)Win->UserData);
                break;
            }
            case MOUSEMOVE: {
                  /* Collapse all consecutively queued MOUSEMOVE msgs */
                while ((QdMsg = (struct IntuiMessage *)GetMsg(Sharedport))
                  && (QdMsg->Class == MOUSEMOVE)) {
                    ReplyMsg((struct Message *)QdMsg);
                }
                SyncGS((struct GfxSnap *)Win->UserData);
                break;
            }
            case REFRESHWINDOW: {
                BeginRefresh(Win);
                SyncGS((struct GfxSnap *)Win->UserData);
                EndRefresh(Win, 1L);
            }
            case INACTIVEWINDOW: {
                if (Win != ControlWindow) {
                    struct GfxSnap *GS;
                    GS = (struct GfxSnap *)Win->UserData;
                    if (SwapGS) {
                        SwapColorMap(SwapGS);
                        SwapGS = NULL;
                    }
                    GS->DiskGad.GadgetRender = (APTR)&InactiveDiskImage;
                    GS->ClipGad.GadgetRender = (APTR)&InactiveClipImage;
                    RefreshGList(&GS->DiskGad, GS->window, NULL, -1);
                }
                break;
            }
            case ACTIVEWINDOW: {
                if (Win != ControlWindow) {
                    struct GfxSnap *GS;
                    GS = (struct GfxSnap *)Win->UserData;
                    GS->DiskGad.GadgetRender = (APTR)&ActiveDiskImage;
                    GS->ClipGad.GadgetRender = (APTR)&ActiveClipImage;
                    RefreshGList(&GS->DiskGad, GS->window, NULL, -1);
                }
                break;
            }
            case GADGETUP: {
                switch (Gad->GadgetID) {
                    case VPROP:
                    case HPROP: {
                        SyncGS((struct GfxSnap *)Win->UserData);
                        break;
                    }
                    case SAVEGAD: {
savepic:
                        if (SaveWin) {
                            WORD success = 0;
                            struct GfxSnap *GS;
                            GS = (struct GfxSnap *)SaveWin->UserData;

                            if (SaveName[0] == '\0') {
                                DisplayBeep(NULL);
                                ActivateGadget(&NameGad, ControlWindow, NULL);
                                break;
                            }
                            SnapFile = (BPTR)Open((char *)SaveName, MODE_NEWFILE);
                            if (SnapFile) {
                                struct CBFHandle CBFH;
                                CBFH.Type = CBFFILE;
                                CBFH.Handle.File = SnapFile;
                                success = SaveGS(GS, &CBFH);
                                Close(SnapFile);
                            }
                            if (success) {
                                SetWindowTitles(ControlWindow, "Saved ok", (char *)-1);
                            } else {
                                DeleteFile((char *)SaveName);
                                DisplayBeep(NULL);
                                SetWindowTitles(ControlWindow, "Save failed", (char *)-1);
                            }
                        }
                        break;
                    }
                    case NAMEGAD: { /* Should only happen with Req */
#ifdef ASLLIB
                        if ((AslNameFR) && (Kick36)) {
                            if (RequestFile(AslNameFR)) {
                                strncpy(SaveName, AslNameFR->rf_Dir, sizeof(SaveName));
                                AddPart((UBYTE *)SaveName,
                                        (UBYTE *)AslNameFR->rf_File,
                                        sizeof(SaveName));
                            }
                            GadText(&NameGad, SaveName, (LONG)strlen(SaveName));
                        }
#else
                        if (0) {}
#endif ASLLIB
#ifdef REQLIB
                        else if (NameFR) {
                            NameFR->Title = "Save picture as...";
                            NameFR->PathName = SaveName;
                            NameFR->Window = ControlWindow;
                            (VOID)BruceFileRequester(NameFR);
                            GadText(&NameGad, SaveName, (LONG)strlen(SaveName));
                        }
#endif REQLIB
                        break;
                    }
                    case DISKGAD: {
                        struct GfxSnap *GS;
                        if (!ControlWindow && !OpenCW()) {
                            DisplayBeep(NULL);
                            break;
                        }
                        if (Win == SaveWin) {
                            goto savepic;
                        }
                        if (SaveWin) {
                            SetWindowTitles(SaveWin, (char *)WindowTitle, (char *)-1);
                            GS = (struct GfxSnap *)SaveWin->UserData;
                            RefreshGList(&GS->DiskGad, GS->window, NULL, 1L);
                        } else {
                            GadText(&SaveGad, "Save", 4L);
                            OnGadget(&SaveGad, ControlWindow, NULL);
                        }
                        SaveWin = Win;
                        SetWindowTitles(SaveWin, "Selected", (char *)-1);
                        GS = (struct GfxSnap *)SaveWin->UserData;
                        RefreshGList(&GS->DiskGad, GS->window, NULL, 1L);
                        break;
                    }
                    case CLIPGAD: {
                        struct CBFHandle CBFH;
                        struct GfxSnap *GS = (struct GfxSnap *)Win->UserData;

                        CBFH.Type = CBFCLIP;
                        CBFH.Handle.ClipReq = ClipReq;
                        if (!SaveGS(GS, &CBFH)) {
                            DisplayBeep(NULL);
                        }
                        break;
                    }
                    default: {
                        break;
                    }
                }
                break;
            }
            case MOUSEBUTTONS: {
                if (Win != ControlWindow) {
                    if (Code == SELECTDOWN && !SwapGS) {
                        SwapGS = (struct GfxSnap *)Win->UserData;
                        SwapColorMap(SwapGS);
                    } else if (Code == SELECTUP && SwapGS) {
                        SwapColorMap(SwapGS);
                        SwapGS = NULL;
                    }
                }
                break;
            }
            default: {
                break;
            }
        }
    }
    if (QdMsg) {
        ReplyMsg((struct Message *)QdMsg);
    }
}
#endif SNAPGFX

#define WriteStr(str) fputs(str, stdout)
#define WriteChar(char) fputc(char, stdout)

struct QualPair {
    char *str;
    WORD val;
};

struct QualPair Qualifiers[] = {
    { "LSHIFT",    IEQUALIFIER_LSHIFT },
    { "RSHIFT",    IEQUALIFIER_RSHIFT },
    { "CONTROL",   IEQUALIFIER_CONTROL },
    { "LALT",      IEQUALIFIER_LALT },
    { "RALT",      IEQUALIFIER_RALT },
    { "LAMIGA",    IEQUALIFIER_LCOMMAND },
    { "RAMIGA",    IEQUALIFIER_RCOMMAND },
    { "MIDBUTTON", IEQUALIFIER_MIDBUTTON }
};

WORD ParseQual(char *quals)
{
    char *temp;
    WORD i;
    char oldc;
    WORD qual = 0;

    if (isdigit(*quals)) {
        return hextoint(quals);
    }

    while (*quals) {
        temp = quals;
        while ((oldc = *quals) && oldc != '+') {
            quals++;
        }
        *quals = 0;
        for (i = 0; i < (sizeof(Qualifiers) / sizeof(Qualifiers[0])); i++) {
            if (!stricmp(temp, Qualifiers[i].str)) {
                qual |= Qualifiers[i].val;
                break;
            }
        }
        if (*quals = oldc) {
            quals++;
        }
    }
    return qual;
}

WORD SetAltFont(char *str)
{
    struct TextAttr ta;
    struct TextFont *NewFont;
    char temp[33];
    WORD pos = 0;

    if (strlen(str) <= 32) {

        strcpy(temp, str);
        ta.ta_Name = (UBYTE *)temp;
        while (temp[pos] != '\0' && temp[pos] != '/') {
            ++pos;
        }
        if (temp[pos] == '\0') {     /* No size */
            ta.ta_YSize = 8;
        } else {
            temp[pos] = '\0';
            ta.ta_YSize = dectoint(&temp[pos + 1]);
        }
        if (pos > 5) {
            if (stricmp(&temp[pos - 5], ".font")) {
                strcpy(&temp[pos], ".font");
            }
        } else {
            strcpy(&temp[pos], ".font");
        }
        ta.ta_Style = 0;
        ta.ta_Flags = 0;
        NewFont = SmartOpenFont(&ta);
        if (NewFont) {
            if (SnapRsrc->AlternateFont) {
                CacheSync(SnapRsrc->AlternateFont);
                CloseFont(SnapRsrc->AlternateFont);
            }
            SnapRsrc->AlternateFont = NewFont;
        }
    }
    return (NewFont ? 1 : 0);
}

struct SnapRsrc DefaultRsrc = {
    { NULL, NULL, NT_RESOURCE, 0, SNAPRSRC },   /* Node */
    NULL,                                       /* Task */
    52,                                         /* Priority */
    IEQUALIFIER_RCOMMAND,                       /* Graphics qualifier */
    IEQUALIFIER_LCOMMAND,                       /* Text qualifier */
    0x17,                                       /* Insert key */
    0x11,                                       /* Control Window key */
    { '>', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Prepend */
    {   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Append */
    TRUEUNDERSCORE,                             /* Flags */
    0,                                          /* Char delay */
    0,                                          /* Line delay */
    0x7777,                                     /* Crawl pattern */
    UNIT_FRAME,                                 /* Starting unit */
    1,                                          /* Frame mask */
    '?',                                        /* Bad char */
    10,                                         /* Cache size */
    1,                                          /* Extra line spacing */
    { NULL, NULL, NULL },                       /* MinList, Cached windows */
    NULL                                        /* Alternate font */
};

#ifdef LATTICE
VOID main(int argc, char **argv)
#else
WORD main(int argc, char **argv)
#endif
{
    WORD create = 0, usage = 0;

#ifdef AZTEC_C
    Enable_Abort = 0;
#endif AZTEC_C

    Kick36 = (SysBase->LibNode.lib_Version >= 36 ? 1 : 0);

    if (!(SnapRsrc = (struct SnapRsrc *)OpenResource(SNAPRSRC))) {
        create = 1;
        SnapRsrc = Create(SnapRsrc);
        CopyMem((char *)&DefaultRsrc, (char *)SnapRsrc, sizeof(struct SnapRsrc));
        SnapRsrc->Task = FindTask(NULL);
        NewList((struct List *)&SnapRsrc->CachedWindows);
        AddResource((struct MiscResource *)SnapRsrc);
    }

      /* Open libraries since we might need them when parsing arguments */
    if (!OpenLibs()) {
        goto exitpoint;
    }

    if (!argc) {    /* WB Startup */
        if (!create) {     /* Second time from WB -- Remove Snap */
            Signal(SnapRsrc->Task, SIGBREAKF_CTRL_C);
            goto exitpoint;
        } else if (IconBase) {   /* Is it possible to be started from Workbench
                                    without icon.library being available. */
            BPTR olddir;
            struct WBStartup *wbstartup;
            struct DiskObject *diskobject;
            char *val;

            wbstartup = (struct WBStartup *)argv;
            olddir = CurrentDir(wbstartup->sm_ArgList[0].wa_Lock);
            diskobject = GetDiskObject(wbstartup->sm_ArgList[0].wa_Name);
            if (!diskobject) {
                goto skipargs;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "PRIORITY")) {
                WORD pri = dectoint(val);
                if (pri>50 && pri<128) {
                    SnapRsrc->Priority = pri;
                }
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "TEXTQUAL")) {
                SnapRsrc->textqual = ParseQual(val);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "GFXQUAL")) {
                SnapRsrc->gfxqual = ParseQual(val);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "INSERTKEY")) {
                SnapRsrc->insertkey = hextoint(val);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "CWKEY")) {
                SnapRsrc->cwkey = hextoint(val);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "APPEND")) {
                strncpy(&SnapRsrc->Append[0], val, 16);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "PREPEND")) {
                strncpy(&SnapRsrc->Prepend[0], val, 16);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "CHARDELAY")) {
                SnapRsrc->chardelay = dectoint(val);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "LINEDELAY")) {
                SnapRsrc->linedelay = dectoint(val) * 1000;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "CRAWLPTRN")) {
                SnapRsrc->CrawlPtrn = hextoint(val);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "XEROX")) {
                SnapRsrc->flags |= XEROX;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "NOXEROX")) {
                SnapRsrc->flags &= ~XEROX;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "EARLYPATCH")) {
                SnapRsrc->flags |= EARLYPATCH;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "NOEARLYPATCH")) {
                SnapRsrc->flags &= ~EARLYPATCH;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "STARTUNIT")) {
                if (*val == '1') {
                    SnapRsrc->StartUnit = UNIT_CHAR;
                } else {
                    SnapRsrc->StartUnit = UNIT_FRAME;
                }
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "TRUEUNDERSCORE")) {
                SnapRsrc->flags |= TRUEUNDERSCORE;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "FAKEUNDERSCORE")) {
                SnapRsrc->flags &= ~TRUEUNDERSCORE;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "JOINLONG")) {
                SnapRsrc->flags |= JOINLONG;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "NOJOINLONG")) {
                SnapRsrc->flags &= ~JOINLONG;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "SIMPLEREFRESH")) {
                SnapRsrc->flags |= SIMPLEREFRESH;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "SMARTREFRESH")) {
                SnapRsrc->flags &= ~SIMPLEREFRESH;
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "PLANEMASK")) {
                SnapRsrc->FrameMask = hextoint(val);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "CACHESIZE")) {
                SnapRsrc->CacheSize = dectoint(val);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "LEADING")) {
                SnapRsrc->Leading = dectoint(val);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "BADCHAR")) {
                SnapRsrc->BadChar = (*val ? *val : 0);
            }
            if (val = FindToolType(diskobject->do_ToolTypes, "ALTFONT")) {
                SetAltFont(val);
            }
            FreeDiskObject(diskobject);
            goto skipargs;
        }
    }

    if (create) {
        WriteStr("Snap");
        WriteStr(&Version[5]);
    }

    for (argc--, argv++; argc > 0; argc--, argv++) {
        if (**argv == '-') { /* Argument coming up */
            switch(*++(*argv)) {
                case 'p': priority: {  /* Priority */
                    if (ARGVAL()) {
                        WORD pri = dectoint(*argv);
                        if (pri>50 && pri<128) {
                            SnapRsrc->Priority = pri;
                        }
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 't': textqual: {
                    if (ARGVAL()) {
                        SnapRsrc->textqual = ParseQual(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
#ifdef SNAPGFX
                case 'g': gfxqual: {
                    if (ARGVAL()) {
                        SnapRsrc->gfxqual = ParseQual(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
#endif SNAPGFX
                case 'i': insertkey: {
                    if (ARGVAL()) {
                        SnapRsrc->insertkey = hextoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
#ifdef SNAPGFX
                case 'w': cwkey: {
    3t1m;Eiqg #^}]JYހ$S'#  v 
à|U  '_o}dm?^ z=@Eԣ: e/ ~ x'޺dƶi RP׊) 5M5 x'靣H2+#UrfZ0䋨ɀ'P/(AWڻ()
$}OA(b80  p#  C@}%D֖%C`K*(   ~}]  'u`9W)aۙ@	%  'sQ?W8Cھ)P^&,z**j'4l!m7"^@;nwTe 'Ba:xAJFVX*N{jk h#	D-  >[@%O?YHuꠣZ`z  ycq\?  '->WoOQ7 `jh 'gPق+ܔDڠpFbqdkjU''5JJY!~:?ϋ`}]g ' IǅQaVS|m{ܞ1j>kM  # @ RDzU4JonRm*j JJ@  qm 
`NߵN  'CPҎo	  
 ZHm  P'.++D5I5(
: {U~ 'WL)[m|w^߾)t 4-jL'nv(ΈMT@UvKzr4,sT  p"F! D	s:^Ѿ4i /  `hAg^sЀ  'Ϝ d^kN/ma0  ,4). '<1\@D\+-bMADE`02> 'oYfew|Vc{Ftp"'TlvC/'
l3xʤHDh*0}T  H# B@*~{5[_F5)ܱ#	"  	`N  'uR0 WCzJʀ("4Q-E\'~ ցR|jʤJІ8#9/SC'=?ƻR**SJtްB  '(-J탫^B@p;jV$y܉T}D P"A-5%Pp΁--PTDE  |;R  'U7RZo|QZ~!JR=1 ( %-\D" 'ϳ BX+AJ^ BR$1u,-T'DΝ})@ _=t'7 o'!њUbueh E5yђNRk5Tv  #`B"kWSA- J)UZ QU B  w  G@  'jiUzoG`be@ R +B5h'*VTN`	@H$4Z"U!uF'V#vjTixq!_N+@'t-&Ew
BL mK(4"{  #  1ǅ]n
H5)AP  ~ yo  '	hUf:vVi~an @v)[D/U,@X'ux(Ad8mF JNke7)F 's͋vڪݿ8o.zT#~z@'!AHJ5P` lH̰.M{u=X  H"@@ӖO֨Z *BХYA)  > X!  '3jiWB|Ȥ4 %YF!T '**iCUlH9sDHb'XGTX`'Jvm/ի7"_ӬɋU';<7Z<AG
㪡R)QzT[ 0#B@2Ku܏K٦>%. [`D  W xQ߭T  'qjly'Y|_ a RA(Ư^ ':*,o%Q<Z*ahp[ibg'7)nz^xI~-+fMXK5gP 'f;&J6+PJKJN@.ڒI[?R  X# Ic.e鑿-J B 2  %9  '
D+{[Wl>EHADt`rI '~?=H*oCmUi,΁dJ/I/ '^z/5ZG6Qi}dnXOǝބk@'Za):羞VTPþb%]jS[(hNo   #J Z*NFtw9?QK@	 ` [  w  '>~նnTQUf9A@RQKɄ,Gi@ 'E8$mT@` h`[KU\לnn@'DHt\{[eu4sDnX?i- @'DAlPԽX$&%ĢZ x$ !( +SRe}ےWHT]X   y@  '1'+r-$ib  X < @'
ob.   kW`dȃZ:@'b<g>`3:W,\̿)V 'pC]	էL@`^$@؝Q  P#h_~`7kR[>jR  E4 ߟ j_  'L/XcaQ&@#B\
/<G!U 'Fh+P/ɗ`&KG0\0-iW'銊fIJOg:dtOs  UT'Y5 [I"¹	Mq#%+  X#  R׋"(JiLTP!< pyY  'C_-UOK2$g@ !ғk;1T@'YITGk
Kd.PH),$ƶz]/u4p'S[Y>_YϵxE5ݍD 7'RňȝJ1Y e{EP响3Rc8  # !HX<*wbXPijĀ ?_j{|p  '-_/ՈUWd@ $i"Dψ5 0'm,V7inňmV[af*ohPƙ6'1fJg@תtq|^@T] 9'&_M0	AP#MEBO%U p#	A+;usλ4b~_*NH@Ѿ ?{',i@  'A5d$̐U0e>/K; <0nHSs: 'Sn% .D&dI1 C6NJZ 'uICs?#g:鋖 rY65 ?'!KӻK>c3@Ad)7@MsH  $9շμUj<\ ZC o?@ rs  '..hӊSQhр5LA $J3 h'="m@Ph)t% j_';A+C=KF_߯ Ĳ~{)\'$U~#zC$ikLDW  h#	 (Qɂ6,mTifn P2$   	 {s  '&F菑-֐ŀMJ['	Bbh/I T: Ĥp4|'<5]ySI%{{#B ,εsם 'p^:H"(1T6` v@I  p#D4RR֫uʕP*Eo*~ ,  	  w (  'KTϹ5j5$(R$@TRu  'KT9
\0j$(O6PLZ/ '^=BU{j/݀	'c˔<EDw'\ׯM
}8?u;9gMao5T $B!ɴ#ՙmY_:C;ANҀ W   W,  '
tM~E$E&LR@kЫD'$Z	@6/6j֬z-@p' MK*Zϴ8ICȁ`@UvA_'ĮEP< p!quK}-}X  !!N*g/>s_ʾ/#ZX* Q 	 "o   'jK(ʡպ߸teg )\P@zTXA'=Oxm 4 Cڴ;~$YvHhbV,@'쥵{4|=u˞اvLG_[ W'Pr_U}	uۥ3߯p=v  $aÊ|3R=G\!!?U'E@	m@ r @  '<C/Yfϕ   ^9D&P'joX8 &ɴ2=o@Uwj	I '' \3	(VM.`dZ3V[ 'bJ8Os}{H&r/ÙC7d  h# >{6i5A@./
G 	P g,  '?}ӵ񨖗侉t@$/hF
4GA'ٽ0@p8JĘ	|DR(Bƛ'_tՕ~v$햂 l]8srǶː'*fl^{ @C_JTAh:-|  #PAckP [dGߩH!  ^ ^ W  'i?]2b,JH#
rJH']o8,&D"JK?選vK'?_EX:]@>b*ܗ@G@G'a~.$HB{]J
ߔ]f  8$ VD_eͷR}ۮK  ~k $Q?  '@һQ?2X}}̄`#ዎ'	FFаP2 h\8H"uʊJc'}s_\oP:=sxfV/'
6cE  AY8x޳iN"  $Xw[g7m/_q)%Ct#    _ uy  '|(ꭿ_!dCԧz ȋ@$@B';ǻ*(RAPTtZh;*𤘵T^x'\?A뻫$ˌ$l/(P O')kB36.w| Dw6;O(oU5y   OH@J`7Ah0-/M   A8 SM  'io;yIQ&(HЬPL  '	_+Q1&I $Ql6Sp#AZ 'u{֯fQ	8;mP['@$"'&$^fbCIZf|ozU	G  @#߿	$'dv!'>֠Hb'D  		 ;;@  'n{+1GMڞo($NDPƄHS  `'Oar!9 DE؆n6M,gV^HWf'oݵ5 VX	_,c>, $rYs< GC*ku;Vsr $>6MI&|td$@ ߿	^6W  ' Wn/vJXc606K*dA  'SUvJl& l#  'JY;oYS?,TI: Q,bZC  $3ڤXYG_)Ce w||BB @פ۶>gNG'B)A e XvPPTH Ͽ	#߀  ' iSviϿ28ؽ=ֿ, ah&PLH0  '	V:(X$ԗ),RD;E  '5h&wĿYu@~}@$۳NV~,;C~JE*"4wh9La\ $	ߦZ.`uuTx  , 	@ n   'ilUӓ],Y}=?{ DGR,AM
@@ 'k$WP8qYY{s` VЄ(l! M
  '=owp/ԋOlǫ.~!  $ՋO=~1Z~U%`A~c?óf  ='7  C?#     '`|rݰ3_
CCrq $s<45شj1`WHdSVS ';X{7߀~kEV2x $9܉	4zq	BKSaͪ>tWaiͪ $	(גK<5@= 4qR"D
 ? ߋ ߻  '{mʾr=!ye@dQĕ%  '
̟m1Ȇ{-!<qlן.  'd EOw5Rw頮_ђ}ow	 $Q1~eV0B 6;d<gHp^~ $ ECv4< C__@@<$?\ ]0AX  ^  '<5^</ +]Ě $v0}h5Okč1!m( '{Lt_n1~@:B۵nϘ=  $BUA @R1jKnʢ $ 	ؕq.]v "H (c`?"| 7 Ta݀  '{θ!+RJ5 c$ BP  $ܗȐ",f*5@rC	5b|&
@ 'ul?;KBϵn!ed7 @'$]je"BO?|(YG/W^.һ $ 4OHeql# `9R'DM?  & _0  'ʆ	>_YU>niԭKƃB$DtW @ 'mwv9-B"IiR-V@ Kq,&   'u1eU.h@cK&|ek`vxݵ$E#:9wt2_ؚ|g!l^ $ .ES}x|   9YPD(?H  ƦRwN  '"V<?*g%Ewd	IPX)F  '>_*r@6$g	PN/ '{5Iu.;V*Or"*&y '$?B'jN튑Ror]AQY-b $ :/!+b1(H+ @ ^	:e?@` 1U 	ߠV}  '@?TKY׷nU@(V%0/N  'tT	pFF_ne ialַE0<V@  'klT[nv
\͏ؑ.eR $UoLTt-kū+ $e/n@an2h B  HhH~	 4 r/~T  '$ݿ]W99}BLH9pIxR  'wQQW9ȟsSTHY2WXJkKtR '췆$ƻIpǩ	3CSe󵈭|ւ$ܦZ B|w BH̋T $+A1aF@ %P

^@ t ?	ڿx 7  ']nj?Bz !@[H
,@2@P'hYJ<8c
b j'{g_$ߚ]U7/kʹPP$Z4/+{tiDr0$(; $ =+ORJ*J
"H  0"Q 
|T<  _p!  '	v+j~ LQE 'BtNs*e "|ZDѱ1,VPP('c-,;oďuRHgՒ} 'oC3 9?I;V]*T.`  3#LOp`z@E| Y4 _
^W  'zWƝ綾v{~_d !idI0$0 'T%2b9.Yf@$DeEHU}E'IZ^?8uHP[`;=*дHN@$ޠ]~#kzo΢T
}d."֫' $ sW'Uwh@PE'dR=,	 y	, w  ',ɷ,?\ ),I(B (p 'LHX	{#x_*Ti,I.F!|@ 'f<:
	<FFa=vϷ؜o|VS/$9^J)	"/8]vj]5Bl}O $+v7O o@ ]4H^qL  ˷2  'oԅe1$eZ՟I5H\Y*x 'kԗX 3 ]WiJ^,9K.\A('hl/g۬PKot:@X.TU}4j'-ma5ԑNg<vWTmnǶ  $Oׯ +# Y_U%L $ ?٨ڿ@  '2z~VTOۻ1 'WTPP2d,*'20*>@PID隳=^MU\Tvt<B'ncw64ce-kPk1R"kk	
u6+f{edG''1߫~$ϳ-VYs  $
S< R)+# E҄&r b{U  ' z\Mf_/lTK>1PϫZrS@'jlÁU&&u,:pNKVC9u<A r*Vw '*^W+UM5U_{|	)'$w97d_t39;*_ k΁  'm+VQB  (9Y
-)9@  j>  'Y_Qd=?A`Op,<,'PD]!`Ds$OH]E
))/ue='՟OdOh 1U+Տq~E8E{H'';פ	<Bʰ)FLoTq  !h| }H p$ToP@E9  ?f;@ 'uYlG;4j¿xR7 8E 0('d(k*`WYt6c\A
|h'{VŪ9XfEo		S:<{ǆ8$HW'S}e)Ul"ϰ
{  'G9a/P @lR Cx3  ?	u_  '`aL"{v?yAN+  R2 `H' "j/!s"L` BNIi@P'm)δʈ[uY:(ox!1Է'^A:{J?~5©q.	L
  '7ф;6 Wh @b$P7  :3po߿VןH@ ' c%}䬈?+aU"8`$)pT' 'U@-&
b )];PE'oַ_=14ʢo_Gt-bg!5eFW'
/`oO)
%$+OJy  '7`Ё4w\ )P D(Q@ZH  <[o  
?F|$
"R$AH 'z:X5&"u?}Qbl"I$}P'f-dZF;~<VU+r6$V-q1W'oPƎxsZx|4fļ	_2^@ 5g|5P @  PC
   ||ok SP {rTU˃Й qO  @'W  BT[֨,QG+
Й0 JiP'W{ה6؊`gX,߁&xyNw9'bR 	1)"%R'T 'x;" %ߑ @$-@9T   = ~w_ '9@'vq~Q?ڏ`gX-a0\#5 '7@|{:AvʋqgG		
a
2^毈'y)'m/fNd#_)C1Zٞ[r7
'Bސ$#oGǯ^ܯRFNg1շP p|+=b_T "Bc
RT8  
>g  '_ K~Hߟp _(('S C\+`H׆x.@*ZXR
|>Z'ٯIQ1VUl3L?-ʨ'(B'[o? \&Tvm`P3z  'X$߲@ 	EAx`  
wZn '|pG`4BUa   Nf$x'_E 4WbU$JR'?/Ld-+ 7h#jWu'Kp!'u+uzC.D%wOK?)  Pe㥰
  P"A%ҔM0  
  '}zL0POUu( 2uHGAN'u^0Q{˪(Dp'"% H	Eq[R'or$>W$M^ǱՆOeS2)ZO'H@`_i!M6E.;r%3.ІZ]5 '_K2%.Ѡ; [ ` "#Q(  
m?o{w ' ._~_фBe[/(?8'	_\ 6WAf\]JeJԸ+xL[p'Z/	?,$ݝ.c2;-Jc'x9`)=}~?&+IO [)b-Z?K '	_zBͧ4 (CpE(SN  _?
o` 'y] "?%+d-aQRu{v'	Qs *'Ͱ$)> $  Q	P(YP9p'KmUkm(=քŪU> ]*fN~w'q*3BC&*{}4cm˩i 'tz#8!jo7@PЀlАg  
o?/  'm]h^G_-Ȋ nQP&ҁP'~4uhlVCBЭ).؊j@+P6+h'ϧ}oő[UGEkVbҧ'zBt23Μ5E&6:Xm.) .~Fat(z0(&$)*>"p  ~oWo '	Q_"Z_C$Ԭ؈}f}BbDx'+x鸴΄ODesʾ$DXꍌr'hs;{=Π<Z{[Շq/mU]'D?'AJFQ.U j2Xa '$ЀޫrQ]` @*O|'  > ww '
ߘ|&;.I"* McF'嘁ѦP1F5Va^-Pm3WM'l?O󿈡FO8t򱗕OW'*|(f 6u8n%crRo '׈bs5 %(  Bg=G  
?~~ ? _J '̋@E}DEtZ  F+` 8'̉Oڀfz13DEu} b)D#E(L';\MK_X?}nZ˭EEjW'Q7@>Zҟ}'+P#UtW$PU} '- FUiUՈ  "BXAx%z  
_o~ݽ~_ '·4p*})T ZPH!@EOʅ0G':L@
\TԼ"XI$Mܵ'+a4/҅?}hhCmA@o'%>=&77Uޚ+).[-3P}W  I T	I@I6  
V?c_ 7 'ܘG j~v	_Vl	:= C5'"*:b-KHDeHzDG6^'ʿLWFP(ҝogt3'gOUŶKp'H!߽(lIn
\\J0W?yAs" I$Dm/  {  'F>mƘ(*5ha#I :'!C\]"(Ɗ Z&*YMĥ'jd'NESz>4cq5Y~nKWXw'~ Ieq.J+
% ' @ @@T J7?  _ z ']?%m(NQYҀj1x~B	'
%J-hd
UP@!j-B{/'