package org.Views;

import javax.swing.*;

import org.Models.*;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.util.Observable;
import java.util.Observer;

@SuppressWarnings("deprecation")
public class VueGrille extends JPanel implements Observer, Runnable {
    private JPanel grillePanel;

    private Grille grille;
    private Jeu jeu;
    private Ordonnanceur ordonnanceur;

    private boolean afficherFenetreFinPartie = false;

    private int nbLignes;
    private int nbColonnes;
    private JPanel[][] casesGrille;

    public VueGrille(Grille grille, Jeu jeu) {
        this.grille = grille;
        this.jeu = jeu;
        this.nbLignes = grille.getNbLignes();
        this.nbColonnes = grille.getNbColonnes();
        setLayout(new BorderLayout());
        grillePanel = new JPanel(new GridLayoutCarre(nbLignes,nbColonnes)); //pour que les cases soient carrés
        add(grillePanel, BorderLayout.CENTER);
        casesGrille = new JPanel[nbLignes][nbColonnes];
        for (int i = 0; i < nbLignes; i++) {
            for (int j = 0; j < nbColonnes; j++) {
                JPanel caseG = new JPanel(){
                    @Override
                    public Dimension getPreferredSize(){
                        return super.getPreferredSize();
                    }
                };
                caseG.setBackground(Color.WHITE);
                caseG.setBorder(BorderFactory.createLineBorder(Color.GRAY));
                casesGrille[i][j] = caseG;
                grillePanel.add(caseG);
            }
        }

        grille.addObserver(this);
        jeu.addObserver(this);

        this.ordonnanceur = new Ordonnanceur(this, 1000);
        ordonnanceur.start();
    }

    public void resizeCases() {
        int largeurPanel = grillePanel.getWidth();
        int hauteurPanel = grillePanel.getHeight();
        if (largeurPanel==0||hauteurPanel==0) {
            return;
        }
        int taille = Math.min(largeurPanel, hauteurPanel);
        grillePanel.setPreferredSize(new Dimension(taille, taille));
        grillePanel.setMaximumSize(new Dimension(taille, taille));
        grillePanel.setMinimumSize(new Dimension(taille, taille));
        grillePanel.setSize(new Dimension(taille, taille));
        int tailleCaseX = largeurPanel / nbColonnes;
        int tailleCaseY = hauteurPanel / nbLignes;
        int tailleCase = Math.min(tailleCaseX, tailleCaseY);
        Dimension taillePreferee=new Dimension(tailleCase, tailleCase);
        for (int i = 0; i < nbLignes; i++) {
            for (int j = 0; j < nbColonnes; j++) {
                casesGrille[i][j].setPreferredSize(taillePreferee);
            }
        }
        grillePanel.revalidate();
        grillePanel.repaint();
    }

    private void initialiserVueGrille() {
        for (int i = 0; i < grille.getNbLignes(); i++) {
            for (int j = 0; j < grille.getNbColonnes(); j++) {
                JPanel caseG = new JPanel();
                caseG.setBackground(Color.WHITE);
                grillePanel.add(caseG);
            }
        }
    }

    public synchronized void updateGrille() {
        for (int i = 0; i < nbLignes; i++) {
            for (int j = 0; j < nbColonnes; j++) {
                JPanel caseG = casesGrille[i][j];
                if (grille.getGrille()[i][j]) {
                    caseG.setBackground(Color.BLUE);
                } else {
                    caseG.setBackground(Color.WHITE);
                }
            }
        }

        // dessiner la pièce courante
        if (jeu != null) {
            PieceCourante piece = grille.getPieceCourante();
            int posX = grille.getPieceCouranteX();
            int posY = grille.getPieceCouranteY();

            boolean[][] motif = piece.getMotif();
            for (int i = 0; i < motif.length; i++) {
                for (int j = 0; j < motif[i].length; j++) {

                    if (motif[i][j]) {

                        int grilleX = posX + j;
                        int grilleY = posY + i;

                        if (grilleY >= 0 && grilleY < nbLignes &&
                                grilleX >= 0 && grilleX < nbColonnes) {
                            JPanel caseG = casesGrille[grilleY][grilleX];
                            caseG.setBackground(Color.RED);
                        }
                    }
                }
            }
        }
        repaint();
    }

    private void afficherFinPartie() {
        System.err.println("FIN PARTIE"); // TODO : gerer affichage ?
    }

    /**
     * * Met à jour la vue de la grille lorsque l'état de la grille change.
     */
    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof Grille) {
            updateGrille();
        }

        if (o instanceof Jeu && !afficherFenetreFinPartie) {
            if (!this.jeu.jeuEnCours) {
                afficherFenetreFinPartie = true;
                afficherFinPartie();
            }
        }
    }

    /**
     * * Met à jour la vue de la grille périodiquement selon l'ordonnaceur.
     */
    @Override
    public void run() {
        updateGrille();
    }
}
