#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>

#include "gameover.h"
#include "gamestate.h"
#include "main.h"

#define GAMEOVER_TexturePath        "assets/images/gameover.png"
#define GAMEOVER_NumbersTexturePath "assets/images/numbers.png"
#define GAMEOVER_ScoreTexturePath   "assets/images/yourscore.png"
#define GAMEOVER_HUDScale           16.0f
#define GAMEOVER_Scale              4.0f

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>

#include "breakout.h"
#include "vector.h"
#include "background.h"

int GAMEOVER_HUDMargin = 5;
SDL_Texture * GAMEOVER_Texture;
SDL_Texture * GAMEOVER_Numbers;
SDL_Texture * GAMEOVER_ScoreTexture;
SDL_Rect * GAMEOVER_NumberRects;
SDL_Rect GAMEOVER_TargetRect;
SDL_Rect GAMEOVER_ScoreTargetRect;
SDL_Rect GAMEOVER_HUDScoreTargetRect;
int * GAMEOVER_Digits;
bool GAMEOVER_IsInit = false;

void GAMEOVER_Initialize(SDL_Renderer * renderer){
    if (!GAMEOVER_IsInit) {
        printf("Initializing Gameover...\n");
        GAMEOVER_Texture = IMG_LoadTexture(renderer, GAMEOVER_TexturePath);
        if (!GAMEOVER_Texture) printf("Gameover Texture couldn't be loaded!\n");
        GAMEOVER_Numbers = IMG_LoadTexture(renderer, GAMEOVER_NumbersTexturePath);
        if (!GAMEOVER_Numbers) printf("Gameover Numbers couldn't be loaded!\n");
        GAMEOVER_ScoreTexture = IMG_LoadTexture(renderer, GAMEOVER_ScoreTexturePath);
        if (!GAMEOVER_ScoreTexture) printf("Gameover Score Texture couldn't be loaded!\n");
        int w, h;
        SDL_QueryTexture(GAMEOVER_Texture, NULL, NULL, &w, &h);
        w /= 2;
        h /= 2;
        GAMEOVER_TargetRect.x = ((1920 - w) / 2);
        GAMEOVER_TargetRect.y = 50;
        GAMEOVER_TargetRect.w = w;
        GAMEOVER_TargetRect.h = h;
        GAMEOVER_NumberRects = calloc(10, sizeof(SDL_Rect));
        if (!GAMEOVER_NumberRects) printf("FATAL: Memory Allocation Failed!\n");
        GAMEOVER_NumberRects[0] = (SDL_Rect) {.x = 446, .y = 668, .w = 442, .h = 665 };
        GAMEOVER_NumberRects[1] = (SDL_Rect) {.x = 1299, .y = 1335, .w = 242, .h = 665 };
        GAMEOVER_NumberRects[2] = (SDL_Rect) {.x = 1, .y = 1, .w = 443, .h = 665 };
        GAMEOVER_NumberRects[3] = (SDL_Rect) {.x = 1, .y = 668, .w = 443, .h = 665 };
        GAMEOVER_NumberRects[4] = (SDL_Rect) {.x = 1, .y = 1335, .w = 443, .h = 665 };
        GAMEOVER_NumberRects[5] = (SDL_Rect) {.x = 446, .y = 1, .w = 443, .h = 665 };
        GAMEOVER_NumberRects[6] = (SDL_Rect) {.x = 891, .y = 1, .w = 443, .h = 665 };
        GAMEOVER_NumberRects[7] = (SDL_Rect) {.x = 890, .y = 1335, .w = 407, .h = 665 };
        GAMEOVER_NumberRects[8] = (SDL_Rect) {.x = 446, .y = 1335, .w = 442, .h = 665 };
        GAMEOVER_NumberRects[9] = (SDL_Rect) {.x = 890, .y = 668, .w = 442, .h = 665 };
        GAMEOVER_ScoreTargetRect.y = 450;
        GAMEOVER_ScoreTargetRect.h = 183;
        GAMEOVER_ScoreTargetRect.w = 1000;
        GAMEOVER_HUDScoreTargetRect = (SDL_Rect) {.x = GAMEOVER_HUDMargin, .y = GAMEOVER_HUDMargin, .w = 250, .h = 46 };
        GAMEOVER_Digits = malloc(25 * sizeof(int));
        printf("Gameover initialized!\n");
        GAMEOVER_IsInit = true;
    } else
        printf("Gameover already initialized!\n");
} /* GAMEOVER_Initialize */

void GAMEOVER_Draw(SDL_Renderer * renderer, Scenery * scenery){
    int i, count;

    SDL_RenderCopy(renderer, GAMEOVER_Texture, NULL, &GAMEOVER_TargetRect);
    GAMEOVER_GetDigits((scenery->Score), &count);
    int totalWidth = GAMEOVER_ScoreTargetRect.w;
    for (i = (count - 1); i >= 0; i--) {
        totalWidth += (int)roundf((float)GAMEOVER_NumberRects[i].w / GAMEOVER_Scale);
    }
    GAMEOVER_ScoreTargetRect.x = ((1920 - totalWidth) / 2);
    SDL_RenderCopy(renderer, GAMEOVER_ScoreTexture, NULL, &GAMEOVER_ScoreTargetRect);
    int xOffset = GAMEOVER_ScoreTargetRect.x + GAMEOVER_ScoreTargetRect.w;
    SDL_Rect target;
    target.y = 450;
    for (i = (count - 1); i >= 0; i--) {
        target.x = xOffset;
        target.h = (int)roundf((float)(GAMEOVER_NumberRects[GAMEOVER_Digits[i]].h) / GAMEOVER_Scale);
        target.w = (int)roundf((float)(GAMEOVER_NumberRects[GAMEOVER_Digits[i]].w) / GAMEOVER_Scale);
        SDL_RenderCopy(renderer, GAMEOVER_Numbers, (GAMEOVER_NumberRects + GAMEOVER_Digits[i]), &target);
        xOffset += target.w;
    }
} /* GAMEOVER_Draw */

void GAMEOVER_GetDigits(int input, int * digitCount){
    int score = input;
    int count = 0;

    while (score != 0) {
        GAMEOVER_Digits[(count++)] = (score % 10);
        score /= 10;
    }
    if (count == 0) {
        count = 1;
        GAMEOVER_Digits[0] = 0;
    }
    *digitCount = count;
}

void SCORE_DrawHUD(SDL_Renderer * renderer, Scenery * scenery){
    int i, count;

    GAMEOVER_GetDigits((scenery->Score), &count);
    int totalWidth = GAMEOVER_HUDScoreTargetRect.w;
    for (i = (count - 1); i >= 0; i--) {
        totalWidth += (int)roundf((float)GAMEOVER_NumberRects[i].w / GAMEOVER_HUDScale);
    }
    GAMEOVER_HUDScoreTargetRect.x = GAMEOVER_HUDMargin;
    SDL_RenderCopy(renderer, GAMEOVER_ScoreTexture, NULL, &GAMEOVER_HUDScoreTargetRect);
    int xOffset = GAMEOVER_HUDScoreTargetRect.x + GAMEOVER_HUDScoreTargetRect.w;
    SDL_Rect target;
    target.y = GAMEOVER_HUDMargin;
    for (i = (count - 1); i >= 0; i--) {
        target.x = xOffset;
        target.h = (int)roundf((float)(GAMEOVER_NumberRects[GAMEOVER_Digits[i]].h) / GAMEOVER_HUDScale);
        target.w = (int)roundf((float)(GAMEOVER_NumberRects[GAMEOVER_Digits[i]].w) / GAMEOVER_HUDScale);
        SDL_RenderCopy(renderer, GAMEOVER_Numbers, (GAMEOVER_NumberRects + GAMEOVER_Digits[i]), &target);
        xOffset += target.w;
    }
} /* SCORE_DrawHUD */

void GAMEOVER_Deinitialize(){
    if (GAMEOVER_IsInit) {
        printf("De-initializing Gameover...\n");
        free(GAMEOVER_Digits);
        SDL_DestroyTexture(GAMEOVER_Texture);
        SDL_DestroyTexture(GAMEOVER_ScoreTexture);
        SDL_DestroyTexture(GAMEOVER_Numbers);
        printf("Gameover de-initialized!\n");
        GAMEOVER_IsInit = false;
    } else
        printf("Gameover already de-initialized!\n");
}
