                                // TODO
                                // add readline support
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <err.h>
#include "../lpi.h"

#define CONVENTIONAL_SPACE  's'

                                // function prototypes
int     command(char *);
void    initialize(void);
void    restore(void);
void    printVars(void);

                                // global variables
int     oldbase, base;
int     oldspace, space;        // e.g. 013267 --> space = 6
int     oldgroup, group;        // e.g. 13 267 --> group = 3
char    olddelim, delim;        // e.g. 13,267 --> delim = ','
char    prompt[10] = "> ";

int
main(int argc, char *argv[])
{
    long    number;
    int     nargs;
    char    buf[BUFSIZ];
    char    **array;
    char    *r;

    initialize();
    for ( ; ; ) {
        printf("%s", prompt);
        if (fgets(buf, BUFSIZ, stdin) == NULL) {
            printf("quit\n");   // print a new line at exit.
            break;
        }

        trim(buf);              // ltrim + trim
        if (*buf == '\0')
            continue;           // empty line

        restore();              // restore old global variables
        if (command(buf))       // check input is command?
            continue;

        array = toArray(buf, " ");
        if ((nargs = arrayLength((void *) array)) < 1 || nargs > 5) {
            fprintf(stderr, "number [base space group delimiter]\n");
            continue;
        }

        if ((errno = toLong(array[0], &number)) != 0) {
            warn("invalid number %s", array[0]);
            continue;
        }

        if (nargs >= 2)
            if ((errno = toInt(array[1], &base)) != 0) {
                warn("invalid base %s", array[1]);
                continue;
            }

        if (nargs >= 3)
            if ((errno = toInt(array[2], &space)) != 0) {
                warn("invalid number %s", array[2]);
                continue;
            }

        if (nargs >= 4)
            if ((errno = toInt(array[3], &group)) != 0) {
                warn("invalid number %s", array[3]);
                continue;
            }

        if (nargs == 5) {
            if (!isprint(delim = array[4][0])) {
                warnx("delimiter is not printable!");
                continue;
            }
            if (delim == CONVENTIONAL_SPACE)
                delim = ' ';
        }

        if (r = toBase(number, base, space, group, delim))
            printf("%s\n", r);
    }
    exit(EXIT_SUCCESS);
}

int
command(char *s)
{
    char **v;
    int num;

    if (strncmp(s, "clear", 5) == 0) {
        system("clear");
        return 1;               // was command
    } else if (strncmp(s, "reset", 5) == 0) {
        initialize();
        return 1;
    } else if (strncmp(s, "vars", 4) == 0) {
        printVars();
        return 1;
    }

    v = toArray(s, "=");
    if (arrayLength((void *) v) != 2)
        return 0;

    if (strcmp(v[0], "base") == 0) {
        if ((errno = toInt(v[1], &num)) != 0)
            perror(NULL);
        else
            base = oldbase = num;
        return 1;
    } else if (strcmp(v[0], "space") == 0) {
        if ((errno = toInt(v[1], &num)) != 0)
            perror(NULL);
        else
            space = oldspace = num;
        return 1;
    } else if (strcmp(v[0], "group") == 0) {
        if ((errno = toInt(v[1], &num)) != 0)
            perror(NULL);
        else
            group = oldgroup = num;
        return 1;
    } else if (strcmp(v[0], "delim") == 0) {
        if (!isprint(v[1][0]))
            fprintf(stderr, "unpintable delimiter");
        else
            delim = olddelim =
                    ( v[1][0] == CONVENTIONAL_SPACE ? ' ' : v[1][0] );
        return 1;
    } else if (strcmp(v[0], "prompt") == 0) {
        if (strlen(v[1]) < sizeof(prompt))
            strcpy(prompt, v[1]);
        else
            fprintf(stderr, "prompt must be < %ld charo\n", sizeof(prompt));
        return 1;
    }
    return 0;                   // was not command
}

void
restore(void)
{
    base  = oldbase;
    space = oldspace;
    group = oldgroup;
    delim = olddelim;
}

void
initialize(void)
{
    base  = oldbase = 16;
    space = oldspace = 0;
    group = oldgroup = 0;
    delim = olddelim = ' ';
}

void
printVars(void)
{
    printf("base=%d, ", base);
    printf("space=%d, ", space);
    printf("group=%d, ", group);
    printf("delim=%c$, ", delim);
    printf("prompt=%s$\n", prompt);
    printf("%s\n", "$ is not part of delim and prompt.");
}
