/*
 * Gearcoleco - ColecoVision Emulator
 * Copyright (C) 2021  Ignacio Sanchez

 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses/
 *
 */

#ifndef CONFIG_H
#define	CONFIG_H

#include <SDL.h>
#include "../../src/gearcoleco.h"
#define MINI_CASE_SENSITIVE
#include "mINI/ini.h"
#include "imgui/imgui.h"

#ifdef CONFIG_IMPORT
    #define EXTERN
#else
    #define EXTERN extern
#endif

static const int config_max_recent_roms = 10;

struct config_Emulator
{
    bool maximized = false;
    bool fullscreen = false;
    bool always_show_menu = false;
    bool paused = false;
    int save_slot = 0;
    bool start_paused = false;
    bool pause_when_inactive = true;
    bool ffwd = false;
    int ffwd_speed = 1;
    int region = 0;
    bool show_info = false;
    std::string recent_roms[config_max_recent_roms];
    std::string bios_path;
    int savefiles_dir_option = 0;
    std::string savefiles_path;
    int savestates_dir_option = 0;
    std::string savestates_path;
    std::string last_open_path;
    int window_width = 770;
    int window_height = 600;
    int spinner = 0;
    int spinner_sensitivity = 0;
    bool capture_mouse = false;
    bool status_messages = false;
};

struct config_Video
{
    int scale = 0;
    int scale_manual = 1;
    int ratio = 1;
    int overscan = 1;
    bool fps = false;
    bool bilinear = false;
    bool sprite_limit = false;
    bool mix_frames = true;
    float mix_frames_intensity = 0.60f;
    bool scanlines = true;
    bool scanlines_filter = true;
    float scanlines_intensity = 0.10f;
    bool sync = true;
    int palette = 0;
    GC_Color color[16] = {
        {255, 0, 255}, {0, 0, 0}, {33, 200, 66}, {94, 220, 120},
        {84, 85, 237}, {125, 118, 252}, {212, 82, 77}, {66, 235, 245},
        {252, 85, 84}, {255, 121, 120}, {212, 193, 84}, {230, 206, 128},
        {33, 176, 59}, {201, 91, 186}, {204, 204, 204}, {255, 255, 255}
    };
};

struct config_Audio
{
    bool enable = true;
    bool sync = true;
};

struct config_Input
{
    SDL_Scancode key_left;
    SDL_Scancode key_right;
    SDL_Scancode key_up;
    SDL_Scancode key_down;
    SDL_Scancode key_left_button;
    SDL_Scancode key_right_button;
    SDL_Scancode key_blue;
    SDL_Scancode key_purple;
    SDL_Scancode key_0;
    SDL_Scancode key_1;
    SDL_Scancode key_2;
    SDL_Scancode key_3;
    SDL_Scancode key_4;
    SDL_Scancode key_5;
    SDL_Scancode key_6;
    SDL_Scancode key_7;
    SDL_Scancode key_8;
    SDL_Scancode key_9;
    SDL_Scancode key_asterisk;
    SDL_Scancode key_hash;
    bool gamepad;
    int gamepad_directional;
    bool gamepad_invert_x_axis;
    bool gamepad_invert_y_axis;
    int gamepad_left_button;
    int gamepad_right_button;
    int gamepad_blue;
    int gamepad_purple;
    int gamepad_x_axis;
    int gamepad_y_axis;
    int gamepad_1;
    int gamepad_2;
    int gamepad_3;
    int gamepad_4;
    int gamepad_5;
    int gamepad_6;
    int gamepad_7;
    int gamepad_8;
    int gamepad_9;
    int gamepad_0;
    int gamepad_asterisk;
    int gamepad_hash;
};

enum config_HotkeyIndex
{
    config_HotkeyIndex_OpenROM = 0,
    config_HotkeyIndex_Quit,
    config_HotkeyIndex_Reset,
    config_HotkeyIndex_Pause,
    config_HotkeyIndex_FFWD,
    config_HotkeyIndex_SaveState,
    config_HotkeyIndex_LoadState,
    config_HotkeyIndex_Screenshot,
    config_HotkeyIndex_Fullscreen,
    config_HotkeyIndex_CaptureMouse,
    config_HotkeyIndex_ShowMainMenu,
    config_HotkeyIndex_DebugStep,
    config_HotkeyIndex_DebugContinue,
    config_HotkeyIndex_DebugNextFrame,
    config_HotkeyIndex_DebugRunToCursor,
    config_HotkeyIndex_DebugBreakpoint,
    config_HotkeyIndex_DebugGoBack,
    config_HotkeyIndex_SelectSlot1,
    config_HotkeyIndex_SelectSlot2,
    config_HotkeyIndex_SelectSlot3,
    config_HotkeyIndex_SelectSlot4,
    config_HotkeyIndex_SelectSlot5,
    config_HotkeyIndex_COUNT
};

struct config_Input_Gamepad_Shortcuts
{
    int gamepad_shortcuts[config_HotkeyIndex_COUNT];
};

struct config_Hotkey
{
    SDL_Scancode key;
    SDL_Keymod mod;
    char str[64];
};

struct config_Debug
{
    bool debug = false;
    bool show_screen = true;
    bool show_disassembler = true;
    bool show_processor = true;
    bool show_memory = true;
    bool show_video = false;
    bool show_video_registers = true;
    int font_size = 0;
    bool multi_viewport = false;
};

EXTERN mINI::INIFile* config_ini_file;
EXTERN mINI::INIStructure config_ini_data;
EXTERN char* config_root_path;
EXTERN char config_emu_file_path[260];
EXTERN char config_imgui_file_path[260];
EXTERN config_Emulator config_emulator;
EXTERN config_Video config_video;
EXTERN config_Audio config_audio;
EXTERN config_Input config_input[2];
EXTERN config_Input_Gamepad_Shortcuts config_input_gamepad_shortcuts[2];
EXTERN config_Hotkey config_hotkeys[config_HotkeyIndex_COUNT];
EXTERN config_Debug config_debug;

EXTERN void config_init(void);
EXTERN void config_destroy(void);
EXTERN void config_read(void);
EXTERN void config_write(void);
EXTERN void config_update_hotkey_string(config_Hotkey* hotkey);

#undef CONFIG_IMPORT
#undef EXTERN
#endif	/* CONFIG_H */
