/*
	Copyright (C) 2007  Alexander Atanasov      <aatanasov@gmail.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; version 2 of the License.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
	MA  02110-1301  USA

	Garmin and MapSource are registered trademarks or trademarks
	of Garmin Ltd. or one of its subsidiaries.

*/

/*
File format is:

POINT
GROUP,0x0100 = town_label_1e5, Megapolis (10M +)
GROUP,0x0200 = town_label_5e4, Megapolis (5-10M)
...
GROUP,0x1e00-0x1e3f = district_label, District, Province, State Name
...
POLYLINE
GROUP,0x00 = street_1_land, Road
GROUP,0x01 = highway_land, Major HWY thick
GROUP,0x02 = street_4_land, Principal HWY-thick
GROUP,0x03 = street_2_land, Principal HWY-medium
....
POLYGONE
GROUP,0x01 = town_poly, City (>200k)
GROUP,0x02 = town_poly, City (<200k)
GROUP,0x03 = town_poly, Village

GROUP is
0 - good old garmin types in RGN1
1 - NT types in RGN2-4 5 is completely unknown yet
 */

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
#include "item.h"
#include "gar2navit.h"

#define dlog(x, y...) fprintf(stderr, ## y)
/*
static int add_def(struct gar2nav_conv *conv, int type, unsigned short minid,
		unsigned short maxid, unsigned int routable, char *ntype,
		char *descr)
*/

static void print_header(FILE *fp) {
    fprintf(fp, "// This is autogenerated file -- DO NOT EDIT\n");
    fprintf(fp, "struct gar2nav_conv *g2n_default_conv(void)\n"
            "{\n"
            "\tstruct gar2nav_conv *conv;\n"
            "\n"
            "\tconv = calloc(1, sizeof(*conv));\n"
            "\tif (!conv)\n"
            "\t\treturn conv;\n");
}

static int load_types_file(char *file, char *out) {
    char buf[4096];
    char descr[4096];
    char ntype[4096];
    FILE *fp;
    unsigned int minid, maxid, group;
    int rc;
    int type = -1;
    FILE *fpout = stdout;

    fp = fopen(file, "r");
    if (!fp)
        return -1;
    if (out) {
        fpout = fopen(out, "w");
        if (!fpout)
            return -1;
    }
    print_header(fpout);
    while (fgets(buf, sizeof(buf), fp)) {
        if (*buf == '#' || *buf == '\n')
            continue;
        if (!strncasecmp(buf, "POINT", 5)) {
            type = 1;
            continue;
        } else if (!strncasecmp(buf, "POI", 3)) {
            type = 1;
            continue;
        } else if (!strncasecmp(buf, "POLYLINE", 8)) {
            type = 2;
            continue;
        } else if (!strncasecmp(buf, "POLYGONE", 8)) {
            type = 3;
            continue;
        }

        rc = sscanf(buf, "%d, 0x%04X - 0x%04X = %[^\t , ] , %[^\n]",
                    &group, &minid, &maxid, ntype, descr);
        if (rc != 5) {
            maxid = 0;
            rc = sscanf(buf, "%d, 0x%04X = %[^\t, ], %[^\n]",
                        &group,&minid, ntype, descr);
            if (rc != 4) {
                dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf);
                dlog(1, "minid=%04X ntype=[%s] des=[%s]\n",
                     minid, ntype, descr);
                continue;
            }
        }

        fprintf(fpout, "\tadd_def(conv, %d, %#.04x, %#.04x, %d, \"%s\", \"%s\");\n",
                type, minid, maxid, group, ntype, descr);
    }
    fprintf(fpout, "\treturn conv;\n");
    fprintf(fpout, "}\n");
    fclose(fp);
    if (out)
        fclose(fpout);
    return 1;
}

int main(int argc, char **argv) {
    if (argc!=3) {
        fprintf(stderr, "Usage: %s garmintypes.txt outfile.c\n",
                argv[0]);
        return -1;
    }
    if (load_types_file(argv[1], argv[2]) < 0) {
        unlink(argv[2]);
        return -1;
    }
    return 0;
}
