package jeu;

import engine.GamePainter;
import entity.Bat;
import entity.Hearth;
import entity.Kunai;
import entity.Monster;
import environnement.Coordonnees;
import environnement.HitBox;
import loaders.ObstacleLoader;
import map.Coffre;
import map.Obstacle;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;

import javax.swing.ImageIcon;

import java.net.URL;

import static environnement.HitBox.collision;
import static jeu.Jeu.*;




public class Painter implements GamePainter{

    //protected static final int WIDTH = TILES_SIZE*TILES_IN_WIDTH;
    //protected static final int HEIGHT = TILES_SIZE*TILES_IN_HEIGHT;
    protected static final int WIDTH =1500;
    protected static final int HEIGHT=750;
    private static Coordonnees coordonneesCam;
    public int xCam;
    public int zCam;
    private final int decalage = 255; // decalage Cam bas pour perso

    public Painter() {
    }

    @Override
    public void draw(BufferedImage im) {

        cameraUse();
        Graphics2D crayon = (Graphics2D) im.getGraphics();
        crayon.setColor(Color.blue);

        drawMap(crayon);
        drawSol(crayon);
        drawLifePoints(crayon);
        drawKey(crayon);
        drawMonsters(crayon);
        drawKunais(crayon);
        drawHearths(crayon);
        drawCharacter(crayon,gameCharacterLoader.getImageCharacter());
    }


    private void drawCharacter(Graphics2D crayon,Image imageCharac){
        if (gameCharacter.getNbFramesInvincible() > 0)crayon.setColor(Color.black);
        crayon.fillRect(WIDTH/2-(int) gameCharacter.getEntityWIDTH()/2,HEIGHT/2-(int) gameCharacter.getEntityHEIGHT()/2+decalage, (int) gameCharacter.getEntityWIDTH(),(int) gameCharacter.getEntityHEIGHT());
        //crayon.drawRect(WIDTH/2-500,WIDTH/2-500, 1000,1000);
        if (gameCharacter.getDirection() == 1){
            crayon.drawImage(imageCharac, WIDTH/2- (int) gameCharacter.getEntityWIDTH()/2-10, HEIGHT/2 - (int) gameCharacter.getEntityHEIGHT()/2-3+decalage, null, null);
        }
        else{
            crayon.drawImage(imageCharac, WIDTH/2- (int) gameCharacter.getEntityWIDTH()/2-10-30, HEIGHT/2 - (int) gameCharacter.getEntityHEIGHT()/2-3+decalage, null, null); 
        }
    }

    
    private void drawKey(Graphics2D crayon){
    	for(int i = 1;i<=gameCharacter.key;i++) {
    		crayon.fillRect(40+30*i,60,20,30);
    	}
    }
    private void drawLifePoints(Graphics2D crayon){
        String fn = "Frames_perso";
        URL url = Jeu.class.getClassLoader().getResource(fn);
        assert url != null;
        int placeX = -10;
        String beginPath = url.toString().substring(6)+"/";
        Image filledHeart = new ImageIcon(beginPath+"character_health2.png").getImage();
        Image emptyHeart = new ImageIcon(beginPath+"character_health1.png").getImage();
        for (int i=1;i<=gameCharacter.getNbLifePoints();i++){
            placeX += 45;
            crayon.drawImage(filledHeart, placeX, 10, null, null);
        }
        for (int i=1;i<=gameCharacter.getMaxLifePoints()-gameCharacter.getNbLifePoints();i++){
            placeX += 45;
            crayon.drawImage(emptyHeart, placeX, 10, null, null);
        }
    }

    private void drawHearths(Graphics2D crayon){
        for (Hearth hearth : getHearthList()){
            HashMap<String, Coordonnees> extremites = hearth.getHitBox().getExtremites();
            Coordonnees hd = extremites.get("HautDroite");
            Coordonnees bd = extremites.get("BasDroite");
            Coordonnees hg = extremites.get("HautGauche");
            Coordonnees bg = extremites.get("BasGauche");
            crayon.fillRect((int)hg.getX()-xCam, (int)hg.getZ()-zCam, hearth.getWidth(), hearth.getHeight());
        }
    }

    private void drawObstacle(Graphics2D crayon, Obstacle obstacle){
        HashMap<String, Coordonnees> extremites = obstacle.getHitbox().getExtremites();
        Coordonnees hd = extremites.get("HautDroite");
        Coordonnees bd = extremites.get("BasDroite");
        Coordonnees hg = extremites.get("HautGauche");
        Coordonnees bg = extremites.get("BasGauche");
        //if (HitBox.collision(gameCharacter.getVoisinage(), obstacle.getHitbox()))crayon.setColor(Color.green);
        crayon.drawLine((int)hd.getX() - xCam,(int)hd.getZ() - zCam,(int)bd.getX() - xCam,(int)bd.getZ() - zCam);
        crayon.drawLine((int)bd.getX() - xCam,(int)bd.getZ() - zCam,(int)bg.getX() - xCam,(int)bg.getZ() - zCam);
        crayon.drawLine((int)bg.getX() - xCam,(int)bg.getZ() - zCam,(int)hg.getX() - xCam,(int)hg.getZ() - zCam);
        crayon.drawLine((int)hg.getX() - xCam,(int)hg.getZ() - zCam,(int)hd.getX() - xCam,(int)hd.getZ() - zCam);
    }
    private void drawObstacleBis(Graphics2D crayon, Obstacle obstacle, BufferedImage bufferedImage){
        ObstacleLoader loader = new ObstacleLoader(obstacle,bufferedImage);
        HitBox hitBox = loader.getObstacle().getHitbox();
        int z = (int) hitBox.getCentre().getZ();
        int x = (int) hitBox.getCentre().getX();
        crayon.drawImage(loader.getImageObstacle(), x - (int) hitBox.getWidth()/2 -xCam,z - (int) hitBox.getHeight()/2 -zCam,null,null);
    }

    private void drawCoffre(Graphics2D crayon, Coffre coffre){
        HashMap<String, Coordonnees> extremites = coffre.getHitbox().getExtremites();
        Coordonnees coffreCenter = coffre.getHitbox().getCentre();
        Coordonnees hd = extremites.get("HautDroite");
        Coordonnees bd = extremites.get("BasDroite");
        Coordonnees hg = extremites.get("HautGauche");
        Coordonnees bg = extremites.get("BasGauche");
        crayon.drawLine((int)hd.getX() - xCam,(int)hd.getZ() - zCam,(int)bd.getX() - xCam,(int)bd.getZ() - zCam);
        crayon.drawLine((int)bd.getX() - xCam,(int)bd.getZ() - zCam,(int)bg.getX() - xCam,(int)bg.getZ() - zCam);
        crayon.drawLine((int)bg.getX() - xCam,(int)bg.getZ() - zCam,(int)hg.getX() - xCam,(int)hg.getZ() - zCam);
        crayon.drawLine((int)hg.getX() - xCam,(int)hg.getZ() - zCam,(int)hd.getX() - xCam,(int)hd.getZ() - zCam);
        crayon.drawImage(coffre.getImage(), (int)coffreCenter.getX() - (int) coffre.getHitbox().getWidth()/2 -xCam,(int) coffreCenter.getZ() - (int) coffre.getHitbox().getHeight()/2 -zCam,null,null);

    }

    private void drawSol(Graphics2D crayon){
        ObstacleLoader loader = new ObstacleLoader(Jeu.getSol(),"Terre.png");
        HitBox hitBox = loader.getObstacle().getHitbox();
        int z = (int) hitBox.getCentre().getZ();
        for (int x = 0;x<Jeu.getSol().getHitbox().getWidth();x+=128) {
            crayon.drawImage(loader.getImageObstacle(),x -xCam ,z - zCam,null,null);
        }
    }

    private void drawMap(Graphics2D crayon){
        //System.out.println("Nombre obstacle :"+Jeu.getObstacleTable().size());
        for (Obstacle obs : Jeu.getObstacleTable()){
            if (!collision(gameCharacter.getHitBox(), obs.getHitbox())){
                crayon.setColor(Color.blue);
            }
            else {
                crayon.setColor(Color.red);
            }
            drawObstacle(crayon,obs);
        }
        drawAllObstacle(crayon);
        for (Coffre obs : Jeu.getCoffreTable()){
            if (!collision(gameCharacter.getHitBox(), obs.getHitbox())){
                crayon.setColor(Color.blue);
            }
            else {
                crayon.setColor(Color.red);
            }
            drawCoffre(crayon,obs);
        }
    }

    private void drawAllObstacle(Graphics2D crayon){
        for (int i=0;i < Jeu.getObstacleTable().size()-1;i++){
            drawObstacleBis(crayon, Jeu.getObstacleTable().get(i), getLevelmanager().getObstacleImage().get(i));
        }
    }

    
    /*private void drawCoffreBis(Graphics2D crayon, Coffre coffre, String nom){
        CoffreLoader loader = new CoffreLoader(coffre,nom);
        HitBox hitBox = loader.getCoffre().getHitbox();
        int z = (int) hitBox.getCentre().getZ();
        int x = (int) hitBox.getCentre().getX();
        crayon.drawImage(loader.getImageCoffre(), x - (int) hitBox.getWidth()/2,z - (int) hitBox.getHeight()/2,null,null);
    }*/

    private void drawMonsters(Graphics2D crayon){
        int x;
        int z;
        crayon.setColor(Color.blue);
        for (Monster monster : getMonsterList()){
            crayon.setColor(Color.blue);
            
            x = (int)monster.getCoord().getX();
            z = (int)monster.getCoord().getZ();
            //crayon.drawRect(x-300 - xCam, z-300 - zCam, 600, 600);
            if (HitBox.collision(gameCharacter.getHitBox(),monster.getHitBox()))crayon.setColor(Color.red);
            if (monster.getNbFramesInvincible() > 0)crayon.setColor(Color.black);
            //crayon.fillRect(x-(int)monster.getEntityWIDTH()/2 - xCam, z-(int)monster.getEntityHEIGHT()/2 - zCam, (int)monster.getEntityWIDTH(), (int)monster.getEntityHEIGHT());
            if (monster instanceof Bat){
                crayon.drawImage(new ImageIcon(monster.getSprite()).getImage(),x-(int)monster.getEntityWIDTH()/2 - xCam-7,z-(int)monster.getEntityHEIGHT()/2 - zCam-3, null);
            }
            else{
                crayon.drawImage(new ImageIcon(monster.getSprite()).getImage(),x-(int)monster.getEntityWIDTH()/2 - xCam-25,z-(int)monster.getEntityHEIGHT()/2 - zCam-3, null);
            }
        }
    }

    private void drawKunais(Graphics2D crayon){
        int x;
        int z;
        crayon.setColor(Color.blue);
        for (Kunai kunai : getKunaiList()){
            crayon.setColor(Color.blue);
            
            x = (int)kunai.getCoord().getX();
            z = (int)kunai.getCoord().getZ();
            if (HitBox.collision(gameCharacter.getHitBox(),kunai.getHitBox()))crayon.setColor(Color.red);
            //crayon.fillRect(x-Kunai.getWidth()/2 - xCam, z-Kunai.getHeight()/2 - zCam, Kunai.getWidth(), Kunai.getHeight());
            crayon.drawImage(new ImageIcon(kunai.getSprite()).getImage(),x - xCam-20,z - zCam-10, null);
        }
    }

    private void cameraUse(){
        coordonneesCam = gameCharacter.getCoord();
        xCam = -WIDTH/2 + (int) coordonneesCam.getX();
        zCam = -HEIGHT/2 +(int) coordonneesCam.getZ()-decalage;
    }

    @Override
    public int getWidth() {
        return WIDTH;
    }

    @Override
    public int getHeight() {
        return HEIGHT;
    }

}
