/**Importation des librairies*/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import java.io.*;
import java.net.*;

/**
@author RIGHETTO Dominique
@version 2.0
*/

/**
<APPLET
   code="MorpionClient.class"
   width="500"
   height="300"
   align=middle
   vspace=100
   hspace=200>
   <PARAM Name=hauteur Value="300">
   <PARAM Name=longueur Value="500">
Votre navigateur ne supporte pas le java !
</APPLET>
*/


/**<b>JEU DE MORPION EN MODE CLIENT / SERVEUR </b> <br>
<B><I> Applet du Client</I></B>
<UL>
<LI>Le serveur joue avec les carrés  ( les 1 dans la matrice )</LI>
<LI>Le client  joue avec les cercles ( les 2 dans la matrice )</LI>
</UL>
*/
public class MorpionClient extends Applet implements MouseListener
{
int [][]matrice = new int[3][3];
Socket connexionClient;
String serveur = new String("localhost");

/**Méthode pour initialiser l'applet*/
public void init()
   {
   addMouseListener(this);
   try
    {
    //Création du Socket de connexion  
    connexionClient = new Socket(serveur,2354);
    System.out.print("SECTION CLIENT => "+serveur);
    //Verification de la connexion
    if(connexionClient.isConnected())
         System.out.println("  : Connexion reussie.");
       else
         System.out.println("  : Connexion ratee.");

    //Test d'envoi vers le serveur
    testEnvoi();
    System.out.println("\nLe jeu peut debuter chez le client");
    showStatus("[CLIENT] - Le client ouvre le jeu !");
    JOptionPane.showMessageDialog(null, "Le client joue en premier !","Début du jeu - Client", JOptionPane.WARNING_MESSAGE);
    }

    catch(Exception e)
     {
     JOptionPane.showMessageDialog(null, e.toString(),"connexion sur "+serveur+"[CLIENT]", JOptionPane.WARNING_MESSAGE);
     }
    }//Fin de la méthode init 

/**Méthode pour initialiser le jeu*/
public void initJeu()
   {
   int i,j;

   for(i=0;i<3;i++)
      for(j=0;j<3;j++)
      matrice[i][j]=0;
   }



/**Méthode de test pour un envoie de paquet vers le serveur*/
public void testEnvoi()
{
try
{
 OutputStream sortie    = connexionClient.getOutputStream();
 PrintWriter fluxSortie = new PrintWriter(sortie,false);

System.out.println("[TEST COMMUNICATION]");
fluxSortie.println("Test [Client] vers [Serveur]");
fluxSortie.flush();
System.out.println("[TEST COMMUNICATION TERMINE]");
}
catch(Exception e)
                 {
                 JOptionPane.showMessageDialog(null, e.toString(),"connexion sur "+serveur+"[CLIENT - TestEnvoi()]", JOptionPane.WARNING_MESSAGE);

                 }
}




/**Méthode pour envoyer les coordonnées du point joué au serveur*/
public void envoyerGrille(int x,int y)
{

try
{
 OutputStream sortie           = connexionClient.getOutputStream();
 PrintWriter fluxSortie        = new PrintWriter(sortie,true);
 Integer X                     = new Integer(x);
 Integer Y                     = new Integer(y);
 String  tampon                = new String(X.toString()+";"+Y.toString());

fluxSortie.println(tampon);

}
catch(Exception e)
                 {
                 System.out.println("[EnvoyerGrille()]Erreur : "+e.toString()+" [CLIENT]");
                 }
}


/**Méthode pour recevoir des coordonnées du serveur et maj de la grille*/
public void recevoirGrille()
{

try
{
 InputStream  entree         = connexionClient.getInputStream();
 BufferedReader points       = new BufferedReader(new InputStreamReader(entree));
 String tampon               = new String(points.readLine()+" ");
 int x                       = 0;
 int y                       = 0;



 x = Integer.parseInt(tampon.substring(0,1));
 y = Integer.parseInt(tampon.substring(2,3));

 matrice[x][y] = 1; //indique que le serveur à joué
 repaint();
}
catch(Exception e)
                  {
                  System.out.println("[RecevoirGrille()]Erreur : "+e.toString()+" [CLIENT]");
                  JOptionPane.showMessageDialog(null, "Le serveur a gagné !","Fin du jeu", JOptionPane.INFORMATION_MESSAGE);
                  destroy();
                  }
}





/**Méthode de jeu pour l'humain*/
public void mouseClicked(MouseEvent evt)
   {
   int positionXSouris,positionYSouris;
   int positionXCarre1,positionYCarre1;
   int positionXCarre2,positionYCarre2;
   int positionXCarre3,positionYCarre3;
   int positionXCarre4,positionYCarre4;
   int positionXCarre5,positionYCarre5;
   int positionXCarre6,positionYCarre6;
   int positionXCarre7,positionYCarre7;
   int positionXCarre8,positionYCarre8;
   int positionXCarre9,positionYCarre9;
   Integer H,L;
   boolean finDuJeu;
   int hauteur,longueur,i,j;

   /**Récupération des paramètres de la page HTML*/
   L=new Integer(getParameter("longueur"));
   H=new Integer(getParameter("hauteur"));
   longueur=L.intValue();
   hauteur=H.intValue();
   longueur-=20;
   hauteur-=20;

   /**Affectation des coordonnées de la souris*/
   positionXSouris=evt.getX();
   positionYSouris=evt.getY();

   /**Ordre des carrés
      -------------
      | 1 | 2 | 3 |
      -------------
      | 4 | 5 | 6 |
      -------------
      | 7 | 8 | 9 |
      -------------
     */

   /**Affectation des coordonnées X et Y des différents carrés*/
   positionYCarre1=(int)(hauteur/3);
   positionXCarre1=(int)(longueur/3);

   positionYCarre2=(int)(hauteur/3);
   positionXCarre2=2*((int)(longueur/3));

   positionYCarre3=(int)(hauteur/3);
   positionXCarre3=longueur;

   positionYCarre4=(int)(2*(hauteur/3));
   positionXCarre4=(int)(longueur/3);

   positionYCarre5=2*((int)(hauteur/3));
   positionXCarre5=2*((int)(longueur/3));

   positionYCarre6=2*((int)(hauteur/3));
   positionXCarre6=longueur;

   positionYCarre7=hauteur;
   positionXCarre7=(int)(longueur/3);

   positionYCarre8=hauteur;
   positionXCarre8=2*((int)(longueur/3));

   positionYCarre9=hauteur;
   positionXCarre9=longueur;

   /**Affectation des coordonnées de la matrice interne*/
   i=-1;
   j=-1;

   if(positionXSouris<=positionXCarre1 && positionYSouris<=positionYCarre1)
      {
      i=0;
      j=0;
      }
   else
   if(positionXSouris<=positionXCarre2 && positionYSouris<=positionYCarre2)
      {
      i=0;
      j=1;
      }
   else
   if(positionXSouris<=positionXCarre3 && positionYSouris<=positionYCarre3)
      {
      i=0;
      j=2;
      }
   else
   if(positionXSouris<=positionXCarre4 && positionYSouris<=positionYCarre4)
      {
      i=1;
      j=0;
      }
   else
   if(positionXSouris<=positionXCarre5 && positionYSouris<=positionYCarre5)
      {
      i=1;
      j=1;
      }
   else
   if(positionXSouris<=positionXCarre6 && positionYSouris<=positionYCarre6)
      {
      i=1;
      j=2;
      }
   else
   if(positionXSouris<=positionXCarre7 && positionYSouris<=positionYCarre7)
      {
      i=2;
      j=0;
      }
   else

   if(positionXSouris<=positionXCarre8 && positionYSouris<=positionYCarre8)
      {
      i=2;
      j=1;
      }
   else
   if(positionXSouris<=positionXCarre9 && positionYSouris<=positionYCarre9)
      {
      i=2;
      j=2;
      }

   /**Affectation de l'entier de validation de jeu si l'endroit est libre*/
   if(matrice[i][j]==0 && i!=-1 && j!=-1)
      {
      matrice[i][j]=2;
      finDuJeu=arreterJeu();
      if(!finDuJeu && gagneLeJeu()==0)
         {
         envoyerGrille(i,j);
           showStatus("Le serveur joue - attente des informations..." );
         recevoirGrille();
         showStatus("[données reçues] A vous de jouer ! (vous avez les cercles)");
         }
      }
   }

   /**Autres méthodes non utilisées d'actions de la souris
   Déclaration obligatoire*/
   public void mousePressed(MouseEvent evt){}
   /**Autres méthodes non utilisées d'actions de la souris
   Déclaration obligatoire*/
   public void mouseReleased(MouseEvent evt){repaint();}
   /**Autres méthodes non utilisées d'actions de la souris
   Déclaration obligatoire*/
   public void mouseEntered(MouseEvent evt){}
   /**Autres méthodes non utilisées d'actions de la souris
   Déclaration obligatoire*/
   public void mouseExited(MouseEvent evt){}

   /**Méthode pour déterminer l'arrêt de jeu*/
   public boolean arreterJeu()
      {
      int i,j,nbreDeZero;

      nbreDeZero=0;
      for(i=0;i<=2;i++)
         for(j=0;j<=2;j++)
            if(matrice[i][j]==0)
            nbreDeZero++;

      if(nbreDeZero!=0)
         return(false);
      else
         return(true);
      }

   /**Méthode pour déterminer le gagnant du jeu*/
   public int gagneLeJeu()
      {
      int joueur=0;

      if(matrice[0][0]==matrice[0][1] && matrice[0][1]==matrice[0][2])
         joueur=matrice[0][0];

      if(matrice[1][0]==matrice[1][1] && matrice[1][1]==matrice[1][2])
         joueur=matrice[1][0];

      if(matrice[2][0]==matrice[2][1] && matrice[2][1]==matrice[2][2])
         joueur=matrice[2][0];

      if(matrice[0][0]==matrice[1][0] && matrice[1][0]==matrice[2][0])
         joueur=matrice[0][0];

      if(matrice[0][1]==matrice[1][1] && matrice[1][1]==matrice[2][1])
         joueur=matrice[0][1];

      if(matrice[0][2]==matrice[1][2] && matrice[1][2]==matrice[2][2])
         joueur=matrice[0][2];

      if(matrice[0][0]==matrice[1][1] && matrice[1][1]==matrice[2][2])
         joueur=matrice[0][0];

      if(matrice[0][2]==matrice[1][1] && matrice[1][1]==matrice[2][0])
         joueur=matrice[0][2];
      return (joueur);
      }

   /**Méthode de dessin de la grille*/
   public void paint(Graphics g)
      {
      int i                   = 0;
      int j                   = 0;
      Integer H               = null;
      Integer L               = null;
      int hauteur             = 0;
      int longueur            = 0;


      //Récupération des paramètres
      L=new Integer(getParameter("longueur"));
      H=new Integer(getParameter("hauteur"));
      longueur=L.intValue();
      hauteur=H.intValue();
      longueur-=20;
      hauteur-=20;

      //Dessin des axes
      g.clearRect(10,10,longueur,hauteur);
      g.drawRect(10,10,longueur,hauteur);
      g.drawLine(10+((int)(longueur/3)),10,10+((int)(longueur/3)),hauteur+10);
      g.drawLine(10+(2*((int)(longueur/3))),10,10+(2*((int)(longueur/3))),hauteur+10);
      g.drawLine(10,10+((int)(hauteur/3)),longueur+10,10+((int)(hauteur/3)));
      g.drawLine(10,10+(2*((int)(hauteur/3))),longueur+10,10+(2*((int)(hauteur/3))));
      setBackground(Color.orange);


      //Déroulement du jeu
      for(i=0;i<=2;i++)
         for(j=0;j<=2;j++)
         /*On inverse les coordonnées car par rapport à l'écran les coordonnées internes de la matrice sont inversées ce
         qui met l'affichage à l'envers*/
            {
            if(matrice[j][i]==1)
               {
               g.setColor(Color.blue);
               g.fillRect((int)((((i+1)*0.33)-0.166)*longueur),(int)((((j+1)*0.33)-0.166)*hauteur),10,10);
               }
            if(matrice[j][i]==2)
               {
               g.setColor(Color.red);
               g.fillOval((int)((((i+1)*0.33)-0.166)*longueur),(int)((((j+1)*0.33)-0.166)*hauteur),10,10);
               }
            }
          //Ecriture à l'écran du vainqueur
          g.setColor(Color.black);
          g.setFont(new Font("Comic",2,30));
          switch(gagneLeJeu())
          {
          case 0:{
                if(arreterJeu())
                    {
                    JOptionPane.showMessageDialog(null, "Match Nul !","Fin du jeu", JOptionPane.INFORMATION_MESSAGE);
                    destroy();
                    }
                  break;
                }

          case 2:{
                 JOptionPane.showMessageDialog(null, "Le client a gagné !","Fin du jeu", JOptionPane.INFORMATION_MESSAGE);
                 destroy();
                  break;
                }

          case 1:{
                 JOptionPane.showMessageDialog(null, "Le serveur a gagné !","Fin du jeu", JOptionPane.INFORMATION_MESSAGE);
                destroy();
                  break;
                }
          }
      }


/**Méthode quand on détruit l'applet - elle coupe le connexion avec le serveur*/
public void destroy()
{
try
 {
 connexionClient.shutdownInput();
 connexionClient.shutdownOutput();
 connexionClient.close();
 System.exit(1);
 }
 catch(Exception e)
  {
  JOptionPane.showMessageDialog(null, e.toString(),"deconnexion sur "+serveur, JOptionPane.WARNING_MESSAGE);
  }
}

}//Fin de l'applet