
#include "conf.hh"

#include <fstream>

#include "itty/kv.hh"
#include "itty/paths.hh"
#include "itty/json.hh"

#include "strings.hh"

void conf_init()
{
        itty::inputs.resize(Input_count);

        itty::inputs[Input_left].catchers = {
                itty::Catch_scancode{SDL_SCANCODE_LEFT},
                itty::Catch_scancode{SDL_SCANCODE_J},
                itty::Catch_gbutton{SDL_GAMEPAD_BUTTON_DPAD_LEFT},
                itty::Catch_gaxis<-1>{SDL_GAMEPAD_AXIS_LEFTX},
                itty::Catch_jhat<SDL_HAT_LEFT>{0},
                itty::Catch_jaxis<-1>{0},
        };

        itty::inputs[Input_right].catchers = {
                itty::Catch_scancode{SDL_SCANCODE_RIGHT},
                itty::Catch_scancode{SDL_SCANCODE_L},
                itty::Catch_gbutton{SDL_GAMEPAD_BUTTON_DPAD_RIGHT},
                itty::Catch_gaxis<1>{SDL_GAMEPAD_AXIS_LEFTX},
                itty::Catch_jhat<SDL_HAT_RIGHT>{0},
                itty::Catch_jaxis<1>{0},
        };

        itty::inputs[Input_up].catchers = {
                itty::Catch_scancode{SDL_SCANCODE_UP},
                itty::Catch_scancode{SDL_SCANCODE_I},
                itty::Catch_gbutton{SDL_GAMEPAD_BUTTON_DPAD_UP},
                itty::Catch_gaxis<-1>{SDL_GAMEPAD_AXIS_LEFTY},
                itty::Catch_jhat<SDL_HAT_UP>{0},
                itty::Catch_jaxis<-1>{1},
        };

        itty::inputs[Input_down].catchers = {
                itty::Catch_scancode{SDL_SCANCODE_DOWN},
                itty::Catch_scancode{SDL_SCANCODE_K},
                itty::Catch_gbutton{SDL_GAMEPAD_BUTTON_DPAD_DOWN},
                itty::Catch_gaxis<1>{SDL_GAMEPAD_AXIS_LEFTY},
                itty::Catch_jhat<SDL_HAT_DOWN>{0},
                itty::Catch_jaxis<1>{1},
        };

        itty::inputs[Input_accept].catchers = {
                itty::Catch_scancode{SDL_SCANCODE_X},
                itty::Catch_gbutton{SDL_GAMEPAD_BUTTON_SOUTH},
                itty::Catch_jbutton{0},
        };

        itty::inputs[Input_cancel].catchers = {
                itty::Catch_scancode{SDL_SCANCODE_Z},
                itty::Catch_gbutton{SDL_GAMEPAD_BUTTON_EAST},
                itty::Catch_jbutton{2},
        };

        itty::inputs[Input_start].catchers = {
                itty::Catch_scancode{SDL_SCANCODE_RETURN},
                itty::Catch_gbutton{SDL_GAMEPAD_BUTTON_START},
                itty::Catch_jbutton{7},
        };

        itty::inputs[Input_menu].catchers = {
                itty::Catch_scancode{SDL_SCANCODE_ESCAPE},
                itty::Catch_gbutton{SDL_GAMEPAD_BUTTON_BACK},
                itty::Catch_jbutton{6},
        };
}

bool conf_save()
{
        if (std::ofstream o{itty::paths.config.w(basedir / "game.cfg")}) {
                o << "\n[media]\n";
                o << "width = " << itty::conf.width << "\n";
                o << "height = " << itty::conf.height << "\n";
                o << "full = " << itty::conf.full << "\n";
                o << "vsync = " << itty::conf.vsync << "\n";
                o << "fps = " << itty::conf.fps << "\n";

                o << "\n[input]\n";
                o << "left = " << itty::inputs[Input_left].catchers << "\n";
                o << "right = " << itty::inputs[Input_right].catchers << "\n";
                o << "up = " << itty::inputs[Input_up].catchers << "\n";
                o << "down = " << itty::inputs[Input_down].catchers << "\n";
                o << "accept = " << itty::inputs[Input_accept].catchers << "\n";
                o << "cancel = " << itty::inputs[Input_cancel].catchers << "\n";
                o << "start = " << itty::inputs[Input_start].catchers << "\n";
                o << "menu = " << itty::inputs[Input_menu].catchers << "\n";

                return true;
        }
        return false;
}

bool conf_load()
{
        conf_init();

        if (std::ifstream i{itty::paths.config.r(basedir / "game.cfg")}) {
                itty::Kv_doc doc{itty::slurp(i)};

                doc.at("media", "width") >> itty::conf.width;
                doc.at("media", "height") >> itty::conf.height;
                doc.at("media", "full") >> itty::conf.full;
                doc.at("media", "vsync") >> itty::conf.vsync;
                doc.at("media", "fps") >> itty::conf.fps;

                doc.at("input", "left") >> itty::inputs[Input_left].catchers;
                doc.at("input", "right") >> itty::inputs[Input_right].catchers;
                doc.at("input", "up") >> itty::inputs[Input_up].catchers;
                doc.at("input", "down") >> itty::inputs[Input_down].catchers;
                doc.at("input", "accept") >> itty::inputs[Input_accept].catchers;
                doc.at("input", "cancel") >> itty::inputs[Input_cancel].catchers;
                doc.at("input", "start") >> itty::inputs[Input_start].catchers;
                doc.at("input", "menu") >> itty::inputs[Input_menu].catchers;

                return true;
        }
        return false;
}

