#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <unistd.h>
#include <termios.h>
#include <limits.h>
#include <time.h>
#include <sys/time.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

#include "structure.h"
#include "base.h"
#include "rooms.h"

int START_CHX;
int START_CHY;
int FINISH_CHX;
int FINISH_CHY;
int START_DIR;

bool is_digit(char c) {
    return ((int)c >= 48 && (int)c <= 57);
}

int read_int(FILE* ptr) {
    int res = 0;
    char c = fgetc(ptr);
    while(c != EOF && !is_digit(c)) {
        c = fgetc(ptr);
    }
    while(c != EOF && is_digit(c)) {
        res = 10*res + (int)c - 48;
        c = fgetc(ptr);
    }
    return res;
}

// typedef enum road_t {NONE, START, END, STR_V, STR_H, TURN_NE, TURN_SE, TURN_SW, TURN_NW} road; //
/*
. = NULL
0 = Vertical
1 = Horizontal
2 = TopRight        (NE)
3 = BottomRight     (SE)
4 = BottomLeft      (SW)
5 = TopLeft         (NW)
6 = Vertical2
7 = Horizontal2
S = Start
E = End
*/
road get_type(char c) {
    switch (c){
    case '.':
        return NONE;
    case 'S':
        return START;
    case 'E':
        return END;
    case '0':
        return STR_V;
    case '1':
        return STR_H;
    case '2':
        return TURN_NE;
    case '3':
        return TURN_SE;
    case '4':
        return TURN_SW;
    case '5':
        return TURN_NW;
    case '6':
        return STR_VB;
    case '7':
        return STR_HB;
    
    default:
        fprintf(stderr, "unrecognized character '%c' encountered in parsing", c);
        return NONE;
    }
}

void test_file(char* path) {
    FILE* ptr = fopen(path, "r");
    char c = fgetc(ptr);
    while(c != EOF) {
        printf("%c", c);
        c = fgetc(ptr);
    }
    fclose(ptr);
}

level* parse_level(char* path) {
    FILE* ptr = fopen(path, "r");

    level* lvl = malloc(sizeof(level));
    lvl->lines = read_int(ptr);
    lvl->cols = read_int(ptr);

    //printf("dims : (%d %d)\n", lvl->lines, lvl->cols);

    lvl->map = malloc(sizeof(road*)*(lvl->lines));
    for(int l = 0; l < lvl->lines; l++) {
        lvl->map[l] = malloc(sizeof(road)*(lvl->cols));
    }

    for(int l = 0; l < lvl->lines; l++) {
        for(int c = 0; c < lvl->cols; c++) {
            char ch = fgetc(ptr);
            if(ch == '\n') {ch = fgetc(ptr); printf("\n");}
            printf("%c", ch);
            lvl->map[l][c] = get_type(ch);
            if(ch == 'S') {
                START_CHX = l;
                START_CHY = c;
            } else if(ch == 'E') {
                FINISH_CHX = l;
                FINISH_CHY = c;
            }
        }
    }
    printf("\n");

    if(START_CHX-1 >= 0 && lvl->map[START_CHX-1][START_CHY] != NONE) {
        START_DIR = 0;
    }
    if(START_CHX+1 < lvl->lines && lvl->map[START_CHX+1][START_CHY] != NONE) {
        START_DIR = 2;
    }
    if(START_CHY-1 >= 0 && lvl->map[START_CHX][START_CHY-1] != NONE) {
        START_DIR = 3;
    }
    if(START_CHY+1 < lvl->cols && lvl->map[START_CHX][START_CHY+1] != NONE) {
        START_DIR = 1;
    }

    return lvl;
}

void free_level(level* lvl) {
    for(int l = 0; l < lvl->lines; l++) {
        free(lvl->map[l]);
    }
    free(lvl->map);
    free(lvl);
}