package fr.iutfbleau.projetAgile.Puissance4.View;

import javax.swing.*;
import javax.swing.border.EmptyBorder;

import fr.iutfbleau.projetAgile.Puissance4.Utils.Constants;
import fr.iutfbleau.projetAgile.Puissance4.Utils.GameStatus;
import java.awt.*;
import java.awt.event.ActionListener;

/**
 * Classe qui représente le panneau du puissance 4, avec la grille, le tour du joueur, les boutons, et le score.
 */
public class Puissance4Panel extends JPanel{
    
    private JButton reset;
    private JButton menu;
    private JLabel playerTurn;
    private JLabel score;
    private Grille grille;
    private String playerOneName;
    private String playerTwoName;
    private String playerThreeName;
    private int playerNumber;

    /**
     * Crée un panneau avec la grille
     * @param grille la grille à afficher
     */
    public Puissance4Panel(Grille grille) {
        super();
        this.reset = new JButton("RECOMMENCER");
        this.menu = new JButton("ACCUEIL");
        this.playerTurn = new JLabel();
        this.score = new JLabel();
        this.grille = grille;
    }

    /**
     * Ajoute tous les composants autres que la grille au panneau (Bouton recommencer, accueil, le nom du joueur qui joue, le score)
     * Il faut appeler cette fonction après avoir initialisé les différents variables du jeu (noms des joueurs)
     */
    public void init() {
        GridBagLayout gbl = new GridBagLayout();
        this.setLayout(gbl);
        GridBagConstraints gbc = new GridBagConstraints();
        this.setBackground(Constants.BACKGROUND_COLOR);

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        gbc.weightx = 0;
        gbc.weighty = 0;
        gbc.insets = new Insets(0, 0, 0, 0);
        this.add(this.menu, gbc);


        JLabel titre = new JLabel("PUISSANCE 4");
        titre.setForeground(Color.WHITE);
        titre.setFont(new Font("",Font.BOLD, 40));
        
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        gbc.weightx = 0;
        gbc.weighty = 0;
        gbc.insets = new Insets(0, 0, 0, 0);

        this.add(titre, gbc);

        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        gbc.weightx = 1;
        gbc.weighty = 0;
        gbc.insets = new Insets(0, 0, 0, 0);

        this.add(this.grille, gbc);

        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.gridwidth = 1;  
        gbc.gridheight = 1;
        gbc.weightx = 0;
        gbc.weighty = 0;
        gbc.insets = new Insets(5, 0, 0, 0);

        playerTurn.setForeground(Color.WHITE);
        playerTurn.setFont(new Font("",Font.BOLD, 20));
        this.add(this.playerTurn, gbc);

        gbc.gridx = 1;
        gbc.gridy = 3;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.gridwidth = 1;  
        gbc.gridheight = 1;
        gbc.weightx = 0;
        gbc.weighty = 0;
        gbc.insets = new Insets(5, 0, 0, 0);

        score.setForeground(new Color(183,183,183));
        score.setFont(new Font("",Font.BOLD, 20));
        this.add(this.score, gbc);

        gbc.gridx = 1;
        gbc.gridy = 4;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.gridwidth = 1;  
        gbc.gridheight = 1;
        gbc.weightx = 0;
        gbc.weighty = 0;
        gbc.insets = new Insets(10, 0, 0, 0);

        this.add(this.reset, gbc);

        reset.setBackground(new Color(255,64,64));
        reset.setForeground(Color.WHITE);
        reset.setFocusPainted(false);
        reset.setBorder(new EmptyBorder(5,10,5,10));

        menu.setBackground(new Color(255,64,64));
        menu.setForeground(Color.WHITE);
        menu.setFocusPainted(false);
        menu.setBorder(new EmptyBorder(5,10,5,10));
    }

    /**
     * Change la couleur de survol des pions selon le tour du joueur
     * @param player le joueur qui joue
     */
    public void changeHoverColor(int player) {
        this.grille.changeHoverColor(player);
    }

    /**
     * Change le texte affichant le tour du joueur
     * @param player le joueur qui joue
     */
    public void changeLabel(int player) {
        switch(player){
            case Constants.PLAYER_ONE: 
                this.playerTurn.setText("Tour de : " + this.playerOneName);
                break;
        
            case Constants.PLAYER_TWO:
                this.playerTurn.setText("Tour de : " + this.playerTwoName);
                break;
            case Constants.PLAYER_THREE:
                this.playerTurn.setText("Tour de : " + this.playerThreeName);
                break;
            default:
                this.playerTurn.setText("JOUEUR INCONNU");
                break;
        }
    }

    /**
     * Change le texte affichant le score des joueurs
     * @param playerOneScore le score du joueur 1
     * @param playerTwoScore le score du joueur 2
     */
    public void changeScore(int playerOneScore, int playerTwoScore) {
        this.score.setText(this.playerOneName + " : " + playerOneScore + " | " + this.playerTwoName + " : " + playerTwoScore);
    }

    /**
     * Change le texte affichant le score des joueurs
     * @param playerOneScore le score du joueur 1
     * @param playerTwoScore le score du joueur 2
     * @param playerThreeScore le score du joueur 3
     */
    public void changeScore(int playerOneScore, int playerTwoScore, int playerThreeScore) {
        this.score.setText(this.playerOneName + " : " + playerOneScore + " | " + this.playerTwoName + " : " + playerTwoScore + " | " + this.playerThreeName + " : " + playerThreeScore);
    }

    /**
     * Change le propriétaire d'un pion et le redessine
     * @param column la colonne du pion a changer
     * @param row la ligne du pion a changer
     * @param player le joueur
     */
    public void addPlayerPiece(int column, int row, int player) {
        this.grille.addPlayerPiece(column, row, player);
    }

    /**
     * Change le status de la partie affiché sur le panneau (Score + Victoire ou Egalité)
     * @param status le status de la partie en cours
     * @param playerTurn le tour du joueur actuel
     * @param playerOneScore le score du joueur 1
     * @param playerTwoScore le score du joueur 2
     */
    public void setGameStatus(GameStatus status, int playerTurn, int playerOneScore, int playerTwoScore, int playerThreeScore) {
        this.grille.hover(-1);
        switch(status){
            case WIN:
                String gagnant = null; 
                if(playerTurn == Constants.PLAYER_ONE)
                    gagnant = this.playerOneName;
                else if(playerTurn == Constants.PLAYER_TWO)
                    gagnant = this.playerTwoName;
                else
                    gagnant = this.playerThreeName;
                this.playerTurn.setText("Victoire de : " + gagnant);
                break;
        
            case DRAW:
                this.playerTurn.setText("Egalité");
                break;

            case FIRST:
                JOptionPane.showMessageDialog(this, "Victoire de : " + (playerTurn == Constants.PLAYER_ONE ? this.playerOneName : this.playerTwoName), "Victoire", JOptionPane.DEFAULT_OPTION);
                break;

            default:
                this.changeLabel(playerTurn);
                break;
        }
        if(this.playerNumber == 2)
            this.changeScore(playerOneScore, playerTwoScore);
        else
            this.changeScore(playerOneScore, playerTwoScore, playerThreeScore);
    }

    public void RemovePlayer(int Player, int[][] grille){
        this.grille.RemovePlayer(Player, grille);
        this.changeHoverColor(Player);
        this.changeLabel(Player);
    }

    /**
     * Permet de définir le nom du joueur 1
     * @param playerOneName le nom du joueur
     */
    public void setPlayerOneName(String playerOneName) {
        this.playerOneName = playerOneName;
    }
    
     /**
     * Permet de définir le nom du joueur 2
     * @param playerTwoName le nom du joueur
     */
    public void setPlayerTwoName(String playerTwoName) {
        this.playerTwoName = playerTwoName;
    }

    /**
     * Permet de définir le nom du joueur 3
     * @param playerTwoName le nom du joueur
     */
    public void setPlayerThreeName(String playerThreeName) {
        this.playerThreeName = playerThreeName;
    }

    public void setPlayerNumber(int playerNumber) {
        this.playerNumber = playerNumber;
    }

    /**
     * Retourne la grille du Puissance 4 
     * @return La grille du Puissance 4
     */
    public Grille getGrille() {
        return grille;
    }

    /**
     * Ajoute un ActionListener au bouton recommencer
     * @param l L'ActionListener à ajouter
     */
    public void resetButton(ActionListener l) {
        this.reset.addActionListener(l);
    }

    /**
     * Ajoute un ActionListener au bouton accueil
     * @param l L'ActionListener à ajouter
     */
    public void accueilButton(ActionListener l){
        this.menu.addActionListener(l);
    }
}

