import java.awt.*;
import java.rmi.*;
import java.rmi.server.*;
import java.awt.event.*;
import java.lang.*;

/**
La classe Client cree la fenetre de jeu affichee au client (FenJeu) et le 
* tableau des cases (Puissance4Graphique) contenu dans cette fenetre.
* Elle cree aussi le champ de texte de la fenetre de jeu.
* Elle gere les evenements souris et la selection de menus dans la fenetre.
@author Sebastien BISMUTH 
@author Yann LENNE
@version 1.1.6
*/

public class Client implements MouseListener, ActionListener{
  /** Nombre de cases en largeur dans le tableau de jeu */
  private int nbCasesX;

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

  /** Fenetre principale de jeu */
  private FenJeu f;

  /** Interface de la classe Puissance4 */
  private Puissance4Distant pd;

  /** Canvas pour le dessin des cases et des pions */
  private Puissance4Graphique p;

  /** Frame pour la legende (correspondance Joueur/pion)  */
  private FenJoueurs fj;


  /** Thread pour detecter les actions de l'autre joueur */
  private Ecouteur oreille;

  /** Champ de texte affiche dans la fenetre principale */
  private TextField tfMesg;

  public Client(String pseudo, String serveur, String port){
    try{
      System.setSecurityManager(new RMISecurityManager());
      pd = (Puissance4Distant)Naming.lookup("rmi://" + serveur + ":" + port + "/Puissance4");
      
      // Verifie que le nombre de joueurs acceptables n'est pas depasse
      if (pd.connexionTotale()) {
        System.exit(0);
      }

      numJoueur = pd.ajouterJoueur(pseudo);
      System.out.println(" 1 retour ajouter Pion NumJoueur : " + numJoueur);
      tfMesg = new TextField();

      p = new Puissance4Graphique(pd, numJoueur, tfMesg);
      fj = new FenJoueurs(pd.getNbJoueurs(), p);
      f = new FenJeu(this, tfMesg, p, fj);

      nbCasesX = pd.getDim().width;

      tfMesg.setText("En attente de la connexion des autres joueurs ...");
      while(!pd.connexionTotale()){
        Thread.sleep(1000);
      }

      p.addMouseListener(this);
      tfMesg.setText("Vous etes le joueur " + numJoueur + " sur " + pd.getNbJoueurs());
      fj.afficherNomsJoueurs();
      //fj.repaint();
      fj.setVisible(true);

      determinerTour(true);
      oreille = new Ecouteur(p, numJoueur, f);
 
    }
    catch(Exception e){
      e.printStackTrace();
    }
  }

  
  /** Determine quel joueur possede la main.
    * En debut de partie, verifie sur l'objet distant si un joueur a deja ete 
    * enregistre et s'il a joue.
    * En fin de partie c'est le joueur suivant le dernier joueur (celui qui a gagne) qui joue en
    * premier.
    @param debutPartie vrai si a la fin d'une partie, faux pour un debut ou un milieu de partie
   */
  private void determinerTour(boolean debutPartie){
    
    if(debutPartie){
      // Lors du debut d'une partie
      switch (numJoueur) {
      case '4':
        try{
          if (pd.getDernierJoueur() == '3'){
            tfMesg.setText(tfMesg.getText() + " : Allez-y, le joueur 3 a joue");
          }
        } catch(Exception e){e.printStackTrace();}
      case '3':
        try{
          if (pd.getDernierJoueur() == '2'){
            if (numJoueur == '4')
              tfMesg.setText(tfMesg.getText() + " : C'est le tour de " + pd.getPseudoJoueur('3') );
            else
              tfMesg.setText(tfMesg.getText() + " : Allez-y, le joueur 2 a joue");
          }
        } catch(Exception e){e.printStackTrace();}
      case '2':
        try{
          if (pd.getDernierJoueur() == '1'){
            if (numJoueur == '4' || numJoueur == '3')
              tfMesg.setText(tfMesg.getText() + " : C'est le tour de " + pd.getPseudoJoueur('2'));
            else
              tfMesg.setText(tfMesg.getText() + " : Allez-y, " + pd.getPseudoJoueur('1')  + "  a joue");
          }
        } catch(Exception e){e.printStackTrace();}
      case '1':
        try{
          if (pd.getDernierJoueur() == '0'){
            if (numJoueur == '4' || numJoueur == '3' || numJoueur == '2')
              tfMesg.setText(tfMesg.getText() + " : C'est le tour de " + pd.getPseudoJoueur('1'));
            else
              tfMesg.setText(tfMesg.getText() + " : C'est a vous de commencer");
          }
        } catch(Exception e){e.printStackTrace();}
        break;
      }
    }
    
    // Cas du recommencer a la fin de la partie
    else{ 
      
      try{
        if (pd.prochainJoueur() == numJoueur){
          p.monTour(true);
        }
        else{
          p.monTour(false);
        }
      } catch(Exception e){e.printStackTrace();}
    }
  }

/** Appel lorsque le joueur a clique dans la fenetre de jeu.
    * Si c'est bien le tour du joueur et qu'il a clique dans une colonne
    * non remplie, demande le dessin partiel de la fenetre de jeu.
  */
  public void mouseClicked (MouseEvent e) {
    int largeurCases;
    int colCliquee;

    try{
      // Verifie que la partie n'est pas finie
      if (pd.getJoueurGagnant() == '0'){
        
        largeurCases = f.getSize().width/nbCasesX;    
        colCliquee = (int)(e.getX()/largeurCases);
      
        // Test si c'est bien mon tour de jouer
        if (pd.prochainJoueur() == numJoueur){
        
          // Test si le pion est bien ajoute (colonne non pleine)
          if(pd.ajouterPion(numJoueur, colCliquee)) {
            p.monTour(false);

            if (pd.getJoueurGagnant() == numJoueur){
              // J'ai gagne
              Point[] casesGagnantes = new Point[4]; 
              casesGagnantes = pd.getCasesGagnantes();
              p.setPartieGagnee(true);
              p.setCasesGagnantes(casesGagnantes);
              p.repaint();
              tfMesg.setText("Vous avez gagne");
              f.btRecoActif(true);
            }
            else{
              if (pd.matchNul()){
                // Tableau rempli : personne n'a gagne
                tfMesg.setText("Match nul : vous etes tous mauvais");
                f.btRecoActif(true);
              }

              // Dessine le pion ajoute
              p.setToutPeindre(false);
              p.repaint(); 
            }
            oreille.resume();
          }
        } 
      }
    }
    catch (Exception ex){ex.printStackTrace();}
    //System.out.println("mouseClicked : monTour = " + p.getMonTour());
  }

  /** Appel lorsqu'une action se produit.
    * Gere les actions de selection de la barre de menus.
  */
  public void actionPerformed(ActionEvent e){
    if(e.getSource() instanceof MenuItem){
      String label = ((MenuItem)e.getSource()).getLabel();
      // Cas milieu ou fin de la partie
      if (label.equals("Recommencer")) {
        f.btRecoActif(false);
        try {
          pd.initPartie();
          p.setToutPeindre(true);
          p.setPartieGagnee(false);
          determinerTour(false);
         
          p.repaint();
          p.setJeVeuxRecommencer(true);
          pd.setRecommencer(true);
          //oreille.resume();
        }
        catch(RemoteException re) {re.printStackTrace();}
      }
      else{
        if (label.equals("Quitter")) {
          try {
            pd.setQuitter(true);
          } catch(Exception ex){ex.printStackTrace();}
          System.exit(0);
        }
        else{
          if (label.equals("Traditionnel")) {
            f.setTitle("Puissance 4");
            f.btTradActif(false);
            f.btJavaActif(true);
            f.btFemmesActif(true);
            f.btSimpsonsActif(true);
            p.setGraphique("traditionnel");
            p.repaint();
            fj.repaint();
          }
          else{
           if (label.equals("Java")) {
             f.setTitle("Sun Puissance 4");
             f.btTradActif(true);
             f.btJavaActif(false);
             f.btFemmesActif(true);
             f.btSimpsonsActif(true);
             p.setGraphique("java");
             p.repaint();
             fj.repaint();
           }
           else{ 
             if (label.equals("Femmes")) {
               f.setTitle("Puissance 4 X");
               f.btTradActif(true);
               f.btJavaActif(true);
               f.btSimpsonsActif(true);
               f.btFemmesActif(false);
               p.setGraphique("femmes");
               p.repaint();
               fj.repaint();
             }
             else{ 
               if (label.equals("Simpsons")) {
                 f.setTitle("Puissance 4 Simpsons");
                 f.btTradActif(true);
                 f.btJavaActif(true);
                 f.btFemmesActif(true);
                 f.btSimpsonsActif(false);
                 p.setGraphique("simpsons");
                 p.repaint();
                 fj.repaint();
               }
             }
           }
          }
        }
      }
    }
  }


  /** Appel lorsque le joueur a appuye sur la souris dans la fenetre de jeu.*/
  public void mousePressed (MouseEvent e) {}

  /** Appel lorsque le joueur a relache la souris dans la fenetre de jeu.*/
  public void mouseReleased (MouseEvent e) {}

  /** Appel lorsque la souris entre dans la fenetre de jeu.*/
  public void mouseEntered (MouseEvent e) {}

  /** Appel lorsque la souris sors de la fenetre de jeu.*/
  public void mouseExited (MouseEvent e) {}

}
