#include "jgame.h"
#include "jdraw.h"
#include "jfile.h"
#include "jinput.h"
#include "jaudio.h"
#include "editor.h"
#include "console.h"
#include <string.h>
#include "config.h"
#include <SDL2/SDL.h>

#include "actor.h"
#include "room.h"

#include "m_game.h"
#include "m_menu.h"
#include "m_logo.h"
#include "m_intro.h"
#include "m_ingame.h"
#include "m_gameover.h"
#include "m_catslife.h"
#include "m_menu_tecles.h"
#include "m_menu_gamepad.h"
#include "m_menu_audio.h"
#include "m_editor_map.h"
#include "m_editor_templates.h"
#include "m_editor_colors.h"
#include "m_editor_bitmap_file.h"
#include "m_editor_bitmap.h"
#include "m_end_sequence.h"
#include "m_prologo_intro.h"
#include "m_end_prologo_sequence.h"

#define M_LOGO               0
#define M_INTRO              1
#define M_MENU               2
#define M_GAME               3
#define M_INGAME             4
#define M_GAMEOVER           5
#define M_CATSLIFE           6
#define M_MENU_TECLES        7
#define M_MENU_GAMEPAD       8
#define M_MENU_AUDIO         9
#define M_EDITOR_MAP         10
#define M_EDITOR_TEMPLATES   11
#define M_EDITOR_COLORS      12
#define M_EDITOR_BITMAP_FILE 13
#define M_EDITOR_BITMAP      14
#define M_END                15
#define M_PROLOGO_INTRO      16
#define M_PROLOGO_END        17


int current_module = M_LOGO;
int zoom = 3;
bool fullscreen = false;
char tmp[100];

void loadConfig()
{
    file::setConfigFolder("thepool");

    if (strcmp(file::getConfigValue("music").c_str(), "no")==0) config::setMusic(false);
    
    if (strcmp(file::getConfigValue("prologo").c_str(), "unlocked")==0) config::setProgoloDesbloquejat();

    const char *so = file::getConfigValue("sound").c_str();
    if (strcmp(so, "basic")==0)
        config::setSound(SOUND_BASIC);
    else if (strcmp(so, "none")==0)
        config::setSound(SOUND_NONE);
    
    std::string txt_zoom = file::getConfigValue("zoom");
    if (txt_zoom!="") zoom = SDL_atoi(txt_zoom.c_str());
    
    std::string txt_fullscreen = file::getConfigValue("fullscreen");
    if (txt_fullscreen=="yes") fullscreen = true;

    int screen_mode = SCREEN_MODE_NORMAL;
    std::string txt_fosforo = file::getConfigValue("fosforo");
    if (txt_fosforo=="yes") screen_mode |= SCREEN_MODE_FOSFORO;

    std::string txt_scanlines = file::getConfigValue("scanlines");
    if (txt_scanlines=="yes") screen_mode |= SCREEN_MODE_SCANLINES;

    draw::setScreenMode(screen_mode);

    static const char* nomtecles[6] = {"keyup", "keydown", "keyleft", "keyright", "keyjump", "keypick"};
    for (int i=0; i<6; ++i)
    {
        const int value = SDL_atoi( file::getConfigValue(nomtecles[i]).c_str() );
        if (value != 0) config::defineKey(i, value);
    }

    static const char* nombotons[6] = {"btnup", "btndown", "btnleft", "btnright", "btnjump", "btnpick"};
    for (int i=0; i<6; ++i)
    {
        const int value = SDL_atoi( file::getConfigValue(nombotons[i]).c_str() );
        if (value != 0) config::definePadBtn(i, value);
    }
}

void game::init()
{
    if (game::getParams(1) && strcmp(game::getParams(1), "editor")==0) editor::setDevMode();

    if (editor::isDevMode())
        draw::init("The Pool", 520, 240, zoom);
    else {
        loadConfig();
        draw::init("The Pool", 320, 240, zoom, fullscreen);
        console::init();

        audio::loadSound("snd_logo.wav");
        audio::loadSound("snd_walk.wav");
        audio::loadSound("snd_push.wav");
        audio::loadSound("snd_pick.wav");
        audio::loadSound("snd_jump.wav");
        audio::loadSound("snd_disappear.wav");
        audio::loadSound("snd_dead.wav");
        audio::loadSound("snd_boost.wav");
    }

    if (draw::getScreenMode()&SCREEN_MODE_FOSFORO) {
        draw::loadPalette("fosforo.gif");
    } else {
        draw::loadPalette("test.gif");
    }

    if (editor::isDevMode()) {
        current_module = M_GAME;
        modules::game::init();

    } else 
        modules::logo::init();
}

bool game::loop()
{
    if (input::keyPressed(SDL_SCANCODE_F1)) {
        draw::decZoom();
        zoom = draw::getZoom();
        file::setConfigValue("zoom", SDL_itoa(zoom, tmp, 10));
    }
    if (input::keyPressed(SDL_SCANCODE_F2)) {
        draw::incZoom();
        zoom = draw::getZoom();
        file::setConfigValue("zoom", SDL_itoa(zoom, tmp, 10));
    }
    if (input::keyPressed(SDL_SCANCODE_F3)) {
        draw::toggleFullscreen();
        fullscreen = draw::getFullscreen();
        file::setConfigValue("fullscreen", fullscreen?"yes":"no");
    }
    if (input::keyPressed(SDL_SCANCODE_F4)) {
        draw::toggleScreenMode();
        const int mode = draw::getScreenMode();

        if (mode&SCREEN_MODE_FOSFORO) {
            draw::loadPalette("fosforo.gif");
        } else {
            draw::loadPalette("test.gif");
        }

        file::setConfigValue("fosforo", mode&SCREEN_MODE_FOSFORO?"yes":"no");
        file::setConfigValue("scanlines", mode&SCREEN_MODE_SCANLINES?"yes":"no");
    }

    if (input::keyPressed(SDL_SCANCODE_F12)) {
        draw::reloadAll();
    }

    int option;
    switch(current_module)
    {
        case M_LOGO:
            if (!modules::logo::loop()) { modules::intro::init(); current_module = M_INTRO; }
            break;
        case M_INTRO:
            if (!modules::intro::loop()) { modules::menu::init(); current_module = M_MENU; }
            break;
        case M_PROLOGO_INTRO:
            if (!modules::prologo_intro::loop()) { modules::game::init(true); current_module = M_GAME; }
            break;
        case M_END:
            if (!modules::end_sequence::loop()) { modules::menu::init(); current_module = M_MENU; }
            break;
        case M_PROLOGO_END:
            if (!modules::end_prologo_sequence::loop()) { modules::end_sequence::init(true); current_module = M_END; }
            break;
        case M_MENU:
            option = modules::menu::loop();
            if (option != OPTION_NONE) {
                if (option == OPTION_EIXIR) return false;
                if (option == OPTION_PROLOGO)  { modules::prologo_intro::init(); current_module = M_PROLOGO_INTRO; }
                if (option == OPTION_JUGAR)  { modules::game::init(); current_module = M_GAME; }
                if (option == OPTION_TECLES)  { modules::menu_tecles::init(); current_module = M_MENU_TECLES; }
                if (option == OPTION_GAMEPAD)  { modules::menu_gamepad::init(); current_module = M_MENU_GAMEPAD; }
                if (option == OPTION_AUDIO)  { modules::menu_audio::init(); current_module = M_MENU_AUDIO; }
            }
            break;
        case M_GAME:
            option = modules::game::loop();
            if (option!=GAME_NONE) { 
                if (option==GAME_MENU) {
                    if (editor::isDevMode()) {
                        return false;
                    } else {
                        modules::ingame::init(); current_module = M_INGAME;
                    }
                } else if (option==GAME_DEAD) {
                    if (actor::stats::catsLife()) {
                        modules::catslife::init(); current_module = M_CATSLIFE;
                    } else {
                        modules::gameover::init(); current_module = M_GAMEOVER;
                    }
                } else if (option==GAME_EDITOR_MAP) {
                    modules::editor_map::init(); current_module = M_EDITOR_MAP;
                } else if (option==GAME_EDITOR_TEMPLATES) {
                    modules::editor_templates::init(); current_module = M_EDITOR_TEMPLATES;
                } else if (option==GAME_EDITOR_COLORS) {
                    modules::editor_colors::init(); current_module = M_EDITOR_COLORS;
                } else if (option==GAME_EDITOR_BITMAP_FILE) {
                    modules::editor_bitmap_file::init(); current_module = M_EDITOR_BITMAP_FILE;
                } else if (option==GAME_EDITOR_BITMAP_POS) {
                    modules::editor_bitmap::init(EDITING_BITMAP_POS); current_module = M_EDITOR_BITMAP;
                } else if (option==GAME_EDITOR_BITMAP_SIZE) {
                    modules::editor_bitmap::init(EDITING_BITMAP_SIZE); current_module = M_EDITOR_BITMAP;
                } else if (option==GAME_END) {
                    modules::end_sequence::init(); current_module = M_END;
                } else if (option==GAME_PROLOGO_END) {
                    modules::end_prologo_sequence::init(); current_module = M_PROLOGO_END;
                }

            }
            break;
        case M_EDITOR_MAP:
            if (!modules::editor_map::loop()) {
                current_module = M_GAME;
            }
            break;
        case M_EDITOR_TEMPLATES:
            if (!modules::editor_templates::loop()) {
                current_module = M_GAME;
            }
            break;
        case M_EDITOR_COLORS:
            if (!modules::editor_colors::loop()) {
                current_module = M_GAME;
            }
            break;
        case M_EDITOR_BITMAP_FILE:
            if (!modules::editor_bitmap_file::loop()) {
                current_module = M_GAME;
            }
            break;
        case M_EDITOR_BITMAP:
            if (!modules::editor_bitmap::loop()) {
                current_module = M_GAME;
            }
            break;
        case M_INGAME:
            option = modules::ingame::loop();
            if (option != INGAME_NONE) {
                if (option == INGAME_EIXIR) { modules::menu::init(); current_module = M_MENU; }
                if (option == INGAME_CONTINUAR)  { current_module = M_GAME; }
            }
            break;
        case M_GAMEOVER:
            if (!modules::gameover::loop()) {
                modules::menu::init(); current_module = M_MENU;
            }
            break;
        case M_CATSLIFE:
            if (!modules::catslife::loop()) {
                actor::hero::init(false);
                actor::hero::setLives(1);
                room::reload();
                current_module = M_GAME;
            }
            break;
        case M_MENU_TECLES:
            if (modules::menu_tecles::loop() == MENU_TECLES_TORNAR) {
                modules::menu::init(); current_module = M_MENU;
            }
            break;
        case M_MENU_GAMEPAD:
            if (modules::menu_gamepad::loop() == MENU_GAMEPAD_TORNAR) {
                modules::menu::init(); current_module = M_MENU;
            }
            break;
        case M_MENU_AUDIO:
            if (modules::menu_audio::loop() == MENU_AUDIO_TORNAR) {
                modules::menu::init(); current_module = M_MENU;
            }
            break;
    };
    return true;
}