package org.Models;

import java.awt.Point;
import java.util.Observable;
import java.util.Random;

import org.Models.Pieces.PieceI;
import org.Models.Pieces.PieceJ;
import org.Models.Pieces.PieceL;
import org.Models.Pieces.PieceO;
import org.Models.Pieces.PieceS;
import org.Models.Pieces.PieceT;
import org.Models.Pieces.PieceZ;
import org.Views.VueGameOver;
import org.Views.VueTetris;

@SuppressWarnings("deprecation")
public class Jeu extends Observable implements Runnable {
    private Grille grille;
    private Ordonnanceur ordonnanceur;
    private Musique musique;

    private PieceCourante pieceSuivante;
    private int pieceSuivanteX;
    private int pieceSuivanteY;

    public boolean jeuEnCours = true;

    public Jeu(Grille grille, Musique musique) {
        System.err.println("init jeu");
        this.grille = grille;
        this.musique = musique;

        System.err.println("init nouvelle piece courante");
        this.grille.setPieceCourante(getNouvellePiece());
        System.err.println("init nouvelle piece suivante");
        this.pieceSuivante = getNouvellePiece();

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

    private PieceCourante getNouvellePiece() {
        Random random = new Random();
        int randomiiii = random.nextInt(7);
        System.err.println("randomiiiii : " + randomiiii);

        PieceCourante nouvellePiece;
        switch (randomiiii) {
            case 0:
                nouvellePiece = new PieceI();
                System.err.println("piece I");

                break;
            case 1:
                nouvellePiece = new PieceL();
                System.err.println("piece L");
                break;
            case 2:
                nouvellePiece = new PieceJ();
                System.err.println("piece J");
                break;
            case 3:
                nouvellePiece = new PieceO();
                System.err.println("piece O");
                break;
            case 4:
                nouvellePiece = new PieceS();
                System.err.println("piece S");
                break;
            case 5:
                nouvellePiece = new PieceT();
                System.err.println("piece T");
                break;
            case 6:
                nouvellePiece = new PieceZ();
                System.err.println("piece Z");
                break;
            default:
                nouvellePiece = new PieceL();
                break;
        }
        return nouvellePiece;
    }

    public PieceCourante getPieceSuivante() {
        return pieceSuivante;
    }

    public int getPieceSuivanteX() {
        return pieceSuivanteX;
    }

    public int getPieceSuivanteY() {
        return pieceSuivanteY;
    }

    public Grille getGrille() {
        return grille;
    }

    public boolean estFinPartie() {
        for (Point caseColoree : this.grille.motifPieceCouranteColoriee()) {
            if (this.grille.getCase(caseColoree.y, caseColoree.x)) {
                new VueGameOver(grille.getScore(),e -> System.exit(0),e->{
                    System.out.println("Début d'une nouvelle partie");
                });
                return true;
            }
        }

        return false;
    }

    public void finPartie() {
        this.jeuEnCours = false;
        ordonnanceur.interrupt();
        if (musique != null) {
            System.out.println("Arret musique");
            musique.arreterMusique();
        }
        setChanged();
        notifyObservers();
    }

    @Override
    public void run() {
        // TODO: game logic here
        if (!jeuEnCours || grille.estEnPause()) {
            return;
        }

        if (estFinPartie()) {
            finPartie();
            return;
        }

        if (!this.grille.doitFixerPiece()) {
            this.grille.deplacerPiece(Direction.BAS);
        } else {
            this.grille.fixerPiece();
            this.grille.setPieceCourante(pieceSuivante);
            this.pieceSuivante = getNouvellePiece();
        }

        setChanged();
        notifyObservers();
    }
}
