#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include <time.h>

#include "graphical-aspect.h"
#include "networld.h"
#include "controlpanel.h"
#include "player.h"

#include "raylib.h"




void Graphic_ShowPlayerInfo(Player * player, int screenWidth, int screenHeight, Font font){
    Rectangle rec = {0, screenHeight - 250, 250, 250}; 
    DrawRectangleLinesEx(rec, 10, player->color);
    //Font font = LoadFont("Game On_PersonalUseOnly.ttf");
    char * playerNumber = malloc(20*sizeof(char));
    sprintf(playerNumber, "Player %d", player->ID);
    DrawTextEx(font, playerNumber, (Vector2){35, screenHeight - 240}, 30.0, 3.0, player->color);

    char * soldierNumber = malloc(40*sizeof(char));
    sprintf(soldierNumber, "Soldiers left  %d", player->soldiers);
    DrawTextEx(font, soldierNumber, (Vector2){15, screenHeight - 180}, 24.0, 3.0, player->color);

    int totalTroops = 0;
    for(int i =0; i < player->nodeCount; i++){
        totalTroops += player->nodes[i]->soldiers;
    }
    char * str_totalTroops = malloc(40*sizeof(char));
    sprintf(str_totalTroops, "Total Troops  %d", totalTroops);
    DrawTextEx(font, str_totalTroops, (Vector2){15, screenHeight - 150}, 24.0, 3.0, player->color);

    char * str_nodeCount = malloc(40*sizeof(char));
    sprintf(str_nodeCount, "Nodes owned  %d", player->nodeCount);
    DrawTextEx(font, str_nodeCount, (Vector2){15, screenHeight - 120}, 24.0, 3.0, player->color);

    free(playerNumber);
    free(soldierNumber);
    free(str_totalTroops);
    free(str_nodeCount);
}

void Graphic_RecrutementPhase(Player * player, int screenWidth, int screenHeight, Font font){
    Rectangle rec = {screenWidth-300, 100 , 300, 400}; 
    DrawRectangleLinesEx(rec, 10, player->color);
    DrawTextEx(font, "Recrutement Phase",(Vector2){screenWidth-275, 120}, 23.0, 3.0, player->color);
    DrawTextRec(font, "   LEFT click on one of your node to recruit a soldier", (Rectangle){screenWidth-285, 175, 270, 100}, 20.0, 3.0, true, player->color);
    DrawTextRec(font, "   RIGHT click on the same node to remove the soldier", (Rectangle){screenWidth-285, 295, 270, 100}, 20.0, 3.0, true, player->color);
    DrawTextRec(font, "   click Confirm once finished", (Rectangle){screenWidth-285, 415, 270, 100}, 20.0, 3.0, true, player->color);

}
void Graphic_AttackPhase(Player * player, int screenWidth, int screenHeight, Font font){
    Rectangle rec = {screenWidth-300, 100 , 300, 450}; 
    DrawRectangleLinesEx(rec, 10, player->color);
    DrawTextEx(font, "Attack Phase",(Vector2){screenWidth-265, 120}, 23.0, 3.0, player->color);
    DrawTextRec(font, "   FIRST click on the node you want to attack from", (Rectangle){screenWidth-285, 175, 270, 100}, 20.0, 3.0, true, player->color);
    DrawTextRec(font, "   THEN click on one of neighbouring node you want to attack", (Rectangle){screenWidth-285, 295, 270, 100}, 20.0, 3.0, true, player->color);
    DrawTextRec(font, "   click Next Turn once finished all your attacks", (Rectangle){screenWidth-285, 415, 270, 100}, 20.0, 3.0, true, player->color);
}

void Graphic_WhoseTurnIsIt(Player * player, int screenWidth, int screenHeight, Font font){
    //Rectangle rec = {0, screenHeight - 250, 250, 250}; 
    //DrawRectangleLinesEx(rec, 10, player->color);
    //Font font = LoadFont("Game On_PersonalUseOnly.ttf");
    char * whoseTurn = malloc(20*sizeof(char));
    sprintf(whoseTurn, "Player %d Turn", player->ID);
    DrawTextEx(font, whoseTurn, (Vector2){screenWidth/2 - (MeasureTextEx(font, whoseTurn, 50.0, 3.0).x)/2 , 30}  , 50.0, 3.0, player->color);

    free(whoseTurn);
}

Rectangle Graphic_ConfirmButton(Font font)
{
    Rectangle nextPhase = {200, 200, 220, 55};     
    DrawRectangleRec(nextPhase, GREEN);
    DrawTextEx(font, "Confirm",(Vector2){220 , 210} , 40.0, 3.0, BLACK); 
    return nextPhase;
}

void Graphic_MouseHoverNodeRecrutement(Player * player, Vector2 mousePosition, Panel * panel){
    for(int nodeIndex = 0; nodeIndex < player->nodeCount; nodeIndex++){
        Node* currentNode = player->nodes[nodeIndex];
        if(CheckCollisionPointRec(mousePosition, currentNode->collisionHitbox)){
            //printf("collision noeud !\n");
            Vector2 screenPosition= Panel_pixelFromPosition(panel, &(currentNode->position) );        
            DrawRing(screenPosition, 24.0, 28.0, 0.0, 360.0, 0.1, MAGENTA);
            //DrawCircleV(screenPosition, 45, RAYWHITE);
            if(player->soldiers > 0){
                DrawText("+1", (int)screenPosition.x + 30 , (int)screenPosition.y, 20, MAGENTA);
            }
        }
    }
    
}

void Graphic_MouseHoverNodeChooseAttacker(Player * player, Vector2 mousePosition, Panel * panel){
    for(int nodeIndex = 0; nodeIndex < player->nodeCount; nodeIndex++){
        Node* currentNode = player->nodes[nodeIndex];
        if(CheckCollisionPointRec(mousePosition, currentNode->collisionHitbox)){
            Vector2 screenPosition= Panel_pixelFromPosition(panel, &(currentNode->position) );
            DrawRing(screenPosition, 24.0, 28.0, 0.0, 360.0, 0.1, GOLD);
            //DrawCircleV(screenPosition, 45, RAYWHITE);
            if(!player->hasSelectedNode){
                DrawText("attacker", (int)screenPosition.x + 30 , (int)screenPosition.y, 20, GOLD);
            }    
        }
    }
    if(player->hasSelectedNode){
        Vector2 screenPosition= Panel_pixelFromPosition(panel, &(player->selectedNode->position) );
        DrawRing(screenPosition, 24.0, 28.0, 0.0, 360.0, 0.1, GOLD);
        DrawText("attacker", (int)screenPosition.x + 30 , (int)screenPosition.y, 20, GOLD);
    }
}
void Graphic_MouseHoverNodeChooseTarget(Node * originNode, Vector2 mousePosition, Panel * panel){
    for(int neighbourIndex = 0; neighbourIndex < originNode->card; neighbourIndex++){
        Vector2 screenPosition = Panel_pixelFromPosition(panel, &(originNode->edges[neighbourIndex]._target->position) );
        if( &(originNode->edges[neighbourIndex]._target->color) != &(originNode->color)){          
            DrawRing(screenPosition, 24.0, 30.0, 0.0, 360.0, 0.1, GREEN);
        } 
        if(CheckCollisionPointRec(mousePosition, originNode->edges[neighbourIndex]._target->collisionHitbox) && &(originNode->edges[neighbourIndex]._target->color) != &(originNode->color)){
            DrawRing(screenPosition, 30.0, 33.0, 0.0, 360.0, 0.1, MAROON);
        }
    }
}







#define MAX_FRAME_SPEED     15
#define MIN_FRAME_SPEED      1

int Graphic_ChooseNumberOfAttackers(Player * attacker, Player * defender, Node * originNode, Node * targetNode, Font font)
{      

    // Initialization
    //--------------------------------------------------------------------------------------
    const int screenWidth = 1700;
    const int screenHeight = 800;
    bool endAnimation = false;
    SetTargetFPS(60);               // Set our game to run at 60 frames-per-second

    Rectangle * nbAttackerRectangle = malloc(10*sizeof(Rectangle));
    printf("number dice avail %d \n", originNode->soldiersToAdd + originNode->soldiers );
    for(int i = 0 ; i <  originNode->soldiersToAdd + originNode->soldiers ; i ++){
        nbAttackerRectangle[i] = (Rectangle){200 + (i-1)*250, screenHeight - 500, 150, 70};
        printf("rectangle %d position : %f %f \n", i, nbAttackerRectangle[i].x, nbAttackerRectangle[i].y);
    }
    char * whoseTurnToAttack = malloc(20*sizeof(char));
    sprintf(whoseTurnToAttack, "Player %d attacks ", attacker->ID);
    char * whoseTurnToDefend = malloc(20*sizeof(char));
    sprintf(whoseTurnToDefend, "Player %d", defender->ID);
   

    //--------------------------------------------------------------------------------------

    // Main game loop
    while (!endAnimation )    // Detect window close button or ESC key
    {

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);
            Vector2 mousePosition = GetMousePosition(); 

            DrawTextEx(font, whoseTurnToAttack, (Vector2){screenWidth/2 - (MeasureTextEx(font, whoseTurnToAttack, 50.0, 3.0).x) + 50 , 70}  , 50.0, 3.0, attacker->color);
            DrawTextEx(font, whoseTurnToDefend, (Vector2){screenWidth/2 + 50 , 70}, 50.0, 3.0, defender->color);
            DrawText("How many dices do you want to involve in the fight ?", screenWidth/2 - (MeasureTextEx(font, "How many dice do you want to involve in the fight ?", 30.0, 3.0).x)/2 + 50 , 150 , 30, attacker->color);
            for(int i = 1 ; i < originNode->soldiersToAdd + originNode->soldiers ; i ++){
                DrawRectangleRec(nbAttackerRectangle[i], BLACK);
                char * str_i = malloc(sizeof(int));
                sprintf(str_i, "%d", i);
                DrawTextEx(font, str_i, (Vector2){nbAttackerRectangle[i].x + 55, nbAttackerRectangle[i].y + 5 }, 70.0, 3.0, WHITE);
                free(str_i);
                if(CheckCollisionPointRec(mousePosition, nbAttackerRectangle[i])){
                        DrawRectangleLinesEx(nbAttackerRectangle[i], 5, GREEN);
                    }
                if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
                    if(CheckCollisionPointRec(mousePosition, nbAttackerRectangle[i])){
                        printf("colision dés choix %d \n", i);
                        return i;
                    }
                } 
            }

        EndDrawing();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    // Texture unloading
    free(whoseTurnToAttack);
    free(whoseTurnToDefend);
    free(nbAttackerRectangle);
    //--------------------------------------------------------------------------------------
    
}
void diceRolling(Player * attacker, Player * defender, Node * originNode, Node * targetNode, int nbOfAttackers, int * listOfDices, Font font)
{   
    printf("dice rolling begin\n");    

    // Initialization
    //--------------------------------------------------------------------------------------
    const int screenWidth = 1700;
    const int screenHeight = 800;

    // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
    Image texture =  LoadImage("diceRolling.png"); 
    ImageResize(&(texture), 100, 800);  
    //Texture2D diceTexture = LoadTexture("diceRolling.png");        // Texture loading
    Texture2D diceTexture = LoadTextureFromImage(texture);
    
    int defendersCount = targetNode->soldiers >= 3? 2:1;
    int attackersCount = nbOfAttackers;

    Rectangle frameRec = { 0.0f, 0.0f, (float)diceTexture.width, (float)diceTexture.height/9 };
    int currentFrame = 0;

    int framesCounter = 0;
    int framesSpeed = 7;  
    int frameExit =  0;        // Number of spritesheet frames shown by second
    bool endAnimationDice = false;
    bool endDisplayResult = false;
    SetTargetFPS(60);               // Set our game to run at 60 frames-per-second

    //--------------------------------------------------------------------------------------
    char * whoseTurnToAttack = malloc(20*sizeof(char));
    sprintf(whoseTurnToAttack, "Player %d ", attacker->ID);
    char * whoseTurnToDefend = malloc(20*sizeof(char));
    sprintf(whoseTurnToDefend, "Player %d ", defender->ID);

    Vector2 * positionDiceAttacker = malloc(20 * sizeof(Vector2));
    Vector2 * positionDiceDefender = malloc(20 * sizeof(Vector2));
    for(int i = 0 ; i < nbOfAttackers ; i++){
        positionDiceAttacker[i] = (Vector2){200 + (i)*150, screenHeight - 500};
    }
    for(int i = 0 ; i < defendersCount + 1 ; i++){
        positionDiceDefender[i] = (Vector2){1000 + (i)*150, screenHeight - 500};
        printf("position dice defender %d x : %f \n", i , positionDiceDefender[i].x);
        printf("position dice defender %d y : %f \n", i , positionDiceDefender[i].y);
    }

    // Main game loop
    while (!endAnimationDice )    // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------
        framesCounter++;
        frameExit++;
        //printf("%d frame before Exit0 \n", frameExit);
        if(frameExit == 200) endAnimationDice = true;
        if (framesCounter >= (60/framesSpeed))
        {
            framesCounter = 0;
            currentFrame++;

            if (currentFrame > 8) currentFrame = 0;

            frameRec.y = (float)currentFrame*(float)diceTexture.height/9;
        }
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);
            
            DrawTextEx(font, whoseTurnToAttack, (Vector2){250 , 200}  , 30.0, 3.0, attacker->color);
            DrawTextEx(font, whoseTurnToDefend, (Vector2){screenWidth-700, 200}, 30.0, 3.0, defender->color);
            DrawTextEx(font, " attacker", (Vector2){250 + MeasureTextEx(font, "Player X ", 30.0, 3.0).x , 210}  , 15.0, 3.0, attacker->color);
            DrawTextEx(font, " defender", (Vector2){screenWidth-700 + MeasureTextEx(font, "Player X ", 30.0, 3.0).x, 210}, 15.0, 3.0, defender->color);
            for(int i = 0 ; i < nbOfAttackers ; i++){
                DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
            }
            for(int i = 0 ; i <  defendersCount ; i++){
                DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i], WHITE);
            }

        EndDrawing();
        //----------------------------------------------------------------------------------
    }
    
    currentFrame = 0;
    framesCounter = 0;
    framesSpeed = 7;  
    endDisplayResult = false;

    while (!endDisplayResult )    // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------
        framesCounter++;
        frameExit++;
        //printf("%d frame before Exit1 \n", frameExit);
        if(frameExit == 450) endDisplayResult = true;
        if (framesCounter >= (60/framesSpeed))
        {
            framesCounter = 0;
            currentFrame++;

            if (currentFrame > 8) currentFrame = 0;

            frameRec.y = (float)currentFrame*(float)diceTexture.height/9;
        }
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);
            
            DrawTextEx(font, whoseTurnToAttack, (Vector2){250 , 200}  , 30.0, 3.0, attacker->color);
            DrawTextEx(font, whoseTurnToDefend, (Vector2){screenWidth-700, 200}, 30.0, 3.0, defender->color);
            DrawTextEx(font, " attacker", (Vector2){250 + MeasureTextEx(font, "Player X ", 30.0, 3.0).x , 210}  , 15.0, 3.0, attacker->color);
            DrawTextEx(font, " defender", (Vector2){screenWidth-700 + MeasureTextEx(font, "Player X ", 30.0, 3.0).x, 210}, 15.0, 3.0, defender->color);
            for(int i = 0 ; i < nbOfAttackers ; i++){
                switch (listOfDices[i])
                {
                case 1:
                    frameRec.y = 9*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
                    DrawTextEx(font, "1", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y+100}, 50.0, 3.0, BLACK);
                    break;
                case 2:
                    frameRec.y = 1*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
                    DrawTextEx(font, "2", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y+100}, 50.0, 3.0, BLACK);
                    break;
                case 3:
                    frameRec.y = 2*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
                    DrawTextEx(font, "3", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y+100}, 50.0, 3.0, BLACK);
                    break;
                case 4:
                    frameRec.y = 3*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
                    DrawTextEx(font, "4", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y+100}, 50.0, 3.0, BLACK);
                    break;
                case 5:
                    frameRec.y = 4*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
                    DrawTextEx(font, "5", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y+100}, 50.0, 3.0, BLACK);
                    break;
                case 6:
                    frameRec.y = 5*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
                    DrawTextEx(font, "6", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y+100}, 50.0, 3.0, BLACK);
                    break;
                
                default:
                    break;
                }
                //DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
            }
            for(int i = nbOfAttackers ; i <  nbOfAttackers + defendersCount +1; i++){
                switch (listOfDices[i])
                {
                case 1:
                    frameRec.y = 9*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i-nbOfAttackers], WHITE);
                    DrawTextEx(font, "1", (Vector2){positionDiceDefender[i-nbOfAttackers].x + 30, positionDiceDefender[i-nbOfAttackers].y + 100}, 50.0, 3.0, BLACK);
                    break;
                case 2:
                    frameRec.y = 1*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i-nbOfAttackers], WHITE);
                    DrawTextEx(font, "2", (Vector2){positionDiceDefender[i-nbOfAttackers].x + 30, positionDiceDefender[i-nbOfAttackers].y + 100}, 50.0, 3.0, BLACK);
                    break;
                case 3:
                    frameRec.y = 2*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i-nbOfAttackers], WHITE);
                    DrawTextEx(font, "3", (Vector2){positionDiceDefender[i-nbOfAttackers].x + 30, positionDiceDefender[i-nbOfAttackers].y +  100}, 50.0, 3.0, BLACK);
                    break;
                case 4:
                    frameRec.y = 3*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i-nbOfAttackers], WHITE);
                    DrawTextEx(font, "4", (Vector2){positionDiceDefender[i-nbOfAttackers].x + 30, positionDiceDefender[i-nbOfAttackers].y + 100}, 50.0, 3.0, BLACK);
                    break;
                case 5:
                    frameRec.y = 4*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i-nbOfAttackers], WHITE);
                    DrawTextEx(font, "5", (Vector2){positionDiceDefender[i-nbOfAttackers].x + 30, positionDiceDefender[i-nbOfAttackers].y+100}, 50.0, 3.0, BLACK);
                    break;
                case 6:
                    frameRec.y = 5*(float)diceTexture.height/9;
                    DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i-nbOfAttackers], WHITE);
                    DrawTextEx(font, "6", (Vector2){positionDiceDefender[i-nbOfAttackers].x + 30, positionDiceDefender[i-nbOfAttackers].y + 100}, 50.0, 3.0, BLACK);
                    break;
                
                default:
                    break;
                }
            }
            int remainingAttackers = attackersCount;
            for(int index = 0; index < fmin(defendersCount, attackersCount); index++){
                if(listOfDices[index] > listOfDices[index + attackersCount]){
                    //targetNode->soldiers--;
                    //printf("Defenders lose a soldier\n");
                    DrawTextEx(font, "Defenders lose a soldier", (Vector2){screenWidth/2 - MeasureTextEx(font, "Defenders lose a soldier",50.0, 3.0 ).x/2 , 600}, 50.0, 3.0, BLACK);

                }else{
                    //originNode->soldiers--;
                    //remainingAttackers--;
                    //printf("Attackers lose a soldier\n");
                    DrawTextEx(font, "Attackers lose a soldier", (Vector2){screenWidth/2 - MeasureTextEx(font, "Attackers lose a soldier",50.0, 3.0 ).x/2 , 600}, 50.0, 3.0, BLACK);

                }
            }
            
            if(targetNode->soldiers <= 0){
                //printf("Node has been conquered\n");
                DrawTextEx(font, "Node has been conquered", (Vector2){screenWidth/2 - MeasureTextEx(font, "Node has been conquered",50.0, 3.0 ).x/2 , 700}, 50.0, 3.0, BLACK);
                //Player_remove_Node(defender, targetNode);
                //Player_add_Node(self, targetNode);
                //targetNode->soldiers = attackersCount;
                //originNode->soldiers -= attackersCount;
            }

        EndDrawing();
        //----------------------------------------------------------------------------------
    } 

    // De-Initialization
    //--------------------------------------------------------------------------------------
           // Texture unloading

    //CloseWindow();        
    free(whoseTurnToAttack);
    free(whoseTurnToDefend);
    free(positionDiceAttacker);
    free(positionDiceDefender);        // Close window and OpenGL context
    UnloadTexture(diceTexture);
    //--------------------------------------------------------------------------------------

    
}
