package com.example.sae41_2025;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.GridLayout;
import android.util.Log;
import java.util.Random;

public class GameActivity extends Activity {

    private int[] tiles = {R.drawable.tileblue, R.drawable.tilegreen, R.drawable.tilegrey, R.drawable.tileorange, R.drawable.tilepink, R.drawable.tilered, R.drawable.tileyellow};
    private int NB_LIGNES = 6;
    private int NB_COLS = 6;

    private Case[][] cases;
    private CaseEtat[][] etats; //les infos utiles en Serializable pour pouvoir les ranger dans intent ou bundle

    private int score=0;
    private int coup=1;

    private String GRILLE_ETAT = "grille_etats";

    private String TAG = "blou";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_jeu);

        //mettre la grille carré peut import la taille de lecran 
        GridLayout grille = this.findViewById(R.id.grille);
        grille.getLayoutParams().height = this.getResources().getDisplayMetrics().widthPixels;
        grille.requestLayout();

        this.cases = new Case[this.NB_LIGNES][this.NB_COLS];
        this.etats = new CaseEtat[this.NB_LIGNES][this.NB_COLS];

        
        CaseEtat[][] etatsRestores = null;
        if (savedInstanceState != null) {
            etatsRestores = (CaseEtat[][]) savedInstanceState.getSerializable(GRILLE_ETAT);
        } else {
            etatsRestores = (CaseEtat[][]) this.getIntent().getSerializableExtra(GRILLE_ETAT);
        }

        Random random = new Random();
        Log.d(TAG, "créer grille");

        //creer la grille soit en random (a modif!!!) soit en recuperant les infos de intent ou bundle
        for (int ligne = 0; ligne < this.NB_LIGNES; ligne++) {
            for (int col = 0; col < this.NB_COLS; col++) {

                CaseEtat etat;
                if (etatsRestores != null) {
                    etat = etatsRestores[ligne][col];
                } else {
                    etat = new CaseEtat(this.tiles[random.nextInt(tiles.length)], random.nextInt(5) == 0);
                }

                this.etats[ligne][col] = etat;

                Case cellule = new Case(this, etat.getTileResId(), ligne, col);
                cellule.setBloque(etat.isBloque());
                this.cases[ligne][col] = cellule;

                GridLayout.LayoutParams cellParams = new GridLayout.LayoutParams();
                cellParams.rowSpec = GridLayout.spec(ligne, 1, 1f);
                cellParams.columnSpec = GridLayout.spec(col, 1, 1f);
                cellParams.setMargins(4, 4, 4, 4);
                cellParams.width  = 0;
                cellParams.height = 0;
                grille.addView(cellule, cellParams);
            }
        }
    }

    public void decalerLigne(int ligne, int decalage) {
        int n = this.NB_COLS;
        decalage = (decalage + n) % n;
        if (decalage == 0) 
            return;

        int[] tmpRes = new int[n];
        boolean[] tmpBloque = new boolean[n];
        for (int col = 0; col < n; col++) {
            int destination = (col + decalage) % n;
            tmpRes[destination] = this.cases[ligne][col].getTileResId();
            tmpBloque[destination] = this.cases[ligne][col].isBloque();
        }
        for (int col = 0; col < n; col++) {
            this.cases[ligne][col].updateTile(tmpRes[col]);
            this.cases[ligne][col].setBloque(tmpBloque[col]);
        }
    }

    public void decalerColonne(int colonne, int decalage) {
        int n = this.NB_LIGNES;
        decalage = (decalage + n) % n;
        if (decalage == 0) return;

        int[] tmpRes = new int[n];
        boolean[] tmpBloque = new boolean[n];
        for (int ligne = 0; ligne < n; ligne++) {
            int destination = (ligne + decalage) % n;
            tmpRes[destination] = this.cases[ligne][colonne].getTileResId();
            tmpBloque[destination] = this.cases[ligne][colonne].isBloque();
        }
        for (int ligne = 0; ligne < n; ligne++) {
            this.cases[ligne][colonne].updateTile(tmpRes[ligne]);
            this.cases[ligne][colonne].setBloque(tmpBloque[ligne]);
        }
    }



    @Override
    protected void onResume() {
        super.onResume();
        //ajout listener a chaque case
        for (int ligne = 0; ligne < this.NB_LIGNES; ligne++) {
            for (int col = 0; col < this.NB_COLS; col++) {
                this.cases[ligne][col].setOnTouchListener(new CaseOnTouchListener(this, this.cases[ligne][col]));
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        //pause listener a chaque case
        for (int ligne = 0; ligne < this.NB_LIGNES; ligne++) {
            for (int col = 0; col < this.NB_COLS; col++) {
                this.cases[ligne][col].setOnTouchListener(null);
            }
        }
    }

    @Override
    public void onBackPressed() {
        if (this.coup == 0) {
            //si le joueur a pas commencer de partie -> on garde pas letat du jeu
            super.onBackPressed();
            return;
        }
        //recup les infos des cases pour intent
        for (int ligne = 0; ligne < this.NB_LIGNES; ligne++) {
            for (int col = 0; col < this.NB_COLS; col++) {
                this.etats[ligne][col] = this.cases[ligne][col].toEtat();
            }
        }
        Intent intent = new Intent();
        intent.putExtra(GRILLE_ETAT, this.etats);
        this.setResult(Activity.RESULT_OK, intent);
        Log.d(TAG, "grille sauvegardée (onBackPressed)");
        super.onBackPressed();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //recup les infos des cases pour Bundle
        for (int ligne = 0; ligne < this.NB_LIGNES; ligne++) {
            for (int col = 0; col < this.NB_COLS; col++) {
                this.etats[ligne][col] = this.cases[ligne][col].toEtat();
            }
        }
        outState.putSerializable(GRILLE_ETAT, this.etats);
        Log.d(TAG, "grille sauvegardée (onSaveInstanceState)");
    }

    public int getNbLignes() {
        return this.NB_LIGNES;
    }

    public int getNbCols() {
        return this.NB_COLS;
    }

    public int[] getLigneResIds(int ligne) {
        int[] res = new int[NB_COLS];
        for (int col = 0; col < NB_COLS; col++) res[col] = this.cases[ligne][col].getTileResId();
        return res;
    }

    public boolean[] getLigneBloques(int ligne) {
        boolean[] b = new boolean[NB_COLS];
        for (int col = 0; col < NB_COLS; col++) b[col] = this.cases[ligne][col].isBloque();
        return b;
    }

    public int[] getColonneResIds(int colonne) {
        int[] res = new int[NB_LIGNES];
        for (int ligne = 0; ligne < NB_LIGNES; ligne++) res[ligne] = this.cases[ligne][colonne].getTileResId();
        return res;
    }

    public boolean[] getColonneBloques(int colonne) {
        boolean[] b = new boolean[NB_LIGNES];
        for (int ligne = 0; ligne < NB_LIGNES; ligne++) b[ligne] = this.cases[ligne][colonne].isBloque();
        return b;
    }

    public void surlignerLigne(int ligne) {
        for (int col = 0; col < NB_COLS; col++) 
            this.cases[ligne][col].setSurlignee(true);
    }

    public void surlignerColonne(int colonne) {
        for (int ligne = 0; ligne < NB_LIGNES; ligne++) 
            this.cases[ligne][colonne].setSurlignee(true);
    }

    public void effacerTousSurlignements() {
        for (int ligne = 0; ligne < NB_LIGNES; ligne++)
            for (int col = 0; col < NB_COLS; col++)
                this.cases[ligne][col].setSurlignee(false);
    }

    public boolean ligneEstBloquee(int ligne) {
        for (int col = 0; col < NB_COLS; col++) {
            if (this.cases[ligne][col].isBloque()) 
                return true;
        }
        return false;
    }

    public boolean colonneEstBloquee(int colonne) {
        for (int ligne = 0; ligne < NB_LIGNES; ligne++) {
            if (this.cases[ligne][colonne].isBloque()) 
                return true;
        }
        return false;
    }

    public void restoreLigne(int ligne, int[] resIds, boolean[] bloques) {
        for (int col = 0; col < NB_COLS; col++) {
            this.cases[ligne][col].updateTile(resIds[col]);
            this.cases[ligne][col].setBloque(bloques[col]);
        }
    }

    public void restoreColonne(int colonne, int[] resIds, boolean[] bloques) {
        for (int ligne = 0; ligne < NB_LIGNES; ligne++) {
            this.cases[ligne][colonne].updateTile(resIds[ligne]);
            this.cases[ligne][colonne].setBloque(bloques[ligne]);
        }
    }
}

