#include <string.h>
#include <grass/colors.h>
#include <grass/raster.h>
#include <grass/glocale.h>
#include "local_proto.h"

#define KEY(x) (strcmp(key, x) == 0)

int read_point(double e, double n)
{
    char buf[2048], symb[1024];
    int r, g, b;
    int color_R, color_G, color_B;
    int fcolor_R, fcolor_G, fcolor_B;
    int ret;
    double size, width, rotate;
    /* int have_icon; */ /* unused */
    char ch;
    char *key, *data;
    int masked;

    static char *help[] = {
        "color  color", "fcolor fill color", "symbol group/symbol", "size   #",
        "width  #",     "rotate #",          "masked [y|n]",        ""};

    size = 6.0;
    width = -1.0; /* default is proportionate to symbol size */
    rotate = 0.0;
    masked = 0;
    color_R = color_G = color_B = 0;
    fcolor_R = fcolor_G = fcolor_B = 128;

    while (input(2, buf, help)) {
        if (!key_data(buf, &key, &data))
            continue;

        if (KEY("masked")) {
            masked = yesno(key, data);
            if (masked)
                PS.mask_needed = 1;
            continue;
        }
        if (KEY("color")) {
            ret = G_str_to_color(data, &r, &g, &b);
            if (ret == 1) {
                color_R = r;
                color_G = g;
                color_B = b;
            }
            else if (ret == 2) /* i.e. "none" */
                color_R = color_G = color_B = -1;
            else
                error(key, data, "illegal color request");

            continue;
        }
        if (KEY("fcolor")) {
            ret = G_str_to_color(data, &r, &g, &b);
            if (ret == 1) {
                fcolor_R = r;
                fcolor_G = g;
                fcolor_B = b;
            }
            else if (ret == 2) /* i.e. "none" */
                fcolor_R = fcolor_G = fcolor_B = -1;
            else
                error(key, data, "illegal color request");

            continue;
        }
        if (KEY("symbol")) {
            /* TODO: check if exists */
            strcpy(symb, data);
            continue;
        }

        if (KEY("size")) {
            if (sscanf(data, "%lf", &size) != 1 || size <= 0.0) {
                size = 1.0;
                error(key, data, "illegal size request");
            }
            continue;
        }

        if (KEY("width")) {
            ch = ' ';
            if (sscanf(data, "%lf%c", &width, &ch) < 1 || width < 0.) {
                width = 1.;
                error(key, data, "illegal width request");
            }
            if (ch == 'i')
                width = width * 72.;
            continue;
        }

        if (KEY("rotate")) {
            if (sscanf(data, "%lf", &rotate) != 1) {
                rotate = 0.0;
                error(key, data, "illegal rotate request");
            }
            continue;
        }

        error(key, data, "illegal point request");
    }

    sprintf(buf, "P %d %f %f %d %d %d %d %d %d %f %f %s %.2f", masked, e, n,
            color_R, color_G, color_B, fcolor_R, fcolor_G, fcolor_B, size,
            rotate, symb, width);

    add_to_plfile(buf);

    return 0;
}

int read_eps(double e, double n)
{
    char buf[1024], eps_file[GPATH_MAX];
    char *eps;
    double scale, rotate;
    int have_eps;
    char *key, *data;
    int masked;
    FILE *fp;

    static char *help[] = {"epsfile EPS file", "scale   #", "rotate   #",
                           "masked [y|n]", ""};

    scale = 1.0;
    rotate = 0.0;
    have_eps = 0;
    masked = 0;

    while (input(2, buf, help)) {
        if (!key_data(buf, &key, &data))
            continue;

        if (KEY("masked")) {
            masked = yesno(key, data);
            if (masked)
                PS.mask_needed = 1;
            continue;
        }

        if (KEY("epsfile")) {
            G_chop(data);

            /* expand "$GISBASE" if present */
            if (strncmp(data, "$GISBASE", 8) != 0)
                strcpy(eps_file, data);
            else {
                strcpy(eps_file, G_gisbase());
                data += 8;
                strcat(eps_file, data);
            }

            eps = G_store(eps_file);

            /* test if file is accessible */
            if ((fp = fopen(eps, "r")) == NULL)
                error(key, data, _("Can't open eps file"));

            have_eps = 1;
            fclose(fp);
            continue;
        }

        if (KEY("scale")) {
            if (sscanf(data, "%lf", &scale) != 1 || scale <= 0.0) {
                scale = 1.0;
                error(key, data, "illegal scale request");
            }
            continue;
        }

        if (KEY("rotate")) {
            if (sscanf(data, "%lf", &rotate) != 1) {
                rotate = 0.0;
                error(key, data, "illegal rotate request");
            }
            continue;
        }

        error(key, data, "illegal eps request");
    }
    if (have_eps) {
        sprintf(buf, "E %d %f %f %f %f %s", masked, e, n, scale, rotate, eps);
    }
    add_to_plfile(buf);

    return 0;
}

int read_line(double e1, double n1, double e2, double n2)
{
    char buf[300];
    int r, g, b;
    int color_R, color_G, color_B;
    int ret;
    double width;
    int masked;
    char ch, *key, *data;

    static char *help[] = {"color  color", "width  #", "masked [y|n]", ""};

    width = 1.;
    color_R = color_G = color_B = 0;
    masked = 0;

    while (input(2, buf, help)) {
        if (!key_data(buf, &key, &data))
            continue;

        if (KEY("masked")) {
            masked = yesno(key, data);
            if (masked)
                PS.mask_needed = 1;
            continue;
        }

        if (KEY("color")) {
            ret = G_str_to_color(data, &r, &g, &b);
            if (ret == 1) {
                color_R = r;
                color_G = g;
                color_B = b;
            }
            else if (ret == 2) /* i.e. "none" */
                color_R = color_G = color_B = -1;
            else
                error(key, data, "illegal color request");

            continue;
        }

        if (KEY("width")) {
            ch = ' ';
            if (sscanf(data, "%lf%c", &width, &ch) < 1 || width < 0.) {
                width = 1.;
                error(key, data, "illegal width request");
            }
            if (ch == 'i')
                width = width * 72.;
            continue;
        }

        error(key, data, "illegal line request");
    }

    sprintf(buf, "L %d %f %f %f %f %d %d %d %.2f", masked, e1, n1, e2, n2,
            color_R, color_G, color_B, width);

    add_to_plfile(buf);

    return 0;
}

int read_rectangle(double e1, double n1, double e2, double n2)
{
    char buf[300];
    int r, g, b;
    int color_R, color_G, color_B;
    int fcolor_R, fcolor_G, fcolor_B;
    int ret;
    double width;
    int masked;
    char ch, *key, *data;

    static char *help[] = {"color  color", "fcolor fill color", "width  #",
                           "masked [y|n]", ""};

    width = 1.;
    masked = 0;
    color_R = color_G = color_B = 0;
    fcolor_R = fcolor_G = fcolor_B = -1; /* not filled by default */

    while (input(2, buf, help)) {
        if (!key_data(buf, &key, &data))
            continue;

        if (KEY("masked")) {
            masked = yesno(key, data);
            if (masked)
                PS.mask_needed = 1;
            continue;
        }

        if (KEY("color")) {
            ret = G_str_to_color(data, &r, &g, &b);
            if (ret == 1) {
                color_R = r;
                color_G = g;
                color_B = b;
            }
            else if (ret == 2) /* i.e. "none" */
                color_R = color_G = color_B = -1;
            else
                error(key, data, "illegal color request");

            continue;
        }

        if (KEY("fcolor")) {
            ret = G_str_to_color(data, &r, &g, &b);
            if (ret == 1) {
                fcolor_R = r;
                fcolor_G = g;
                fcolor_B = b;
            }
            else if (ret == 2) /* i.e. "none" */
                fcolor_R = fcolor_G = fcolor_B = -1;
            else
                error(key, data, "illegal color request");

            continue;
        }

        if (KEY("width")) {
            ch = ' ';
            if (sscanf(data, "%lf%c", &width, &ch) < 1 || width < 0.) {
                width = 1.;
                error(key, data, "illegal width request");
            }
            if (ch == 'i')
                width = width * 72.;
            continue;
        }

        error(key, data, "illegal rectangle request");
    }

    sprintf(buf, "R %d %f %f %f %f %d %d %d %d %d %d %.2f", masked, e1, n1, e2,
            n2, color_R, color_G, color_B, fcolor_R, fcolor_G, fcolor_B, width);

    add_to_plfile(buf);

    return 0;
}

int add_to_plfile(char *buf)
{
    FILE *fd;

    if (PS.plfile == NULL) {
        PS.plfile = G_tempfile();
        fd = fopen(PS.plfile, "w");
    }
    else
        fd = fopen(PS.plfile, "a");
    if (fd != NULL) {
        fprintf(fd, "%s\n", buf);
        fclose(fd);
    }
    else
        error("point/line file", "", "can't open");

    return 0;
}
