package jeu;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import entity.Character;
import engine.Game;
import environnement.Coordonnees;
import environnement.HitBox;
import environnement.PositionCollision;
import map.Obstacle;
import loaders.CharacterLoader;

import static environnement.PositionCollision.*;


public class Jeu implements Game{

    //coordonnees du sol
    //private static Coordonnees coordSol = new Coordonnees(200,700); //coordonnees du sol (en realite juste Z nous interesse)

    //perso
    static Character gameCharacter;

    //recupere la direction dans laquelle doit aller le personnage
    private static Map<String,Boolean> directionJeu;

    //celui qui chargera le perso et les sprites
    static CharacterLoader gameCharacterLoader;

    //path vers la bonne frame a utiliser
    String characterSkinPath; 
    //sa construction
    final String beginPath;
    String movement;

    //pour pouvoir se souvenir de l'ancien mouvement effectue
    String previousMovement;

    //gere le chgt de frame
    int numberOfMovement;
    int nbIterationPerFrame = 50;
    int nbBeforeFramechgt = nbIterationPerFrame;
    //private boolean characterNotMoving = true;

    private boolean characterAttacking = false; //boolean necessaire pour rendre l'animation d'attaque prioritaire

    public static Obstacle sol = new Obstacle(new HitBox(new Coordonnees(200,700),1,1000000));

    private static List<Obstacle> obstacleTable = new ArrayList<>();
    private static List<PositionCollision>  obstacleTableCollisionCharac= new ArrayList<>();


    public Jeu(String source) {

        BufferedReader helpReader;
        String fn = "Frames_perso";
        URL url = Jeu.class.getClassLoader().getResource(fn);
        assert url != null;
        beginPath = url.toString().substring(6)+"/";
        movement = "character_idle";
        previousMovement = movement;
        numberOfMovement = 1;
        characterSkinPath = beginPath + movement + numberOfMovement + ".png"; // path premiere frame
        /*A = new ArrayList<Double>();
        n = 0;*/
        gameCharacterLoader = new CharacterLoader(characterSkinPath,new Character(new Coordonnees(300, 300), 2000, 1,600000));
        gameCharacter = gameCharacterLoader.getGameCharacter();
        try {
            helpReader = new BufferedReader(new FileReader(source));
            String line;
            while ((line = helpReader.readLine()) != null) {
                System.out.println(line);
            }
            helpReader.close();
        } catch (IOException e) {
            System.out.println("Help not available");
        }

        //on remplit la table de directions du jeu
        directionJeu = new HashMap<>();
        directionJeu.put("Right", false);
        directionJeu.put("Left", false);
        directionJeu.put("Jump", false);
        directionJeu.put("Attack",false);
        
        //on remplit la map des frames
        Map<String,Integer> tempMap = gameCharacterLoader.getPathTable();

        tempMap.put(movement,4);

        tempMap.put("character_attack",2);
        tempMap.put("character_run", 4);
        tempMap.put("character_jump",1);

        gameCharacterLoader.setPathTable(tempMap);

        obstacleTable.add(sol);
        obstacleTable.add(new Obstacle(new HitBox(new Coordonnees(300,550),32,128)));
        obstacleTable.add(new Obstacle(new HitBox(new Coordonnees(800, 625),150,50)));
        obstacleTable.add(new Obstacle(new HitBox(new Coordonnees(600, 662.5),75,50)));

        obstacleTableCollisionCharac.add(NONE);
        obstacleTableCollisionCharac.add(NONE);
        obstacleTableCollisionCharac.add(NONE);
        obstacleTableCollisionCharac.add(NONE);

    }

    @Override
    public void evolve(HashMap<String,Boolean> command) {  // command est sous la forme map de Boolean qui represente les touches préssées. Voir Controller pour la compositions de cet list.
       
        previousMovement = movement;

        directionJeu.replace("Right", command.get("Right"));
        directionJeu.replace("Left", command.get("Left"));
        directionJeu.replace("Jump", command.get("Jump"));
        directionJeu.replace("Attack",command.get("Attack"));
        boolean Right = command.get("Right");
        boolean Left = command.get("Left");
        boolean Attack = command.get("Attack");


       
        //perso evolue dans le jeu (en actualisant ses coordonnees)
        gameCharacter.evolveCharacter();

        //animation du perso dans le jeu (definir la bonne frame a cet instant)
        animation(Attack, Right, Left);
        
    }

    @Override
    public boolean isFinished() {
        // le jeu n'est jamais fini
        return false;
    }


    public static Map<String, Boolean> getDirectionJeu() {
        return directionJeu;
    }

    public static Obstacle getSol() {
        return sol;
    }

    public static List<Obstacle> getObstacleTable() {
        return obstacleTable;
    }
    public static List<PositionCollision> getObstacleTableCollisionCharac() {
        return obstacleTableCollisionCharac;
    }
    public static void setObstacleTableCollisionCharac(List<PositionCollision> obstacleTableCollisionCharac) {
        Jeu.obstacleTableCollisionCharac = obstacleTableCollisionCharac;
    }

    private void animation(Boolean Attack,Boolean Right,Boolean Left){
        if (Attack && !characterAttacking) {
            movement = "character_attack";
            characterAttacking = true;
        }

        if (!characterAttacking){ //animation d'attaque prioritaire
            if (gameCharacter.getAlpha() == 0) movement = "character_jump"; // pour savoir si il jump ou non
            else{
                if (Right && Left)movement = "character_idle";
                else if (Right || Left){
                    movement = "character_run";
                }
                else if (!Right && !Left){
                        
                    movement = "character_idle"; //ca changera quand j'aurai les nouvelles frames
                }
            }
        }
 
        //si on a change de mouvement, le jeu doit redemarrer a la premiere frame correspondante
        //System.out.println(numberOfMovement);
        if (previousMovement != movement){numberOfMovement = 1;nbBeforeFramechgt = nbIterationPerFrame;}
        if (numberOfMovement == gameCharacterLoader.getPathTable().get(movement)){
            //System.out.println(movement);
            //characterNotMoving = true;
            if (movement == "character_attack"){
                characterAttacking = false;
            }
        }
        if ((nbIterationPerFrame-nbBeforeFramechgt) == nbIterationPerFrame) { // timer pour changer de frame
            numberOfMovement = numberOfMovement%gameCharacterLoader.getPathTable().get(movement) + 1;
            nbBeforeFramechgt = nbIterationPerFrame;
        }
        else nbBeforeFramechgt--;
        
            
        //actualisation de l'image a afficher
        characterSkinPath = beginPath + movement + numberOfMovement + ".png";
        gameCharacterLoader.setSkinPath(characterSkinPath);
        gameCharacterLoader.refreshImage();
    }
    
}