
//////////////////////////////////////////////////
//          Jeu de Morpion Tetedechat V0        //
//     Classe MorpionGraphique pour le client   //
//////////////////////////////////////////////////




//Declaration des imports
import java.awt.*;
import java.awt.event.*;
import java.awt.Image;



/** <B>Caracteristiques :</B><BR>
* 
* Classe graphique principale du client.<BR>Elle represente la fenentre de jeu et gere l'affichage de tous les elements contenus.
* 
* @author Audrey Sanz-Vella
* @author Alexandre Martin
* @see Client
* @see BoiteTeleportation
* @see BoiteRejouer
* @see PlanJeu
* @see PlanFin
* @see JavaMorpiaudAide
*/


//Declaration de la classe  graphique du jeu
public class MorpionGraphique extends Frame implements ActionListener{


    
    //Declaration des variables
    private Client monClient;
    private PlanJeu monPlanJeu;
    private PlanFin monPlanFin;
  
    private Image morPion[];
    private Image imageFond;
    private Image imageFin;

    private MenuBar barreMenu;
    private Menu menuJouer;
    private Menu menuQuitter;
    private Menu menuAide;
    private MenuItem teleportation;
    private MenuItem rejouer;
    private MenuItem quitterPartie;
    private MenuItem quitterJeu;
    private MenuItem aide;

    private TextArea zoneTexte;
    private TextField dialogue;

    private boolean planJeuAffiche=false;
   
    //private MorpSon morpSon;




    /** Constructeur du MorpionGraphique.<BR>
     * il charge les images pour le jeu, et affiche les menus dans un etat precis.
     * @param<code>monClient</code> represente l'instance de la classe client qui appelle MorpionGraphique.
     */

    //Constructeur de la classe
    public MorpionGraphique(Client monClient){

        //Recuperation des variables
        this.monClient=monClient;


        //Chargement des images representant les pions
        //Creation d un chargeur d images
        MediaTracker m=new MediaTracker(this);
        Toolkit monToolkit=this.getToolkit();

        //Creation d un tableau d image pour les differents pions
        morPion=new Image[6];

        //Charge les images
        for (int i=0;i<6;i++){

            morPion[i]=monToolkit.getImage("images/pion"+i+".gif");
            m.addImage(morPion[i],0);
        }
        
        //charge l image de fond
        imageFond = monToolkit.getImage("images/imageFond.gif");
        m.addImage(imageFond,0);

        //charge l image de fin
        imageFin = monToolkit.getImage("images/imageFin.gif");
        m.addImage(imageFin,0);

        //Boucle permettant de charger les images
        try{
            m.waitForID(0);
            }
        catch (InterruptedException e){
            
          System.out.println("Probleme dans le chargement des images");
        }


        //Personnalisation de la fenetre
        this.setSize(600,600);
        this.setTitle("Apprenez en 10 heures a faire un JAVAMORPIAUD V0");
        this.setBackground(Color.white);    
     
        //Definition de la zone de texte
        zoneTexte=new TextArea("",3,200);
        zoneTexte.setEnabled(true);
        zoneTexte.setEditable(false);

        //Definition du textfield permettant de discuter
        dialogue=new TextField(200);
        dialogue.setEditable(true);
        dialogue.addActionListener(this);
      

        //Creation de la barre de menu
        afficherMessage("Creation de la barre de menu 'Special De Course'"); 
        barreMenu = new MenuBar();
        this.setMenuBar(barreMenu);
        
         //Definition du menu Jouer
        menuJouer = new Menu("Jouer");
        menuJouer.add(teleportation=new MenuItem("Teleportation Mr. Spock !!!"));
        menuJouer.add(new MenuItem("-"));
        menuJouer.add(rejouer=new MenuItem("Allez Hop ! Encore Une Ptite Partie..."));
        teleportation.addActionListener(this);
        rejouer.addActionListener(this);

        //Definition du menu Quitter
        menuQuitter=new Menu("Quitter");
        menuQuitter.add(quitterPartie=new MenuItem("Je dis au revoir a mes amis et je quitte la partie !!!"));
        menuQuitter.add(new MenuItem("-"));
        menuQuitter.add(quitterJeu=new MenuItem("Il est trop nul ce jeu, j'me casse..."));
        quitterPartie.addActionListener(this);
        quitterJeu.addActionListener(this); 
      
        //Definition du menu Apropos
        menuAide=new Menu("Qu'est ce qu...");
        menuAide.add(aide=new MenuItem("...Un JavaMorpiaud au juste ????"));   
        aide.addActionListener(this);

        //Ajout des items dans la barre de menus
        barreMenu.add(menuJouer);
        barreMenu.add(menuQuitter);
        barreMenu.add(menuAide);


          //Creation d un layout
        setLayout(new BorderLayout());
        add("North",zoneTexte);
        add("South",dialogue);

        //Mise en place des etats de menus
        setJeu(false);

        //Creation d'une instance de la classe regissant les sons
        // morpSons=new MorpSons("son0.au");
 
        //Ajout d un ecouteur pour la fermeture de la fenetre
	addWindowListener(new WindowAdapter(){
	    public void windowClosing(WindowEvent we){
		//Cas ou l'on n'est pas connecte
		if (getMonClient().getJoueurTour()==true){
                    
 		    afficherMessage("Hep Petit, Pense donc a jouer ton tour avant de partir...\nHistoire de ne pas bloquer les autres...");
                }
		else {
                    quitterJeu(getMonClient().getConnexion());
                }
	    }//Fin de la methode windowClosing
	}//Fin de la classe WindowAdapter 
	    );
        
        //Affichage de la fenetre
        this.setVisible(true);

        //Creation d'un thread pour le son
        //morpSon=new MorpSon();
 
    }//Fin constructeur









    /** Methode utilisee definir l'etat des menus et la valeurs des variables.
     * @param <code>etatJeu</code> definit l'etat du jeu -true si l'on se connecte - false si la partie est finie.
     */

    //Methode permettant de definir les variables et les menus en fonction de l'etat du jeu
    public void setJeu(boolean etatJeu){

        //Cas ou le jeu n est pas active
        if (etatJeu==false){
            
          //Changement des etats des menus
          dialogue.setEnabled(false);
          quitterPartie.setEnabled(false);

          quitterJeu.setEnabled(true);

          try{
            monClient.setReponseServeur("attente");
            monClient.setJoueurTour(false);
            
          }//Fin du try
          catch(Exception e){
            e.printStackTrace();
            System.out.println("Probleme d'execution de setJeu");
          }
            
          //Cas ou le RMISecurityManager n'existe pas encore
          if (monClient.getInitialisationRMIManager()==true){
            
            //Modification des menus en consequence
            //(la deuxieme possibilite de se connecter doit etre desactivee)
            teleportation.setEnabled(true);
            rejouer.setEnabled(false);
          }
          else{
            menuJouer.setEnabled(true);
            rejouer.setEnabled(true);
          }//Fin du else
          
        }//Fin du cas ou etatjeu=false

        else{
            
          //Changement des etats des menus
          dialogue.setEnabled(true);
          quitterPartie.setEnabled(true);
          quitterJeu.setEnabled(true);
            
          menuJouer.setEnabled(false);

          //Mise a jour des variables
          monClient.setConnexion(true);
          
        }//Fin du else

    }//Fin de la methode setJeu



  

        

    /** Methode utilisee pour afficher des informations dans la zone de texte.
     * @param <code>message1</code> premiere chaine de caracteres a afficher.
     */

    //Methode permettant l affichage d une chaine String sur la fenetre du client
    public void afficherMessage(String message1){
        
        zoneTexte.append("******************************************\n\n"+message1+"\n\n");
    
    }//Fin de la methode afficherMessage



    /** Methode utilisee pour afficher des informations dans la zone de texte.
     * @param <code>message1</code> premiere chaine de caracteres a afficher.
     * @param <code>nombre</code> nombre a afficher.
     * @param <code>message2</code> seconde chaine de caracteres a afficher.
     */

    //Methode permettant l affichage d une chaine String et d une variable int sur la fenetre du client
    public void afficherMessage(String message1, int nombre, String message2){
      
        zoneTexte.append("******************************************\n\n"+message1+nombre+message2+"\n\n");
 
    }//Fin methode afficherMessage


    /** Methode utilisee pour afficher des informations dans la zone de texte.
     * @param <code>message1</code> premiere chaine de caracteres a afficher.
     * @param <code>message2</code> seconde chaine de caracteres a afficher.
     */

    //Methode permettant l affichage de deux chaines String sur la fenetre du client
    public void afficherMessage(String message1,String message2){
    
        zoneTexte.append("******************************************\n\n"+message1+message2+"\n\n");
        
    }//Fin de la methode afficherMesssage
    







    /** Methode utilisee pour gerer les evenements des actionlistener.
     * @param <code>ActionEvent</code> evenement d'action.
     */

    //Methode regissant les evenements
    public void actionPerformed(ActionEvent e){
        
        if (e.getSource()==teleportation){
            
            //Affiche la boite de dialogue lorsqu on veut se connecter pour la premiere fois
            new BoiteTeleportation(this);


        }else if (e.getSource()==rejouer){
            
            //Affiche la boite de dialogue permettant de refaire une partie
            new BoiteRejouer(this);
        

        }else if (e.getSource()==dialogue){

            //Affiche la boite de dialogue permettant de refaire une partie
                monClient.chat(dialogue.getText());
                dialogue.setText("");
  

        }else if (e.getSource()==quitterPartie){

            //Regarde si le joueur doit jouer
            if (monClient.getJoueurTour()==true){
                    
                afficherMessage("Hep Petit, Pense donc a jouer ton tour avant de partir...\nHistoire de ne pas bloquer les autres...");
            }
            else{
            
                //tente la deconnection sur le serveur
                monClient.deconnecterClient();
                
                //Regarde si le canvas planjeu existe
                if (planJeuAffiche==true){

                    monPlanJeu.removeNotify();
                }
                
                //Reinitialise les menus    
                setJeu(false);
            }


        }else if (e.getSource()==quitterJeu){

            //Regarde si le client doit jouer
           if (monClient.getJoueurTour()==true){
                    
 		    afficherMessage("Hep Petit, Pense donc a jouer ton tour avant de partir...\nHistoire de ne pas bloquer les autres...");
                }
		else {
                    quitterJeu(monClient.getConnexion());
                }
        }else if(e.getSource()==aide){

          //Affiche l'aide du jeu
          new JavaMorpiaudAide();

        }//Fin du choix de sources d'evevenements

    }//Fin de la methode actionPerformed









    /** Methode permettant d'afficher le plan de jeu.
     * 
     * @param <code>nomClient</code> nom du client.
     * @param <code>nomClient</code> Nombre de joueurs definitif pour la partie (utilise pour definir le nombre de cases sur l'echiquier).
     */

    //Methode pour faire afficher le jeu
    public void afficherJeu(String nomClient,int nbJoueurs){
         
        //Affichage d'un nouveau titre de fenetre
        this.setTitle("Le JAVAMORPIAUD de Mr. "+nomClient+" est servi...");
        
        //Envoie d'un message et creation d'une instance de la frame servant de plateau de jeu
        afficherMessage(" Et c est parti....!!!");
        monPlanJeu=new PlanJeu(this,nbJoueurs);
        this.add(monPlanJeu);
        this.pack();

        //Mise a jour de la zone de texte et de la variable planJeuAffiche
        zoneTexte.setText("");
        planJeuAffiche=true;
    
    }//Fin de la methode afficherJeu







  /** Methode utilisee pour afficher un pion.
   * @param <code>numeroJoueur</code> Numero du pion a afficher.
   * @param <code>caseX</code> numero de colonne
   * @param <code>caseY</code> numero de ligne
   */
   
    //Methode permettant l affichage d un pion
    public void afficherMorPion(int numeroJoueur,int numeroCaseX, int numeroCaseY){

 
        //calcul des coordonnees de depart
        int xDepart=(monPlanJeu.getLargeurCase())*numeroCaseX;
        int yDepart=(monPlanJeu.getHauteurCase())*numeroCaseY;

        //Joue un son
        //morpSon.start();

        //Redefinition de l image de fond
        Graphics g=monPlanJeu.getImage().getGraphics();
        g.drawImage(getMorPion(numeroJoueur),xDepart,yDepart,monPlanJeu.getLargeurCase(),monPlanJeu.getHauteurCase(),this);

        //Rafraichissement du plan de jeu
        repaint();
        invalidate();
        monPlanJeu.repaint();

    }//Fin de la methode afficherMorPion
 







    /** Methode utilisee pour quitter le jeu.
     * Si le joueur est conecte, elle verifie que ce n'est pas le tour de jeu du client.
     * @param <code>connecte</code> definit si le joueur est connecte.
     */

    //Methode permettant de quitter le jeu
    public void quitterJeu(boolean connecte){

        if (connecte==true){
            
            //Envoi d'un message au serveur
            monClient.deconnecterClient();
        }
        
        //fermeture de l'application
        System.exit(0);
            
    }//Fin de la methode quitterJeu



    /** Methode utilisee pour afficher un ecran de fin de jeu.
     * @param <code>nomJoueurGagnant</code> indique le nom du joueur gagnant.
     * @param <code>numeroEvenement</code> indique un numero d'evenement particulier.
     */

    //Methode permettant d'afficher l'ecran gagnant
    public void afficherJoueurGagnant(String nomJoueurGagnant,int numeroEvenement){
 
        //Creation d'un nouvel canvas qui contient le nom du gagnant et son pion
        
        //Suppression du canvas planjeu
        monPlanJeu.removeNotify();

        //Efface la zone de texte et reinitialise les menus
        zoneTexte.setText("");
        setJeu(false);
        invalidate();

        //Affichage du canvas JoueurGagnant
        monPlanFin=new PlanFin(this,nomJoueurGagnant,numeroEvenement);
        this.add(monPlanFin);
        this.pack();

    }//Fin de la methode afficherJoueurGagnant






    /** Methode utilisee lors d'un probleme de connexion*/

    //Methode affichant un message et reinitialisant les menus lors d un probleme de connexion
    public void problemeConnexion(){

        //Regarde si le planJeu est affiche
        if (planJeuAffiche==true){

            monPlanJeu.removeNotify();
        }

        //Affiche un message pour l'utilisateur
        afficherMessage("Oups,...Un probleme de connexion....");

        //Reinitialise les menus et variables
        monClient.setConnexion(false);
        setJeu(false);
    
    }//Fin de la methode problemeConnexion






    /////////////////////////////////////////////////////////////////
    // Accesseurs 
    /////////////////////////////////////////////////////////////////



    /** Accesseur permettant definissant une taille minimum pour la fenetre.*/

    //Methode definissant une taille minimum pour la fenetre
    public Dimension getPreferredSize(){
       
        return new Dimension(600,500);
    
    }//Fin de la methode getPrefferedSize



    /** Accesseur permettant d'obtenir une taille minimum pour la fenetre.*/

    //Methode renvoyant la taille minimum pour la fenetre
    public Dimension getMinimumSize(){
        
        return getPreferredSize();
       
    }//Fin de la methode getMinimumSize
    

    /** Accesseur permettant d'acceder aux images du tableau morPion.*/

    //Methode permettant d'acceder aux images du tableau morPion
    public Image getMorPion(int numeroImage){

        return morPion[numeroImage];

    }//Fin de la methode getMorpion


    /** Accesseur permettant d'acceder a l'image de fond.*/

    //Methode permettant d'acceder a l'image de fond 
    public Image getImageFond(){

        return imageFond;

    }//Fin de la methode getImageFond


    /** Accesseur permettant d'acceder a l'image de find.*/

    //Methode permettant d'acceder a l'image de fin
    public Image getImageFin(){

        return imageFin;

    }//Fin de la methode getImageFin


    /** Accesseur permettant d'acceder a la variable monClient.*/

    //Methode permettant d'acceder a la variable monClient
    public Client getMonClient(){

        return monClient;

    }//Fin de la methode getMonClient




}// fin class MorpionGraphique











