#include "player.h"
#include "application.h"
#include "resources.h"
#include "factory_objects.h"
#include "utils.h"
#include "tween.h"
#include "level.h"
#include "scenes.h"
#include "font.h"
#include "ui.h"

typedef struct player_s
{
    actor_robo_t       *actor_robo;
    actor_checkpoint_t *actor_checkpoint;
    int                 count_coins;
    int                 count_diamonds;
    int                 count_gears;
    int                 health;
    int                 endgame_counter;
    int                 endgame_counter_sleep;
    bool                show_question;
    bool                show_endgame;
    bool                show_restart;
    SDL_Rect            hud_frame;
    SDL_Rect            hud_draw;
    SDL_Rect            hud_question_frame;
    SDL_Rect            hud_question_draw;
    SDL_Rect            label_endgame_draw;
    SDL_Rect            label_restart_draw;
    tween_param_t      *hud_question_y_tween;
    button_t           *exit_button;
    button_t           *yes_button;
    button_t           *no_button;
} player_t;

static player_t player;

static void _Player_HideHudQuestion(void)
{
    int app_height2 = (Uint32)(Application_GetHeight() /2);
    player.show_question = false;
    Tween_ParamResetValues(player.hud_question_y_tween, app_height2 - 82,  -165);
    Tween_ParamRun(player.hud_question_y_tween);

    Scene_Game_Play();
}

static void _Player_OpenHudQuestion(void)
{
    int app_height2 = (Uint32)(Application_GetHeight() /2);
    player.show_question = true;
    Tween_ParamResetValues(player.hud_question_y_tween, -165, app_height2 - 82);
    Tween_ParamRun(player.hud_question_y_tween);

    Scene_Game_Pause();
}

void Player_Init(void)
{
    player.actor_robo       = NULL;
    player.actor_checkpoint = NULL;
    player.count_coins      = 0;
    player.count_diamonds   = 0;
    player.count_gears      = 1;
    player.health           = 10;
    player.endgame_counter       = 9;
    player.endgame_counter_sleep = 0;

    player.show_question = false;
    player.show_endgame  = false;
    player.show_restart  = false;

    player.hud_frame            = Utils_GetRect(0, 0, 240, 14);
    player.hud_draw             = Utils_GetRect(0, 0, 720, 42);
    player.hud_question_frame   = Utils_GetRect(0, 0, 76,  55);
    player.hud_question_draw    = Utils_GetRect(0, 0, 228, 165);
    player.label_endgame_draw   = Utils_GetRect(0, 0, 165, 33);
    player.label_restart_draw   = Utils_GetRect(0, 0, 489, 33);

    player.hud_question_y_tween = Tween_ParamCreate(800, 0, 50, EASE_OUT_CUBIC);

    player.exit_button = UI_Button_Create(btn_exitTex, 0, 0, 29, 13, 87, 39);
    player.yes_button  = UI_Button_Create(btn_yesTex,  0, 0, 22, 13, 66, 39);
    player.no_button   = UI_Button_Create(btn_noTex,   0, 0, 22, 13, 66, 39);

    int app_width2  = (Uint32)(Application_GetWidth() /2);
    int app_height2 = (Uint32)(Application_GetHeight() /2);

    player.hud_draw.x          = app_width2 - 360;
    player.hud_question_draw.x = app_width2 - 114;
    player.hud_question_draw.y = app_height2 - 82;

    player.label_endgame_draw.x = app_width2 - 82;
    player.label_endgame_draw.y = app_height2 - 240;
    player.label_restart_draw.x = app_width2 - 245;
    player.label_restart_draw.y = app_height2 - 240;

    Tween_ParamResetValues(player.hud_question_y_tween, -165, app_height2 - 82);

    UI_Button_SetPosition(player.exit_button, Application_GetWidth() - 90, player.hud_draw.y);
}

void Player_ReInit(void)
{
    int app_width2  = (Uint32)(Application_GetWidth() /2);
    int app_height2 = (Uint32)(Application_GetHeight() /2);

    player.hud_draw.x          = app_width2 - 360;
    player.hud_question_draw.x = app_width2 - 114;
    player.hud_question_draw.y = app_height2 - 82;

    player.label_endgame_draw.x = app_width2 - 82;
    player.label_endgame_draw.y = app_height2 - 240;
    player.label_restart_draw.x = app_width2 - 245;
    player.label_restart_draw.y = app_height2 - 240;

    UI_Button_SetPosition(player.exit_button, Application_GetWidth() - 90, player.hud_draw.y);

    player.actor_checkpoint = NULL;
    player.count_coins      = 0;
    player.count_diamonds   = 0;
    player.count_gears      = 1;
    player.health           = 10;
    player.endgame_counter       = 9;
    player.endgame_counter_sleep = 0;

    player.show_question = false;
    player.show_endgame  = false;
    player.show_restart  = false;

    Tween_ParamResetValues(player.hud_question_y_tween, -165, -165);
}

int  Player_GetHealth(void)
{
    return player.health;
}

void Player_SetHealth(int health)
{
    player.health = health;

    if (player.health < 0)
        player.health = 0;

    if (player.health > 10)
        player.health = 10;
}

void Player_IncCoin(void)
{
    player.count_coins++;
}

void Player_IncDiamond(void)
{
    player.count_diamonds++;
}

void Player_IncGear(void)
{
    player.count_gears++;
}

void Player_ToggleVisibilityHudQuestion(void)
{
    if (player.show_question)
         _Player_HideHudQuestion();
    else _Player_OpenHudQuestion();
}

void Player_Update(void)
{
    if (!Scene_Game_IsPause())
    {
        if (player.actor_robo != NULL)
        {
            // state live

            if (Application_IsKeyDown(KEY_SPACE))
                Actor_Robo_ControllSpace(player.actor_robo);

            if (Application_IsKeyPress(KEY_UP))
                Actor_Robo_ControllUp(player.actor_robo);

            if (Application_IsKeyPress(KEY_RIGHT))
                Actor_Robo_ControllRight(player.actor_robo);

            if (Application_IsKeyPress(KEY_DOWN))
                Actor_Robo_ControllDown(player.actor_robo);

            if (Application_IsKeyPress(KEY_LEFT))
                Actor_Robo_ControllLeft(player.actor_robo);
        }
        else
        {
            // state dead
            if (player.count_gears > 0)
            {
                if (Application_IsKeyDown(KEY_SPACE))
                {
                    vector_t position = Utils_GetVector(0, 0);

                    if (player.actor_checkpoint != NULL)
                         position = Actor_Checkpoint_GetPosition(player.actor_checkpoint);
                    else position = Level_GetPositionStart();

                    object_t *object  = FactoryObjects_Create();
                    player.actor_robo = Actor_Robo_Create(object, position.x, position.y);

                    Actor_Robo_ConnectCheckpoint(player.actor_robo, player.actor_checkpoint);

                    player.count_gears--;

                    player.show_restart = false;
                }
            }
        }

        if (player.show_endgame)
        {
            player.endgame_counter_sleep++;

            if (player.endgame_counter_sleep > 50)
            {
                player.endgame_counter_sleep = 0;

                player.endgame_counter--;

                if (player.endgame_counter < 0)
                {
                    player.endgame_counter = 0;
                    Scene_Set(SCENE_MENU);
                }
            }
        }
    }

    UI_Button_Update(player.exit_button);

    if (UI_Button_IsClick(player.exit_button))
    {
        Mix_PlayChannel(-1, clickSnd, 0);
        Player_ToggleVisibilityHudQuestion();
    }

    player.hud_question_draw.y = (Uint32)Tween_ParamGetValue(player.hud_question_y_tween);

    if (player.hud_question_draw.y > -165)
    {
        UI_Button_SetPosition(player.yes_button,  player.hud_question_draw.x + 81, player.hud_question_draw.y + 51);
        UI_Button_SetPosition(player.no_button,   player.hud_question_draw.x + 81, player.hud_question_draw.y + 105);

        UI_Button_Update(player.yes_button);
        UI_Button_Update(player.no_button);

        if (UI_Button_IsClick(player.yes_button))
        {
            Mix_PlayChannel(-1, clickSnd, 0);
            Scene_Set(SCENE_MENU);
        }

        if (UI_Button_IsClick(player.no_button))
        {
            Mix_PlayChannel(-1, clickSnd, 0);
            _Player_HideHudQuestion();
        }
    }
}

void Player_DrawHUD(SDL_Renderer *renderer)
{
    if (player.show_endgame)
    {
        SDL_RenderCopy(renderer, label_endgameTex, NULL, &player.label_endgame_draw);
        Font_DrawNumber(renderer, player.label_endgame_draw.x + 82, player.label_endgame_draw.y + 39, player.endgame_counter, FNT_LIGHT);
    }

    if (player.show_restart)
        SDL_RenderCopy(renderer, label_restartTex, NULL, &player.label_restart_draw);

    if (player.hud_question_draw.y > -165)
    {
        SDL_RenderCopy(renderer, hud_questionTex, &player.hud_question_frame, &player.hud_question_draw);

        UI_Button_Draw(renderer, player.yes_button);
        UI_Button_Draw(renderer, player.no_button);
    }

    SDL_Rect health_frame = Utils_GetRect(0, 0, (player.health * 3), 8);
    SDL_Rect health_draw  = Utils_GetRect(0, 0, health_frame.w * 3, 24);

    health_draw.x = player.hud_draw.x + 159;
    health_draw.y = player.hud_draw.y + 6;

    SDL_RenderCopy(renderer, hudTex, &player.hud_frame, &player.hud_draw);
    SDL_RenderCopy(renderer, healthTex, &health_frame, &health_draw);
    Font_DrawNumber(renderer, player.hud_draw.x + 324, player.hud_draw.y + 12, player.count_gears, FNT_DARK);
    Font_DrawNumber(renderer, player.hud_draw.x + 417, player.hud_draw.y + 12, player.count_coins, FNT_DARK);
    Font_DrawNumber(renderer, player.hud_draw.x + 513, player.hud_draw.y + 12, player.count_diamonds, FNT_DARK);
    Font_DrawNumber(renderer, player.hud_draw.x + 681, player.hud_draw.y + 12, Scene_Game_GetLevel(), FNT_DARK);


    UI_Button_Draw(renderer, player.exit_button);
}

void Player_BindCheckpoint(actor_checkpoint_t *actor_checkpoint)
{
    player.actor_checkpoint = actor_checkpoint;
}

void Player_BindRobo(actor_robo_t *actor_robo)
{
    player.actor_robo = actor_robo;
}

void Player_UnbindRobo(bool in_teleport)
{
    player.actor_robo = NULL;

    if (!in_teleport)
    {
        if (player.count_gears > 0)
             player.show_restart = true;
        else player.show_endgame = true;
    }
}

void Player_Quit(void)
{
    player.actor_robo       = NULL;
    player.actor_checkpoint = NULL;

    Tween_ParamDelete(player.hud_question_y_tween);
    UI_Button_Free(player.exit_button);
    UI_Button_Free(player.yes_button);
    UI_Button_Free(player.no_button);
}
