#include "snap.h"
#include <stdio.h>

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

struct SnapRsrc *SnapRsrc = NULL;

SHORT isdigit(c)
REGISTER char c;
{
    return (c>='0' && c<='9');
}

#ifdef AZTEC_C
char *strupr(str)
char *str;
{
    register char *p = str;
    register char c;
    while (c = *p) {
        if ('a' <= c && c <= 'z') {
            *p = c - ('a' - 'A');
        }
        ++p;
    }
    return str;
}
#endif AZTEC_C

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

LONG hextoint(str)
REGISTER char *str;
{
    REGISTER long val = 0;
    REGISTER char c;
    while (c = *str) {
        val <<= 4;
        val |= (c & 15) + (isdigit(c) ? 0 : 9);
        str++;
    }
    return(val);
}

main(argc, argv)
WORD argc;
char *argv[];
{
    WORD usage = 0;

    SnapRsrc = (struct SnapRsrc *)OpenResource(SNAPRSRC);
    if (!SnapRsrc) {
        puts("Snap not installed");
        exit(0);
    }

    if (argc == 1) {
        puts("Snap settings:");
        printf("Priority:    %d\n", SnapRsrc->Priority);
        printf("Gfx Qual:    %x, ", SnapRsrc->gfxqual);
        printf("Text Qual:   %x\n", SnapRsrc->textqual);
        printf("Insert key:  %x, ", SnapRsrc->insertkey);
        printf("CW key:      %x\n", SnapRsrc->cwkey);
        printf("Prepend:     \"%s\"\n", &SnapRsrc->Prepend);
        printf("Append:      \"%s\"\n", &SnapRsrc->Append);
        printf("Xerox:       %s, ", (SnapRsrc->flags & XEROX ? "On " : "Off"));
        printf("Early patch: %s\n", (SnapRsrc->flags & EARLYPATCH ? "On " : "Off"));
        printf("Join long:   %s, ", (SnapRsrc->flags & JOINLONG ? "On " : "Off"));
        printf("Underscore:  %s\n", (SnapRsrc->flags & TRUEUNDERSCORE ? "True" : "Fake"));
        printf("Line Delay:  %ld, ", SnapRsrc->linedelay);
        printf("Char Delay:  %ld\n", SnapRsrc->chardelay);
        printf("Crawl Ptrn:  %x\n", SnapRsrc->CrawlPtrn);
        printf("Start Unit:  %d\n", SnapRsrc->StartUnit);
        printf("Frame Mask:  %x\n", SnapRsrc->FrameMask);
        printf("Gad Offset:  %d\n", SnapRsrc->GadOffset);
        printf("Cache Size:  %d\n", SnapRsrc->CacheSize);
        printf("Bad char:    %d\n", SnapRsrc->BadChar);
        exit(0);
    }

    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 = hextoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'g': gfxqual: {
                    if (ARGVAL()) {
                        SnapRsrc->gfxqual = hextoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'i': insertkey: {
                    if (ARGVAL()) {
                        SnapRsrc->insertkey = hextoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'w': cwkey: {
                    if (ARGVAL()) {
                        SnapRsrc->cwkey = hextoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'c': chardelay: {
                    if (ARGVAL()) {
                        SnapRsrc->chardelay = dectoint(*argv) * 1000;
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'l': linedelay: {
                    if (ARGVAL()) {
                        SnapRsrc->linedelay = dectoint(*argv) * 1000;
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'a': crawlptrn: {
                    if (ARGVAL()) {
                        SnapRsrc->CrawlPtrn = hextoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'X': noxerox: {
                    SnapRsrc->flags &= ~XEROX;
                    break;
                }
                case 'x': xerox: {
                    SnapRsrc->flags |= XEROX;
                    break;
                }
                case 'E': noearlypatch: {
                    SnapRsrc->flags &= ~EARLYPATCH;
                    break;
                }
                case 'e': earlypatch: {
                    SnapRsrc->flags |= EARLYPATCH;
                    break;
                }
                case 'R': fakeunderscore: {
                    SnapRsrc->flags &= ~TRUEUNDERSCORE;
                    break;
                }
                case 'r': realunderscore: {
                    SnapRsrc->flags |= TRUEUNDERSCORE;
                    break;
                }
                case 'J': nojoinlong: {
                    SnapRsrc->flags &= ~JOINLONG;
                    break;
                }
                case 'j': joinlong: {
                    SnapRsrc->flags |= JOINLONG;
                    break;
                }
                case 'A': append:
                case 'P': prepend: {
                    char *dest = (**argv == 'A' ?
                      &SnapRsrc->Append[0] : &SnapRsrc->Prepend[0]);
                    if (*++(*argv) || (--argc && ++argv)) { /* "" is ok */
                        char *src = *argv;
                        WORD i = 16;
                        while (*src && i--) {
                            *dest++ = *src++;
                        }
                        *dest = '\0';
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'u': startunit: {
                    if (ARGVAL()) {
                        switch(dectoint(*argv)) {
                            case 1: {
                                SnapRsrc->StartUnit = UNIT_CHAR;
                                break;
                            }
                            case 0:
                            default: {
                                SnapRsrc->StartUnit = UNIT_FRAME;
                                break;
                            }
                        }
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'b': planemask: {
                    if (ARGVAL()) {
                        SnapRsrc->FrameMask = hextoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'o': gadoffset: {
                    if (ARGVAL()) {
                        SnapRsrc->GadOffset = dectoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'C': cachesize: {
                    if (ARGVAL()) {
                        SnapRsrc->CacheSize = dectoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'B': badchar: {
                    if (ARGVAL()) {
                        SnapRsrc->BadChar = dectoint(*argv);
                    } else {
                        usage = 1;
                    }
                    break;
                }
                case 'Q': quit: {
                    Signal(SnapRsrc->Task, SIGBREAKF_CTRL_C);
                    exit(0);
                }
                case '?': {
                    usage = 1;
                    break;
                }
                default: {
                    printf("Bad option: -%c.\n", **argv);
                    usage = 1;
                    break;
                }
            }
        } else {
            (VOID)strupr(*argv);
            if (!strcmp(*argv, "PRIORITY")) {
                (*argv)[1] = '\0';                  /* Fake no argument */
                goto priority;                      /* Terrible, ain't it? */
            } else if (!strcmp(*argv, "TEXTQUAL")) {
                (*argv)[1] = '\0';
                goto textqual;
            } else if (!strcmp(*argv, "GFXQUAL")) {
                (*argv)[1] = '\0';
                goto gfxqual;
            } else if (!strcmp(*argv, "INSERTKEY")) {
                (*argv)[1] = '\0';
                goto insertkey;
            } else if (!strcmp(*argv, "CWKEY")) {
                (*argv)[1] = '\0';
                goto cwkey;
            } else if (!strcmp(*argv, "PREPEND")) {
                (*argv)[1] = '\0';
                goto prepend;
            } else if (!strcmp(*argv, "APPEND")) {
                (*argv)[1] = '\0';
                goto append;
            } else if (!strcmp(*argv, "CHARDELAY")) {
                (*argv)[1] = '\0';
                goto chardelay;
            } else if (!strcmp(*argv, "LINEDELAY")) {
                (*argv)[1] = '\0';
                goto linedelay;
            } else if (!strcmp(*argv, "CRAWLPTRN")) {
                (*argv)[1] = '\0';
                goto crawlptrn;
            } else if (!strcmp(*argv, "XEROX")) {
                goto xerox;
            } else if (!strcmp(*argv, "NOXEROX")) {
                goto noxerox;
            } else if (!strcmp(*argv, "EARLYPATCH")) {
                goto earlypatch;
            } else if (!strcmp(*argv, "NOEARLYPATCH")) {
                goto noearlypatch;
            } else if (!strcmp(*argv, "TRUEUNDERSCORE")) {
                goto realunderscore;
            } else if (!strcmp(*argv, "FAKEUNDERSCORE")) {
                goto fakeunderscore;
            } else if (!strcmp(*argv, "JOINLONG")) {
                goto joinlong;
            } else if (!strcmp(*argv, "NOJOINLONG")) {
                goto nojoinlong;
            } else if (!strcmp(*argv, "STARTUNIT")) {
                (*argv)[1] = '\0';
                goto startunit;
            } else if (!strcmp(*argv, "PLANEMASK")) {
                (*argv)[1] = '\0';
                goto planemask;
            } else if (!strcmp(*argv, "GADOFFSET")) {
                (*argv)[1] = '\0';
                goto gadoffset;
            } else if (!strcmp(*argv, "CACHESIZE")) {
                (*argv)[1] = '\0';
                goto cachesize;
            } else if (!strcmp(*argv, "BADCHAR")) {
                (*argv)[1] = '\0';
                goto badchar;
            } else if (!strcmp(*argv, "QUIT")) {
                goto quit;
            } else if (strcmp(*argv, "?")) {
                printf("Bad switch/keyword: %s.\n", *argv);
            }
            usage = 1;
        }
    }

    if (usage) {
        puts("Usage:");
        puts(" snap -pNN -tXX -gXX -iXX -wXX -Pstr -Astr -cNN -lNN -aXXXX");
        puts("   -x -X -e -E -r -R -j -J -uN -bXX -oNN -CNN -BNN -Q");
        puts(" or");
        puts(" snap PRIORITY/k TEXTQUAL/k GFXQUAL/k INSERTKEY/k CWKEY/k");
        puts("   PREPEND/k APPEND/k CHARDELAY/k LINEDELAY/k CRAWLPTRN/k");
        puts("   XEROX/s NOXEROX/s EARLYPATCH/s NOEARLYPATCH/s STARTUNIT/k");
        puts("   TRUEUNDERSCORE/s FAKEUNDERSCORE/s JOINLONG/s NOJOINLONG/s");
        puts("   PLANEMASK/k GADOFFSET/k CACHESIZE/k BADCHAR/s QUIT/s");
    }

      /* Tell him there are new settings available */
    Signal(SnapRsrc->Task, SIGBREAKF_CTRL_F);
}
