package linea;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.Timer;

public class Jeu implements KeyListener, ActionListener, MouseListener {

	protected ZoneDessin ecran = new ZoneDessin();

	protected Cercle demiCercleAvant = new Cercle(90, -180); // celui qui est sur la ligne
	protected Cercle demiCercleArriere = new Cercle(90, 180); // celui qui est derrière la ligne

	protected GestionnaireNiveau gestionnaireNiveau = new GestionnaireNiveau();
	protected Ligne lili = new Ligne(new NoiseGenerator(0), gestionnaireNiveau);

	protected Timer horloge;

	protected double score = 1;
	protected JLabel labScore;
	protected int vies = 3;

	protected GestionnaireScore gestionnaireBDD = new GestionnaireScore();

	protected int compteurFrames = 0;
	protected boolean enCollision = false;
	protected boolean estGameOver = false;
	protected JLabel labGameOver;
	protected int compteurInvincible = 0;

	protected String pseudo = "";
	protected JFrame fenetre;
	protected MenuPrincipal menu;


	public Jeu() {
		labScore = new JLabel();
		labScore.setForeground(Color.WHITE);
		labScore.setText("<html><h3>" + (int) score + "</h3></html>");
		labScore.setBounds(20, 0, 200, 50);
		ecran.add(labScore);

		labGameOver = new JLabel("GAME OVER", SwingConstants.CENTER);
		labGameOver.setForeground(Color.WHITE);
		labGameOver.setFont(new Font("Arial", Font.BOLD, 40));
		labGameOver.setBounds(0, 200, 800, 100);
		labGameOver.setVisible(false);
		ecran.add(labGameOver);

		ecran.addMouseListener(this);
		ecran.traiterBoucleAnimation();
	}

	@Override
	public void keyPressed(KeyEvent e) {
		int keyCode = e.getKeyCode();

		if (keyCode == 38) { // flèche haut
			demiCercleAvant.Monter();
			demiCercleArriere.Monter();
		}
		if (keyCode == 40) { // flèche bas
			demiCercleAvant.Descendre();
			demiCercleArriere.Descendre();
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		int keyCode = e.getKeyCode();

		if (keyCode == 38) { // flèche haut
			demiCercleAvant.ArreterMonter();
			demiCercleArriere.ArreterMonter();
		}
		if (keyCode == 40) { // flèche bas
			demiCercleAvant.ArreterDescendre();
			demiCercleArriere.ArreterDescendre();
		}
	}

	@Override
	public void keyTyped(KeyEvent e) {
	}

	public void demarrer() {
		fenetre = new JFrame("Linea");

		menu = new MenuPrincipal(fenetre, this);
		menu.afficher(pseudo);

		fenetre.setSize(800, 600);
		fenetre.setResizable(false);
		fenetre.setLocationRelativeTo(null);
		fenetre.setVisible(true);
		fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	public void lancerPartie(String pseudoSaisi) {
		pseudo = pseudoSaisi;

		// C'est cette ligne qui donne vie au bonus !
		ecran.ajouterObjet(new Bonus(lili, demiCercleAvant, this));

		// A FAIRE : placer dans l'écran tous les objets graphiques nécessaires
		ecran.ajouterObjet(demiCercleArriere);
		ecran.ajouterObjet(lili);
		ecran.ajouterObjet(demiCercleAvant);
		demiCercleArriere.setCouleur(new Color(0.0f, 0.4f, 0.0f));
		demiCercleAvant.setCouleur(new Color(0.0f, 0.5f, 0.0f));

		ecran.addKeyListener(this);
		ecran.setFocusable(true);

		fenetre.setContentPane(ecran);
		fenetre.revalidate();
		fenetre.repaint();
		ecran.requestFocusInWindow();

		score = 1;
		compteurFrames = 0;
		vies = 3;
		enCollision = false;
		estGameOver = false;
		compteurInvincible = 0;
		gestionnaireNiveau.reinitialiser();
		labGameOver.setVisible(false);
		ecran.demarrer();

		if (horloge == null) {
			horloge = new Timer(40, this);
		}
		horloge.start();

		// A FAIRE : donner la couleur des 2 demi-cercles
		// demiCercleArriere.setCouleur(new Color(0.8f, 0.0f, 0.0f));
		demiCercleArriere.setCouleur(new Color(0.8f, 0.0f, 0.0f));
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (estGameOver == true) {
			return;
		}

		gestionnaireNiveau.mettreAJour();
		ecran.setCouleurFond(gestionnaireNiveau.getCouleurFondInterpolee());

		double rayon = gestionnaireNiveau.getRayonCercle();
		demiCercleAvant.setRayon(rayon);
		demiCercleArriere.setRayon(rayon);

		ecran.traiterBoucleAnimation();

		compteurFrames = compteurFrames + 1;
		if (compteurFrames >= 25) {
			score = score + 1;
			compteurFrames = 0;
		}

		if (compteurInvincible < 75) {
			compteurInvincible = compteurInvincible + 1;
		} else {
			if (demiCercleArriere.VerifierCollision(lili)) {
				if (enCollision == false) {
					vies = vies - 1; // La nouvelle logique : on perd 1 vie
					enCollision = true;
					compteurInvincible = 0;
				}
			} else {
				enCollision = false;
			}
		}

		if (vies <= 0) {
			vies = 0;
			estGameOver = true;
			ecran.arreter();
			labGameOver.setVisible(true);

			if (pseudo != null && !pseudo.isEmpty()) {
				gestionnaireBDD.sauvegarderScore(pseudo, (int) score);
			}
		}

		labScore.setText("<html><h3>Score : " + (int) score + " | Vies : " + vies + " | Niv. " + gestionnaireNiveau.getNumeroNiveau() + "</h3></html>");

		demiCercleArriere.ResterDansLigne(lili);
		demiCercleAvant.ResterDansLigne(lili);
	}

	private void retourMenu() {
		if (horloge != null) {
			horloge.stop();
		}

		gestionnaireNiveau.reinitialiser();
		lili = new Ligne(new NoiseGenerator(0), gestionnaireNiveau);

		demiCercleAvant.y = 200;
		demiCercleAvant.vitesse = -1.0;
		demiCercleArriere.y = 200;
		demiCercleArriere.vitesse = -1.0;

		ecran.viderObjets();
		menu.afficher(pseudo);
	}

	@Override
	public void mouseClicked(MouseEvent e) {
	}

	@Override
	public void mousePressed(MouseEvent e) {
		if (estGameOver == true) {
			retourMenu();
		}
	}

	@Override
	public void mouseReleased(MouseEvent e) {
	}

	@Override
	public void mouseEntered(MouseEvent e) {
	}

	@Override
	public void mouseExited(MouseEvent e) {
	}
	public GestionnaireScore getGestionnaireBDD() {
		return gestionnaireBDD;
	}
}
