/* ------------------------------------------------------------------------------------------ */
#include <stdio.h>
#include <stdlib.h>
/* ------------------------------------------------------------------------------------------ */
#define FAILED 1
#define SUCCEED 0
/* ------------------------------------------------------------------------------------------ */
#define LOCATION_NUM 460

struct location {
    __uint16_t width;
    __uint16_t height;
};

struct location_table {
    __uint16_t location_num;
    struct location *location_table;
};


#define STATION_NAME_NUM 124

struct station_name_table {
    __uint8_t station_name_num;
    __uint8_t **station_name_table;
};

#define LINE_NUM 6

struct station_id {
    __uint16_t line_id: 3;
    __uint16_t station_id: 6;
    __uint16_t head_station_tag: 1;
    __uint16_t tail_station_tag: 1;
    __uint16_t transfer_station_tag: 1;
    __uint16_t transfer_station_id: 4;
};

struct station {
    struct station_id station_id;
    __uint8_t station_name_id;
    __uint32_t location_id;
};

struct station_table {
    __uint8_t station_num;
    struct station *station_table;
};

struct tstation {
    struct station_id station_id;
    __uint8_t near_tstation_num;
    __uint8_t near_tstation_index[4];
    __uint8_t near_tstation_station_num[4];
};

struct tstation_table {
    __uint8_t tstation_num;
    struct tstation *tstation_table;
};

/* ------------------------------------------------------------------------------------------ */
__uint8_t init_location_table(struct location_table *location_table) {

    location_table -> location_num = LOCATION_NUM;
    location_table -> location_table = (struct location *) malloc (sizeof(struct location) * LOCATION_NUM);

    /* ----- Open location.way file ----- */
    FILE *fp = NULL;

    /* ----- Read location.way ----- */
    if ((fp = fopen("../lib/location.way", "r")) == NULL) {
        printf(" [ Console ]: Cannot open file location.way\n");
        return FAILED;
    }

    __uint16_t tmp_width, tmp_height;

    for (__uint16_t location_table_index = 0; location_table_index < LOCATION_NUM; ++location_table_index) {
        tmp_width = tmp_height = 0;
        fgetc(fp);
        for (__uint8_t width_ch_index = 0; width_ch_index < 5; ++width_ch_index) {
            tmp_width = tmp_width * 10 + (fgetc(fp) - '0');
        }
        fgetc(fp);
        fgetc(fp);
        fgetc(fp);
        for (__uint8_t height_ch_index = 0; height_ch_index < 5; ++height_ch_index) {
            tmp_height = tmp_height * 10 + (fgetc(fp) - '0');
        }
        fgetc(fp);
        fgetc(fp);
        ((location_table -> location_table) + location_table_index) -> width = tmp_width;
        ((location_table -> location_table) + location_table_index) -> height = tmp_height;
    }
    
    fclose(fp);

    printf(" [ Console ]: Initialize location_table successfully\n");
    
    return SUCCEED;
}

__uint8_t init_station_name_table(struct station_name_table *station_name_table) {
    
    /* ----- Open station_name.way file ----- */
    FILE *fp = NULL;

    /* ----- Read station_name.way ----- */
    if ((fp = fopen("../lib/station_name.way", "r")) == NULL) {
        printf(" [ Console ]: Cannot open file station_name.way\n");
        return FAILED;
    }

    station_name_table -> station_name_num = STATION_NAME_NUM;
    station_name_table -> station_name_table = (__uint8_t **) malloc (sizeof(__uint8_t *) * STATION_NAME_NUM);

    for (__uint8_t station_name_index1 = 0, station_name_index2, *station_name, station_name_len; station_name_index1 < STATION_NAME_NUM; ++station_name_index1) {

        fgetc(fp);
        station_name_len = (fgetc(fp) - '0') * 10 + (fgetc(fp) - '0');
        fgetc(fp);
        fgetc(fp);
        fgetc(fp);
        station_name = *((station_name_table -> station_name_table) + station_name_index1) = (__uint8_t *) malloc (sizeof(__uint8_t) * station_name_len);
        for (station_name_index2 = 0; station_name_index2 < station_name_len; ++station_name_index2) {
            *(station_name + station_name_index2) = fgetc(fp);
        }
        *(station_name + station_name_len - 1) = '\000';
        fgetc(fp);
    }

    fclose(fp);

    printf(" [ Console ]: Initialize station_name_table successfully\n");
    
    return SUCCEED;
}

__uint8_t init_station_table(struct station_table *station_table) {

    /* ----- Open station_id.way file ----- */
    FILE *fp = NULL;

    /* ----- Read station_id.way ----- */
    if ((fp = fopen("../lib/station_id.way", "r")) == NULL) {
        printf(" [ Console ]: Cannot open file station_id.way\n");
        return FAILED;
    }




    __uint8_t station_num;

    for (__uint8_t ch_index = 0; ch_index < 15; ++ch_index) fgetc(fp);

    station_num = station_table -> station_num = ((fgetc(fp) - '0') * 10) + (fgetc(fp) - '0');
    station_table -> station_table = (struct station *) malloc (sizeof(struct station) * station_num);

    fgetc(fp);
    fgetc(fp);

    for (__uint8_t station_index = 0; station_index < station_num; ++station_index) {

        /* ----- line_id ----- */
        for (__uint8_t ch_index = 0; ch_index < 11; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_id.line_id = fgetc(fp) - '0';

        /* ----- station_id ----- */
        for (__uint8_t ch_index = 0; ch_index < 16; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_id.station_id = (fgetc(fp) - '0') * 10 + (fgetc(fp) - '0');

        /* ----- head_station_tag ----- */
        for (__uint8_t ch_index = 0; ch_index < 22; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_id.head_station_tag = (fgetc(fp) - '0');

        /* ----- tail_station_tag ----- */
        for (__uint8_t ch_index = 0; ch_index < 22; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_id.tail_station_tag = (fgetc(fp) - '0');

        /* ----- transfer_station_tag ----- */
        for (__uint8_t ch_index = 0; ch_index < 26; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_id.transfer_station_tag = (fgetc(fp) - '0');

        /* ----- transfer_station_id ----- */
        for (__uint8_t ch_index = 0; ch_index < 25; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_id.transfer_station_id = (fgetc(fp) - '0') * 10 + (fgetc(fp) - '0');

        /* ----- station_name_id ----- */
        for (__uint8_t ch_index = 0; ch_index < 21; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_name_id = (fgetc(fp) - '0') * 100 + (fgetc(fp) - '0') * 10 + (fgetc(fp) - '0');

        /* ----- location_id ----- */
        for (__uint8_t ch_index = 0; ch_index < 17; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> location_id = (fgetc(fp) - '0') * 100 + (fgetc(fp) - '0') * 10 + (fgetc(fp) - '0');

        fgetc(fp);
        fgetc(fp);
    }

    





    for (__uint8_t station_index = 0; station_index < station_num; ++station_index) {

        printf("line_id:%d,", ((station_table -> station_table) + station_index) -> station_id.line_id);
        printf("station_id:%d,", ((station_table -> station_table) + station_index) -> station_id.station_id);
        printf("head_station_tag:%d,", ((station_table -> station_table) + station_index) -> station_id.head_station_tag);

        /* ----- head_station_tag ----- */
        for (__uint8_t ch_index = 0; ch_index < 22; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_id.head_station_tag = (fgetc(fp) - '0');

        /* ----- tail_station_tag ----- */
        for (__uint8_t ch_index = 0; ch_index < 22; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_id.tail_station_tag = (fgetc(fp) - '0');

        /* ----- transfer_station_tag ----- */
        for (__uint8_t ch_index = 0; ch_index < 26; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_id.transfer_station_tag = (fgetc(fp) - '0');

        /* ----- transfer_station_id ----- */
        for (__uint8_t ch_index = 0; ch_index < 25; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_id.transfer_station_id = (fgetc(fp) - '0') * 10 + (fgetc(fp) - '0');

        /* ----- station_name_id ----- */
        for (__uint8_t ch_index = 0; ch_index < 21; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> station_name_id = (fgetc(fp) - '0') * 100 + (fgetc(fp) - '0') * 10 + (fgetc(fp) - '0');

        /* ----- location_id ----- */
        for (__uint8_t ch_index = 0; ch_index < 17; ++ch_index) fgetc(fp);
        ((station_table -> station_table) + station_index) -> location_id = (fgetc(fp) - '0') * 100 + (fgetc(fp) - '0') * 10 + (fgetc(fp) - '0');

        fgetc(fp);
        fgetc(fp);
    }





    fclose(fp);

    return SUCCEED;
}


int main(int argc, char **argv) {

    struct location_table location_table;
    struct station_name_table station_name_table;
    struct station_table line_01_station_table;


    init_location_table(&location_table);
    init_station_name_table(&station_name_table);
    init_station_table(&line_01_station_table);


    return 0;
}