#include "japi/draw.h"
#include "japi/game.h"
#include "japi/font.h"
#include "menu.h"
#include "toolbar.h"
#include "treeview.h"
#include "propertygrid.h"
#include "tilemap.h"
#include "fkYAML/node.hpp"
#include <filesystem>
#include <iostream>
#include "misc.h"

namespace fs = std::filesystem;

bool loop();

std::map<std::string, std::string> rooms;

fkyaml::node room;
std::string current_room = "";

void loadRoom(std::string room_file)
{
    int filesize;
    char *f = file::getFileBuffer(std::string("room/"+room_file+".yaml").c_str(), filesize, true);
    room = fkyaml::node::deserialize(std::string(f));
    current_room = room_file;
    free(f);

    uint16_t tiles[32*16];
    int i=0;
    for(auto row : room.at("tilemap").as_seq())
    {
        for (auto t : row.as_seq())
        {
            tiles[i] = t.get_value<int>();
            i++;
        }
    }
    tilemap::set(tiles);
    tilemap::setBackground(misc::getColorByName(room["room"]["bgColor"].get_value<std::string>()));
    tilemap::setBorder(misc::getColorByName(room["room"]["border"].get_value<std::string>()));
    //fkyaml::node name_node = room["room"]["name"];
    //printf("%s\n", name_node.get_value<std::string>().c_str());
}

void game::init()
{
    draw::init("DILEMMAKER v0.1", 800, 600);
    game::setState(loop);
    font::load("font/8bithud");
    draw::cls(0x00000000);
    tilemap::init();

    std::vector<std::string> room_names;

    for (const auto& entry : fs::directory_iterator("./data/room")) {
        if (entry.is_regular_file() && entry.path().extension() == ".yaml") {
            room_names.emplace_back(entry.path().stem());
        }
    }
    std::sort(room_names.begin(), room_names.end(), [](const fs::path& a, const fs::path& b) {
        return a.filename().string() < b.filename().string();
    });

    for (auto& entry : room_names) {
        loadRoom(entry);
        rooms[entry] = room["room"]["name"].get_value<std::string>();
    }
}

bool loop()
{
    menu::start();
    if (menu::option("FILE")) {
        menu::popup::start();
        menu::popup::option("New...");
        menu::popup::option("Load...");
        menu::popup::option("Save...");
        menu::popup::end();
    }
    if (menu::option("EDIT"))  {
        menu::popup::start();
        menu::popup::end();
    }
    if (menu::option("SELECTION"))  {
        menu::popup::start();
        menu::popup::end();
    }
    if (menu::option("VIEW"))  {
        menu::popup::start();
        menu::popup::end();
    }
    if (menu::end()) { draw::render(); return true; }

    toolbar::start();

    treeview::start();
    for (auto p : rooms) {
        const char *r = p.first.c_str();
        //std::string room_label = r + 
        if (treeview::option(std::string(p.first + ": " + p.second).c_str(), 0)) {
            if (current_room != r) {
                loadRoom(r);
            } else {
                auto enemies = room.at("enemies").as_seq();
                if (!enemies.empty()) treeview::option("ENEMIES:", 1);
                for (auto enemy : enemies) {
                    treeview::option(enemy["animation"].get_value<std::string>().c_str(), 2);
                }
                auto items = room.at("items").as_seq();
                if (!items.empty()) treeview::option("ITEMS:", 1);
                char tmp[5];
                for (int i=0; i<items.size(); ++i) {
                    treeview::option(SDL_itoa(i, tmp, 10), 2);
                }
            }
        }
    }
    treeview::end();

    tilemap::start();
    tilemap::draw();
    char tmp[256];
    propertygrid::start();
    if (treeview::getSelected(0) > -1) {
        if (treeview::getSelected(2) == -1) {
            propertygrid::sectionProperty("ROOM:");
            propertygrid::stringProperty("NAME", room["room"]["name"].get_value<std::string>());
            propertygrid::stringProperty("BGCOLOR", room["room"]["bgColor"].get_value<std::string>());
            propertygrid::stringProperty("BORDER", room["room"]["border"].get_value<std::string>());
            propertygrid::stringProperty("TILESET", room["room"]["tileSetFile"].get_value<std::string>());
            propertygrid::stringProperty("ITEMCOL1", room["room"]["itemColor1"].get_value<std::string>());
            propertygrid::stringProperty("ITEMCOL2", room["room"]["itemColor2"].get_value<std::string>());
            propertygrid::stringProperty("CONVEYOR", SDL_itoa(room["room"]["autoSurface"].get_value<int>(), tmp, 10));
            propertygrid::sectionProperty("CONNECTIONS:");
            propertygrid::stringProperty("UP", room["room"]["connections"]["up"].is_null()?"null":room["room"]["connections"]["up"].get_value<std::string>()+": "+rooms[room["room"]["connections"]["up"].get_value<std::string>()]);
            propertygrid::stringProperty("DOWN", room["room"]["connections"]["down"].is_null()?"null":room["room"]["connections"]["down"].get_value<std::string>()+": "+rooms[room["room"]["connections"]["down"].get_value<std::string>()]);
            propertygrid::stringProperty("LEFT", room["room"]["connections"]["left"].is_null()?"null":room["room"]["connections"]["left"].get_value<std::string>()+": "+rooms[room["room"]["connections"]["left"].get_value<std::string>()]);
            propertygrid::stringProperty("RIGHT", room["room"]["connections"]["right"].is_null()?"null":room["room"]["connections"]["right"].get_value<std::string>()+": "+rooms[room["room"]["connections"]["right"].get_value<std::string>()]);
        }
    }
    propertygrid::end();

    /*x1 += 6; x2 = x1 + font::len("FILE")+6;
    font::print("FILE", x1, 5); x1=x2;

    font::print("EDIT", x, 5); x+= font::len("EDIT")+12;
    font::print("SELECTION", x, 5); x+= font::len("SELECTION")+12;
    font::print("VIEW", x, 5); x+= font::len("VIEW")+12;*/
    draw::render();
    return true;
}
