#include <string.h>
#include <stdlib.h>
#include <dos.h>
#include "dos/dos.h"
#include "proto/dos.h"

#include <private/Version.h>
#define  ObjRev "1"
const UBYTE version[]="\0$VER: EditOpts " BUILDVER "." ObjRev " ©" COPYRIGHT " by Digerati Dreams "__AMIGADATE__;

#define SINGLE_LINE 0xc4
#define DOUBLE_LINE 0xcd
unsigned char kool;
unsigned char kool_array[] = { ' ', SINGLE_LINE, DOUBLE_LINE, '-', '=', '~', '.', ':' };

char *uname;
char q_greeting[257];
int  q_prefix;
int  cookie_ask;
int  cookie_topic;
int  chuck;
char msgcolor[13];
char quotecolor[13];
char helpcolor[13];
char hbcolor[13];
char wbcolor[13];
char mlcolor[13];
// index into cval... 0 is unused
#define MSGCOLOR   3
#define QUOTECOLOR 5
#define HELPCOLOR  4
#define HBCOLOR    1
#define WBCOLOR    2
#define MLCOLOR    6
    
short cval[7];

    
void mywrite(char *s)
{
    Write(Output(), s, strlen(s));
}

void myputchar(int c)
{
    char buf[1];
    buf[0] = c;
    Write(Output(), buf, 1);
}

int getchar(void)
{
    char c;
    Read(Input(), &c, 1);
    chkabort();
    return c;
}

void getstring(char *buf, int len)
{
    int c;
    int i = strlen(buf);
    mywrite(buf);
    while ((c = getchar()) != '\r') {
   if (c == '\b') {
       if (i > 0) {
      --i;
      mywrite("\b \b");
       }
   } else if (c == 24) {
       while (i > 0) {
      mywrite("\b \b");
      --i;
       }
   } else if (c == 27) {
       c = getchar();
       if (c == '[') {
      // ignore escape sequence for now
      c = getchar();
       }
   } else if ((c&0xff) == 0x9b) {
       // ignore escape sequence for now
       c = getchar();
   } else if (i < len && c >= ' ' && c <= '~') {
       buf[i++] = c;
       myputchar(c);
   }
    }
    buf[i] = 0;
}

char *cname[] = {    /* names of colors      */
"BLACK", "RED", "GREEN", "YELLOW", "BLUE", "MAGENTA", "CYAN", "GREY",
"GRAY",  "LRED","LGREEN","LYELLOW","LBLUE","LMAGENTA","LCYAN","WHITE"
};

unsigned char colorval(char *name)
{
   unsigned char i;
   for (i=0; i<16; ++i) {
      if (stricmp(name, cname[i]) == 0) {
         return i;
      }
   }
   return 2; // WHITE
}

void cls(void)
{
    mywrite("\033[0;37m\033[H\033[J");
}

#define INTWIDTH sizeof(int) * 3

char *int_asc(int i)
{
   register int digit;     /* current digit being used */
   register char *sp;      /* pointer into result */
   register int sign;      /* sign of resulting number */
   static char result[INTWIDTH+1]; /* resulting string */

   /* record the sign...*/
   sign = 1;
   if (i < 0) {
      sign = -1;
      i = -i;
   }

   /* and build the string (backwards!) */
   sp = result + INTWIDTH;
   *sp = 0;
   do {
      digit = i % 10;
      *(--sp) = '0' + digit;  /* and install the new digit */
      i = i / 10;
   } while (i);

   /* and fix the sign */
   if (sign == -1) {
      *(--sp) = '-'; /* and install the minus sign */
   }

   return(sp);
}

int asc_int(char *str)
{
    int result = 0;
    int c;
    
    if (*str < '0' || *str > '9') return -1;
    for (;;) {
   c = *str++;
   if (c < '0' || c > '9') break;
   result = result*10 + c - '0';
    }
    return result;
}

void gotorc(int row, int col)
{
    char buf[50];
    buf[0] = '\033';
    buf[1] = '[';
    strcpy(buf+2, int_asc(row+1));
    strcat(buf, ";");
    strcat(buf, int_asc(col+1));
    strcat(buf, "H");
    mywrite(buf);
}

void color(int n)
{
    static char dim[] = "\033[0;3xm";
    static char brt[] = "\033[1;3xm";
    if (n < 8) {
   dim[5] = '0'+n;
   mywrite(dim);
    } else {
   brt[5] = '0'+n-8;
   mywrite(brt);
    }
}

void bcolor(int n, int f)
{
    static char back[] = "\033[0;3x;4xm";
    if (f >= 8) {
   f -= 8;
    }
    if (n >= 8) {
   n -= 8;
    }
    back[5] = '0'+f;
    back[8] = '0'+n;
    mywrite(back);
}

void region(int reg)
{
    char buf[40];
    if (reg == 2 && kool == 0) {
   // kludge foreground color to look good on all bitplanes
        bcolor(cval[reg], (cval[reg] == 7 || cval[reg] == 15) ? 12 : 7);
    } else {
   color(cval[reg]);
    }
    switch (reg) {
    case 1:
   gotorc(0,3);
   mywrite("  To: Sysop");
   gotorc(1,3);
   mywrite("Subj: Blackjack");
   break;
    case 2:
   memset(buf, kool_array[kool], 33);
   buf[33] = 0;
   gotorc(9,3);
   memcpy(buf+2, "Quote", 5);
   mywrite(buf);
   gotorc(6,3);
   memcpy(buf+2,"DLG1.2", 6);
   mywrite(buf);
   gotorc(2,3);
   memcpy(buf+2, "Press ? for help", 16);
   mywrite(buf);
   if (kool == 0) bcolor(0, 7);
   break;
    case 3:
   gotorc(3,3);
   mywrite("Hey sysop!");
   gotorc(4,3);
   mywrite("The blackjack game is great!");
   break;
    case 4:
   gotorc(5,3);
   mywrite("   Help text is this color");
   break;
    case 5:
   gotorc(7,3);
   mywrite("In a message to All, Sysop wrote:");
   gotorc(8,3);
   mywrite("Play Al's Blackjack Casino!");
   break;
    case 6:
   gotorc(10,3);
   mywrite("Save message? (YES/no)");
   break;
    }
}

void colors(void)
{
    int ch;
    int reg;
    cls();
    mywrite(" 1\n"
       "\n"
       " 2\n"
       " 3\n"
       "\n"
       " 4\n"
       "\n"
       " 5\n"
       "\n"
       "\n"
       " 6\n"
       "\n\n");

    color(6);
    mywrite("Press 1-6 to select region and cycle colors.\n"
       "Press B to change style of border line.\n");
    color(5);
    mywrite("Press RETURN when done.\n");

    for (reg = 1; reg <= 6; ++reg) {
   region(reg);
    }

    reg = 1;
    while (1) {
   gotorc(16,0);
   ch = getchar();
   if (ch >= '1' && ch <= '6') {
       reg = ch - '0';
   }
   switch (ch) {
   case '1':
   case '2':
   case '3':
   case '4':
   case '5':
   case '6':
       if (++cval[reg] == 16) {
      cval[reg] = 0;
       }
       region(reg);
       break;
   case 'b': case 'B':
       ++kool;
       if (kool == sizeof(kool_array)) kool = 0;
       region(2);
       break;
   case '\r':
       return;
   }
    }
}

void quote_greeting(void)
{
    cls();
    mywrite("The following codes may be used:\n\n");
    color(2);
    mywrite("  %F  The full name of the original message author.\n"
       "  %f  The first name of the original message author.\n"
       "  %T  The full name of the original message recipient.\n"
       "  %S  The subject of the quoted message.\n"
       "  %q  The quote attribution of the original message author.\n"
       "      This will be either the initials or first name, depending\n"
       "      on how your quote prefix is set.\n"
       "  %d  The date and time that the quoted message was written.\n");
    color(6+8);
    mywrite("  %N  A hard newline is inserted at this point.  You normally will\n"
       "      want to end your quote greeting with a hard newline.\n");
    color(2);
    mywrite("  %%  A single % is inserted at this point.\n\n");

    color(5);
    mywrite("\n\nEnter new greeting:\n");
    color(7);
    getstring(q_greeting, 256);
}

void quote_prefix(void)
{
    char tempstr[5];
    int tempval;

    cls();
    mywrite("The quote prefix appears at the beginning of each quoted line.\n\n");
    color(2);
    mywrite("[1] BZ>    Initials (upper case)\n"
       "[2] Bob>   First name\n"
       "[3] bz>    Initials (lower case)\n"
            "[4] >      Bracket only\n"
            "[5] Bob_Z> First name and initial\n");

    color(6);
    mywrite("\nCurrent choice is ");
    mywrite(int_asc(q_prefix));
    color(5);
    mywrite("\n\nEnter new choice: ");
    *tempstr = 0;
    getstring(tempstr, 1);
    tempval = *tempstr - '0';
    if (tempval >= 1 && tempval <= 5) {
   q_prefix = tempval;
    }
}

#define NUM_COOKIE_TOPICS 20
char *cfg_fname; /* set during startup to EmacDLG.cfg path */
struct fortcmd {
    char *cmd;
    char *desc;
} fc[NUM_COOKIE_TOPICS];

//
// Read the fortune cookie topics from the config file.
// Returns the number of available topics.
//
static int get_fortune_topics(void)
{
    char buf[120];
    int numfort = 0;
    
    BPTR f;
    f = Open(cfg_fname, MODE_OLDFILE);
    if (f) {
   while (numfort < NUM_COOKIE_TOPICS && FGets(f, buf, 120) != NULL) {
       if (*buf == ';') {
      buf[strlen(buf)-1] = 0; /* destroy newline */
      if (*(buf+1) == '=') {
          fc[numfort].cmd = malloc(strlen(buf+2)+1);
          strcpy(fc[numfort].cmd, buf+2);
      } else if (*(buf+1) == '!') {
          fc[numfort].desc = malloc(strlen(buf+2)+1);
          strcpy(fc[numfort].desc, buf+2);
          ++numfort;
      }
       }
   }
   Close(f);
    }
    return numfort;
}

void cookie(void)
{
    char tempstr[500];
    int tempval;
    int numfort;
    int i;

    cls();
    numfort = get_fortune_topics();

    if (numfort == 0) {
   mywrite("No fortune cookies available.  Ask your sysop for help.\n\n"
      "[Press return]");
   while (getchar() != '\r') {}
   return;
    }


    mywrite("A fortune cookie is a random saying that can be appended to the\n"
       "end of your messages.  Your sysop can setup one or more fortune\n"
       "cookie topics to choose from.\n\n");

    if (numfort == 1) {
   cookie_topic = 0;
    } else {
   mywrite("First, how should we determine which topic you want to use?\n\n");
   color(2);
   mywrite("[1] Never use fortune cookies\n"
      "[2] Ask me for a topic each time I save a message\n");
   for (i=0; i<numfort; ++i) {
       mywrite("[");
       mywrite(int_asc(i+3));
       mywrite("] Use topic: ");
       strcpy(tempstr, fc[i].desc);
       strcat(tempstr, "\n");
       color(5);
       mywrite(tempstr);
       color(2);
   }
   color(6);
   mywrite("\nCurrent choice is ");
   mywrite(int_asc(cookie_topic));
   color(5);
   mywrite("\n\nEnter new choice: ");
   *tempstr = 0;
   getstring(tempstr, 2);
   tempval = asc_int(tempstr);
   if (tempval >= 1 && tempval <= numfort+2) {
       cookie_topic = tempval;
   }
   if (cookie_topic == 1) {
       cookie_ask = 1;
       return;
   }
   cls();
   mywrite("Next, how should we determine which individual fortune cookie to use?\n\n");
    }
    color(2);
    mywrite("[1] Never use fortune cookies\n"
       "[2] Ask me each time I save a message\n"
       "[3] Choose a random fortune cookie without asking\n");
    color(6);
    mywrite("\nCurrent choice is ");
    mywrite(int_asc(cookie_ask));
    color(5);
    mywrite("\n\nEnter new choice: ");
    *tempstr = 0;
    getstring(tempstr, 1);
    tempval = *tempstr - '0';
    if (tempval >= 1 && tempval <= 3) {
   cookie_ask = tempval;
    }
}

void word_wrap(void)
{
    char tempstr[5];
    int tempval;

    cls();
    mywrite("Set the SPECIAL WORD WRAP only if you are a sysop who often\n"
       "edits configuration files remotely.  This option turns off\n"
       "word wrapping when editing plain files.\n\n");
    color(2);
    mywrite("[1] Use normal word wrap\n"
       "[2] Use SPECIAL WORD WRAP for remote file edits\n");
    color(6);
    mywrite("\nCurrent choice is ");
    mywrite(int_asc(chuck));
    color(5);
    mywrite("\n\nEnter new choice: ");
    *tempstr = 0;
    getstring(tempstr, 1);
    tempval = *tempstr - '0';
    if (tempval >= 1 && tempval <= 2) {
   chuck = tempval;
    }
}

BPTR out;

void writeout(char *b)
{
    Write(out, b, strlen(b));
}

void nset(char *n, int v)
{
    char buf[500];
    strcpy(buf, "set ");
    strcat(buf, n);
    strcat(buf, " ");
    strcat(buf, int_asc(v));
    strcat(buf, "\n");
    writeout(buf);
}

void set(char *n, char *v)
{
    char buf[500];
    char *p;
    strcpy(buf, "set ");
    strcat(buf, n);
    strcat(buf, " \"");
    p = buf + strlen(buf);
    while (*v) {
   if (*v == '"') {
       *p++ = '~';
   }
   *p++ = *v++;
    }
    *p++ = '"';
    *p++ = '\n';
    *p++ = 0;
    writeout(buf);
}

void save(void)
{
    char fname[120];
    
    mywrite("Saving...");

    strcpy(fname, "user:");
    strcat(fname, uname);
    strcat(fname, "/ScreenEdit.opt");
    
    out = Open(fname, MODE_NEWFILE);
    if (out) {
   nset("$kool", kool);
   nset("$qstyle", q_prefix - 1);
   nset("$zfask", cookie_ask - 1);
   nset("$zftop", cookie_topic - 1);
   set("$zhello", q_greeting);
   set("$zmsgc", cname[cval[MSGCOLOR]]);
   set("$zqc", cname[cval[QUOTECOLOR]]);
   set("$zhelpc", cname[cval[HELPCOLOR]]);
   set("$zhbc", cname[cval[HBCOLOR]]);
   set("$zwbc", cname[cval[WBCOLOR]]);
   set("$zmlc", cname[cval[MLCOLOR]]);
   nset("%chuck", chuck - 1);
   Close(out);
    } else {
   mywrite("NOT!\n");
    }
}

void finished(void)
{
    //mywrite("\033[0m[PRESS RETURN]");
    //while (getchar() != '\r') {}
    cls();
    _XCEXIT(0);
}

void _CXBRK(int n)
{
    mywrite("What a loser!\n");
    _XCEXIT(13);
}

void main(int argc, char *argv[])
{
    int ch;
    char *p, *q;
    
    if (argc != 15) {
   mywrite("Must be invoked by ScreenEdit\n");
   return;
    }

    uname = argv[1];

    //strcpy(q_greeting, argv[2]);
    // Convert magic character to double quote in quote greeting
    p = argv[2];
    q = q_greeting;
    while (*p) {
   if (*p == 1) *q++ = '"';
   else *q++ = *p;
   ++p;
    }
    *q = 0;
    
    q_prefix = *argv[3] - '0' + 1;
    strcpy(msgcolor, argv[4]);
    strcpy(quotecolor, argv[5]);
    strcpy(helpcolor, argv[6]);
    strcpy(hbcolor, argv[7]);
    strcpy(wbcolor, argv[8]);
    strcpy(mlcolor, argv[9]);
    cval[MSGCOLOR] = colorval(msgcolor);
    cval[QUOTECOLOR] = colorval(quotecolor);
    cval[HELPCOLOR] = colorval(helpcolor);
    cval[HBCOLOR] = colorval(hbcolor);
    cval[WBCOLOR] = colorval(wbcolor);
    cval[MLCOLOR] = colorval(mlcolor);
    kool = *argv[10] - '0';  // beware: only 0-9 supported for kool

    cookie_ask = *argv[11] - '0' + 1;
    chuck = *argv[12] - '0' + 1;
    cookie_topic = asc_int(argv[13]) + 1;
    cfg_fname = argv[14];
    
    while (1) {
   cls();
   mywrite("ScreenEdit User Options\n\n");
   color(2);
   mywrite("[C] Colors\n"
      "[G] Quote greeting\n"
      "[P] Quote prefix\n"
      "[W] Word wrap special option\n"
      "[F] Fortune cookies\n");
   color(6);
   mywrite("\n[S] Save changes and return to editor\n"
      "[A] Abort changes\n\n");
   color(5);
   mywrite("Your choice => ");

   ch = getchar();
   if (ch >= 'a' && ch <= 'z') ch = ch - 'a' + 'A';
   switch (ch) {
   case 'C':
       colors();
       break;
   case 'G':
       quote_greeting();
       break;
   case 'P':
       quote_prefix();
       break;
   case 'W':
       word_wrap();
       break;
   case 'F':
       cookie();
       break;
   case 'S':
       save();
       finished();
   case 'A':
       finished();
   }
    }
}

