/** 
Puissance4Graphique represente le dessin du tableau du jeu : les cases
* et les pions des deux joueurs.
@author Sebastien BISMUTH 
@author Yann LENNE
@version 1.1.6
*/

import java.awt.*;
import java.rmi.*;
import java.lang.*;
import java.util.*;

public class Puissance4Graphique extends Canvas {
  /** Classe pour le chargement des images du fond d'ecran et des pions */
  private MediaTracker tracker;

  /** Tableau contenant les images pour le graphique de type Java */
  private Image java[];

  /** Tableau contenant les images pour le graphique de type Femmes */
  private Image femmes[];

  /** Tableau contenant les images pour le graphique de type Femmes */
  private Image simpsons[];

  /** Nombre de cases du tableau de jeu */
  private Dimension dim;

  /** Interface de l'objet Puissance4 */
  private Puissance4Distant pd;

  /** Indique si toute la fenetre doit etre repeinte ou seulement une case */
  private boolean toutPeindre;

  /** Indique si un joueur a gagne la partie */
  private boolean partieGagnee;

  /** Coordonnees des 4 cases gagnantes */
  private Point[] casesGagnantes;

  /** Indique si c'est le tour du joueur */
  //private boolean monTour;

  /** Numero du joueur */
  private char numJoueur;

  /** Champ de texte de la fenetre de jeu */
  private TextField tfMesg;

  /** Indique quel joueur veut recommencer */
  private boolean jeVeuxRecommencer;

  /** Permet de reconnaitre le graphique en cours */
  private String graphique;

  /** Image a afficher */
  private Image image;

  /** Permet de savoir quand le premier joueur a joue pour la premiere fois */
  private boolean premierCoup;

  /** @param pd Interface de l'objet Puissance4
    @param num Numero du joueur
    @param t Champ de texte de la fenetre de jeu
  */
  public Puissance4Graphique(Puissance4Distant pd, char num, TextField t) {
    try { this.dim = pd.getDim(); } catch (Exception e) {e.printStackTrace();}

    tracker = new MediaTracker(this);
    java = new Image[6];
    femmes = new Image[6];
    simpsons = new Image[6];
    
    premierCoup = false;
    
    for (int i = 0 ; i <= 5 ; i++) {
      java[i] = Toolkit.getDefaultToolkit().getImage("Images/java" + i + ".gif");
      tracker.addImage(java[i], 0);
    }
    
    for (int i = 0 ; i <= 5 ; i++) {
      femmes[i] = Toolkit.getDefaultToolkit().getImage("Images/femme" + i + ".gif");
      tracker.addImage(femmes[i], 1);
    }

    for (int i = 0 ; i <= 5 ; i++) {
      simpsons[i] = Toolkit.getDefaultToolkit().getImage("Images/simpsons" + i + ".gif");
      tracker.addImage(simpsons[i], 2);
    }

    // Chargement des images java
    try{
      tracker.waitForID(0);
    }
    catch (InterruptedException e){e.printStackTrace();}

    // Chargement des images femmes
    try{
      tracker.waitForID(1);
    }
    catch (InterruptedException e){e.printStackTrace();}

    // Chargement des images simpsons
    try{
      tracker.waitForID(2);
    }
    catch (InterruptedException e){e.printStackTrace();}

    this.pd = pd;
    numJoueur = num;
    tfMesg = t;
    toutPeindre = true;
    partieGagnee = false;

    graphique = new String("traditionnel");
    setVisible(true);
  }
  
  /** Retourne la taille a affecter par defaut au Canvas
    @return Dimension Dimensions du Canvas
  */
  public Dimension getPreferredSize() {
    return new Dimension(400, 280);
  }

  /** Retourne la taille minimum du Canvas
    @return Dimension Taille minimum du Canvas
  */ 
  public Dimension getMinimumSize() {
    return getPreferredSize();
  }

  /** Retourne la valeur de la chaine 'graphique' representant le fond d'ecran et les pions
    @return String Representation du graphique en cours
  */ 
  public String getGraphique() {
    return graphique;
  }

  /** Modificateur de l'attribut toutPeindre
    * Modifie la valeur de l'attribut toutPeindre
    @param b Valeur que doit prendre toutPeindre
  */
  public void setToutPeindre(boolean b) {
    toutPeindre = b;
  }
  
  /** Modificateur de l'attribut graphique
    * Modifie la valeur de l'attribut graphique
    @param b Valeur que doit prendre graphique
  */
  public void setGraphique(String s) {
    graphique = s;
  }

  /** Modificateur de l'attribut jeVeuxRecommencer
    * Modifie la valeur de l'attribut jeVeuxRecommencer
    @param b Valeur que doit prendre jeVeuxRecommencer
  */
  public void setJeVeuxRecommencer(boolean b) {
    jeVeuxRecommencer = b;
  }

  /** Accesseur de l'attribut jeVeuxRecommencer
    * Retourne la valeur de l'attribut jeVeuxRecommencer
    @return boolean Indique si le joueur a voulu recommencer
  */
  public boolean getJeVeuxRecommencer() {
    return jeVeuxRecommencer;
  }

   /** Modificateur de l'attribut partieGagnee
     * Modifie la valeur de l'attribut partieGagnee
    @param b Valeur que doit prendre partieGagnee
  */
  public void setPartieGagnee(boolean b) {
    partieGagnee = b;
  }

  /** Accesseur de l'attribut casesGagnantes
    * Modifie la valeur de l'attribut casesGagnantes
    @param b Valeur que doit prendre casesGagnantes
  */
  public void setCasesGagnantes(Point[] casesGagnantes) {
    this.casesGagnantes = casesGagnantes;
  }

  /** Affiche un message au joueur pour lui dire si c'est son tour ou non.
    @param b true si c'est le tour du joueur, false sinon
  */
  public void monTour(boolean b) {
    if(premierCoup) {
      if (b)
        tfMesg.setText("A vous de jouer");
      else{
        try{
          tfMesg.setText("C'est le tour de " + pd.getPseudoJoueur(pd.prochainJoueur()));
        } catch (RemoteException e) {e.printStackTrace();}
      }
    }
    else
      premierCoup = true;
  }
  
  /** Accesseur de l'attribut numJoueur 
    * Retourne la valeur de l'attribut numJoueur 
    @return char Numero du joueur 
  */
  public char getNumJoueur() {
    return numJoueur;
  }
  
  /** Accesseur de l'attribut pd
    * Retourne une reference sur l'attribut pd 
    @return Puissance4Distant Interface de la classe Puissance4 
  */
  public Puissance4Distant getP4Distant() {
    return pd;
  }
  
  /** Accesseur de l'attribut tfMesg.
    * Retourne une reference sur l'attribut tfMesg.
    @return TextField Champ de texte de la fenetre de jeu
  */
  public TextField getMessage() {
    return tfMesg;
  }

  /** Renvoie le tableau des noms des joueurs 
   @return vector Vecteur contenant les noms des joueurs
  */
  public Vector renvoyerNomsJoueurs(){
    Vector v = null;
    try{
      v = pd.getNomsJoueurs();
    }
    catch(RemoteException re){re.printStackTrace();}

    return v;
  }

  /** Procedure de dessin du Canvas.
    * Determine si la fenetre doit etre peinte ou seulement une case.
    @param gc Contexte graphique du Canvas
  */
  public void paint(Graphics gc) {
    System.out.println("P4G : Entree dans paint : toutPeindre = " + toutPeindre);
    if (toutPeindre)
      toutDessiner(gc);
    else
      dessinerPion(gc);
    toutPeindre = true;
  }

  /** Dessin des pions gagnants.
    * Dessine les 4 pions gagnants dans une couleur differente.
    @param Contexte graphique du Canvas
  */
  public void dessinerCasesGagnantes(Graphics gc) {
    int height, width;
    int largeurCase, hauteurCase;
    int nbCasesX, nbCasesY;
    nbCasesX = dim.width;
    nbCasesY = dim.height;
    height = getSize().height;
    width = getSize().width;
    largeurCase = (int)(width/nbCasesX); 
    hauteurCase = (int)(height/nbCasesY);

    if (graphique.compareTo("traditionnel") == 0){
      gc.setColor(Color.green);

      for (int i =0; i<casesGagnantes.length; i++) {
        gc.fillOval(casesGagnantes[i].x*largeurCase+4, casesGagnantes[i].y*hauteurCase+4, largeurCase-8, hauteurCase-8);
      }
    }
    else{
      if(graphique.compareTo("java") == 0) {
        if (tracker.statusID(0, true) == MediaTracker.COMPLETE) {
          for (int i =0; i<casesGagnantes.length; i++)
            gc.drawImage(java[5], casesGagnantes[i].x*largeurCase+1, casesGagnantes[i].y*hauteurCase+1, largeurCase-2, hauteurCase-2, this);
        }
      }
      else if(graphique.compareTo("femmes") == 0) {
        if (tracker.statusID(1, true) == MediaTracker.COMPLETE) {
          for (int i =0; i<casesGagnantes.length; i++)
            gc.drawImage(femmes[5], casesGagnantes[i].x*largeurCase+1, casesGagnantes[i].y*hauteurCase+1, largeurCase-2, hauteurCase-2, this);
        }
      }
      else if(graphique.compareTo("simpsons") == 0) {
        if (tracker.statusID(2, true) == MediaTracker.COMPLETE) {
          for (int i =0; i<casesGagnantes.length; i++)
            gc.drawImage(simpsons[5], casesGagnantes[i].x*largeurCase+1, casesGagnantes[i].y*hauteurCase+1, largeurCase-2, hauteurCase-2, this);
        }
      }
    }
  }

  /** Dessin du tableau de jeu en entier
    @param Contexte graphique du Canvas
  */
  public void toutDessiner (Graphics gc) {
    int height, width;
    int largeurCase, hauteurCase;
    int nbCasesX, nbCasesY;
    String stringTemp = new String();;

    System.out.println("P4G : Entree dans toutDessiner");
    
    nbCasesX = dim.width;
    nbCasesY = dim.height;

    char[][] tab = new char[nbCasesY][nbCasesX];
    try { tab = pd.getTab();} catch (Exception e) {e.printStackTrace();}

    //System.out.println("nbCasesX => " + nbCasesX + " nbCasesY => " + nbCasesY);

    height = getSize().height;
    width = getSize().width;
    largeurCase = (int)(width/nbCasesX); 
    hauteurCase = (int)(height/nbCasesY); 

    // Dessin du fond
    if (graphique.compareTo("traditionnel") == 0){
      gc.setColor(Color.blue);
      gc.fillRect(0, 0, width, height);
    }
    else{
      if (graphique.compareTo("java") == 0){
        gc.drawImage(java[0], 0, 0, width, height, this);
      }
      else {
        if (graphique.compareTo("femmes") == 0){
          gc.drawImage(femmes[0], 0, 0, width, height, this);
        }
        else {
          if (graphique.compareTo("simpsons") == 0){
            gc.drawImage(simpsons[0], 0, 0, width, height, this);
          }
        }
      }
    }
    // Dessin des cases
    for(int i=0; i<nbCasesX; i++) {
      for(int j=0; j<nbCasesY; j++) {
        gc.setColor(Color.black);
        gc.drawRect(i*largeurCase, j*hauteurCase, largeurCase, hauteurCase);
      }
    }
   
    // Dessin des pions
    for(int i=0; i<nbCasesY; i++) {
      for(int j=0; j<nbCasesX; j++) {

        if (graphique.compareTo("traditionnel") == 0){
        
          switch (tab[i][j]) {
            // Jeton jaune dans la case pour le joueur 1
          case '1':
            gc.setColor(Color.yellow);
            gc.fillOval(j*largeurCase+1, i*hauteurCase+1, largeurCase-2, hauteurCase-2);
            break;
            // Jeton rouge dans la case pour le joueur 2
          case '2':
            gc.setColor(Color.red);
            gc.fillOval(j*largeurCase+1, i*hauteurCase+1, largeurCase-2, hauteurCase-2);
            break;
            // Jeton blanc dans la case pour le joueur 3
          case '3':
            gc.setColor(Color.white);
            gc.fillOval(j*largeurCase+1, i*hauteurCase+1, largeurCase-2, hauteurCase-2);
            break;
            // Jeton rose dans la case pour le joueur 4
          case '4':
            gc.setColor(Color.pink);
            gc.fillOval(j*largeurCase+1, i*hauteurCase+1, largeurCase-2, hauteurCase-2);
            break;
          }
        }
        else if(tab[i][j] >= '1'){
          // Les images sont dans le repertoire Images et ont comme nom 
          // <graphique><numJoueur>.gif
          if (graphique.compareTo("java") == 0){
            if (tracker.statusID(0, true) == MediaTracker.COMPLETE) {
              stringTemp = "" + tab[i][j] + "";
              gc.drawImage(java[Integer.parseInt(stringTemp)], j*largeurCase+1, i*hauteurCase+1, largeurCase-2, hauteurCase-2, this);
            }
          }
          else {
            if (graphique.compareTo("femmes") == 0){
              stringTemp = "" + tab[i][j] + "";
              gc.drawImage(femmes[Integer.parseInt(stringTemp)], j*largeurCase+1, i*hauteurCase+1, largeurCase-2, hauteurCase-2, this);
            }
            else {
              if (graphique.compareTo("simpsons") == 0){
                stringTemp = "" + tab[i][j] + "";
                gc.drawImage(simpsons[Integer.parseInt(stringTemp)], j*largeurCase+1, i*hauteurCase+1, largeurCase-2, hauteurCase-2, this);
              }
            }
          }
        }
      }
    }
      //System.out.println("partieGagnee == " + partieGagnee);
    if(partieGagnee == true) {
      dessinerCasesGagnantes(gc);
    }
  }

  /** Surcharge de la methode update
    * Permet d'eviter que le Canvas soit totalement efface avant d'etre repeint
    @param gc Contexte graphique du Canvas
  */
  public void update(Graphics gc){
    paint(gc);
  }
  
  /** Dessin du dernier pion ajoute dans le tableau des pions
    @param gc Contexte graphique du Canvas
  */
  public void dessinerPion(Graphics gc) {
    int height, width;
    int largeurCase, hauteurCase;
    int nbCasesX, nbCasesY;
    String stringTemp = new String();

    System.out.println("P4G : Entree dans dessinerPion");
    
    nbCasesX = dim.width;
    nbCasesY = dim.height;

    height = getSize().height;
    width = getSize().width;

    largeurCase = (int)(width/nbCasesX); 
    hauteurCase = (int)(height/nbCasesY);

    try {
      Point p = new Point();
      p = pd.getPionAjoute();
      
      if (graphique.compareTo("traditionnel") == 0){

        switch (pd.getDernierJoueur()) {
          
          // Jeton jaune dans la case pour le joueur 1
        case '1':
          gc.setColor(Color.yellow);
          gc.fillOval(p.x*largeurCase+1, p.y*hauteurCase+1, largeurCase-2, hauteurCase-2);
          break;
          // Jeton rouge dans la case pour le joueur 2
        case '2':
          gc.setColor(Color.red);
          gc.fillOval(p.x*largeurCase+1, p.y*hauteurCase+1, largeurCase-2, hauteurCase-2);
          break;
          // Jeton blanc dans la case pour le joueur 3
        case '3':
          gc.setColor(Color.white);
          gc.fillOval(p.x*largeurCase+1, p.y*hauteurCase+1, largeurCase-2, hauteurCase-2);
          break;
          // Jeton rose dans la case pour le joueur 4
        case '4':
          gc.setColor(Color.pink);
          gc.fillOval(p.x*largeurCase+1, p.y*hauteurCase+1, largeurCase-2, hauteurCase-2);
          break;
        }
      }
      else{
        if (graphique.compareTo("java") == 0){
          if (tracker.statusID(0, true) == MediaTracker.COMPLETE) {
            stringTemp = "" + pd.getDernierJoueur() + "";
            
            gc.drawImage(java[Integer.parseInt(stringTemp)], p.x*largeurCase+1, p.y*hauteurCase+1, largeurCase-2, hauteurCase-2, this);
          }
        }
        else {
          if (graphique.compareTo("femmes") == 0){
            stringTemp = "" + pd.getDernierJoueur() + "";
            
            gc.drawImage(femmes[Integer.parseInt(stringTemp)], p.x*largeurCase+1, p.y*hauteurCase+1, largeurCase-2, hauteurCase-2, this);
          }
          else {
            if (graphique.compareTo("simpsons") == 0){
              stringTemp = "" + pd.getDernierJoueur() + "";
              
              gc.drawImage(simpsons[Integer.parseInt(stringTemp)], p.x*largeurCase+1, p.y*hauteurCase+1, largeurCase-2, hauteurCase-2, this);
            }
          }
        }
      }

      //System.out.println("partieGagnee == " + partieGagnee);
      if(partieGagnee == true) {
        dessinerCasesGagnantes(gc);
      }
    }
    catch(RemoteException e) {e.printStackTrace();}
  }
}






