import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import javax.swing.text.*;

public class MonCanvas extends JComponent implements Observer{
  
  private MatriceJeu jeu;
  static int x; // pour sauvegarder la position precedente
  static int y; // meme chose
  private static boolean testTouche = false;
  private Image[] image;
  private MediaTracker MT;
  private static boolean entre = false;
  private static boolean rotate = false;
  private static boolean premiereFois = true;
  private boolean intro;
	
  public MonCanvas() {

    super();
    jeu = new MatriceJeu(20, 12);
    image = new Image[10];
    MT = new MediaTracker(this);
    image[0] = Toolkit.getDefaultToolkit().getImage("fond.jpg");
    image[1] = Toolkit.getDefaultToolkit().getImage("fond2.jpg");
    image[2] = Toolkit.getDefaultToolkit().getImage("fond3.jpg");
    image[3] = Toolkit.getDefaultToolkit().getImage("fond4.jpg");
    image[4] = Toolkit.getDefaultToolkit().getImage("fond5.jpg");
    MT.addImage(image[0], 0);
    MT.addImage(image[1], 0);
    MT.addImage(image[2], 0);
    MT.addImage(image[3], 0);
    MT.addImage(image[4], 0);
    
    try { // MediaTracker en attente de chargement.
      MT.waitForAll();
    }
    catch (InterruptedException e) {}
    setBounds(0, 0, 240, 400);
  }
  
  
  public Dimension getMinimumSize(){

    return new Dimension(300, 300);
  }


  public Dimension getPreferredSize(){
    
    return getMinimumSize();
  }
  
  
  public PieceGenerique getPieceSuivante(){
    
    return jeu.getPieceSuivante();
  }
  
  public MatriceJeu getJeu(){
    
    return jeu;
  }  		

  public void testKey(int d) {
    
    if (d==KeyEvent.VK_LEFT) {
      testTouche = true;
      x = jeu.getPiece().getX(); // on sauve x
      y = jeu.getPiece().getY(); //on sauve y
      jeu.translationGauche();
    }
    else if (d==KeyEvent.VK_RIGHT) {
      testTouche = true;
      x = jeu.getPiece().getX(); // on sauve x
      y = jeu.getPiece().getY(); //on sauve y
      jeu.translationDroite();
    }
    else if (d==KeyEvent.VK_UP) {
      rotation();
    }
    else if (d==KeyEvent.VK_DOWN) {
      testTouche = true;
      x = jeu.getPiece().getX(); // on sauve x
      y = jeu.getPiece().getY(); // on sauve y
      translationBas();
    }
  }

  public void rotation() {
    
    // Avant la rotation, on efface l'objet
    
    /*Graphics g = getGraphics();
    PieceGenerique piece = jeu.getPiece();
    int[][] matrice = piece.getMatrice();
    int x = piece.getX();
    int y = piece.getY();

    rotate=true;
	
    for (int i = 0; i < piece.getTaille(); i++) {
      for (int j = 0; j < piece.getTaille(); j++) {
        if (matrice[i][j] >= 1) {
          g.drawImage(image[jeu.getNiveau()-1],x*20+j*20, y*20+i*20,
                      x*20+j*20+20, y*20+i*20+20,
                      x*20+j*20, y*20+i*20,
                      x*20+j*20+20, y*20+i*20+20,
                      null);  
        }
      }
      }*/
    
    jeu.rotation();
    repaint();
  }

  public void nouveauJeu(){

    Graphics g = getGraphics();
    testTouche = false;
    jeu.init();
    paintComponent(g);
    jeu.setPiece(jeu.pieceSuivante());
    jeu.demarrer();
    jeu.addObserver(this);
  }
  
  /*public void paint(Graphics g){
    /*    if (MT.statusID(0, false) == MediaTracker.COMPLETE) { // Le chargement de l'image est OK.
      g.drawImage(image[0], 1, 1, this); // Affichage de l'image
    }
    g.drawRect(0,0,240,400);
    if (!premiereFois) // boolean sinon ça plante (il reste des nullPointerException mais ça passe
      paintComponent(g); // quand même)
      premiereFois=false;
    }*/
  
  public void translationBas(){
    x=jeu.getPiece().getX();
    y=jeu.getPiece().getY();
    jeu.translationBas();
  }

  public void update(Observable o, Object arg){
    
    if (arg instanceof Touche){
      Graphics g = getGraphics();
      if (!testTouche) {
      	x=jeu.getPiece().getX();
      	y=jeu.getPiece().getY() -1 ;
      }
      testTouche=false; 
      if (MatriceJeu.getLignes()!=0) {
      	MatriceJeu.setLignes(0);
      	paintComponent(g);
      }
      else repaint();
    }
    else if (((Warning) arg).finDeJeu){
      JFrame frameText = new JFrame();
      frameText.setSize(300, 100);
      JPanel jp = new JPanel(new GridLayout(0, 1));
      frameText.getContentPane().add(jp);
      JTextField text = new JTextField("        ici", 15);
      jp.add(new JLabel("Entrez votre nom:"));
      jp.add(text);
      /*frameText.getContentPane().add(new JLabel("Entrez votre nom"));
      frameText.getContentPane().add(text);
      */frameText.setVisible(true);
      try {
        String s = text.getText(0, 15);
        System.out.println(s);
      }
      catch(BadLocationException e){
      }
    }
  }

  public void paintComponent(Graphics g) {
    // Méthode permettant de régénérer le canvas de dessin 
    // après que la fenêtre ait été cachée
    PieceGenerique piece;
        if ((piece = jeu.getPiece()) != null){ 
    int [][] matrice;
    matrice = jeu.getMatrice();
    //dessineObjet(g);
    
    // for (int i = 0; i < piece.getTaille();i++){
//     	for (int j = 0; j < piece.getTaille();j++){
//     		if (matrice[piece.getY()+i][piece.getX()+j] >= 1){
//     				System.out.print("T");
//     			g.setColor(PieceGenerique.getCouleur(matrice[piece.getY()+i][piece.getX()+j]));
//     			dessineCarre(g, piece.getX()+j, piece.getY()+i);
//     		}
//     		else System.out.print("F");
//     	}
//     	System.out.println();
//     }
    
       g.drawImage(image[jeu.getNiveau()-1], 1, 1, this); // Affichage de l'image de fond

    for (int i = 0 ; i < jeu.longueur; i++) {
      for (int j = 0; j < jeu.largeur; j++) {
        if (matrice[i][j] >= 1) {
        	g.setColor(PieceGenerique.getCouleur(matrice[i][j]));
          g.fillRect(j*20, i*20, 20, 20);
          g.setColor(Color.black);
          g.drawRect(j*20, i*20, 20, 20);
          g.drawRect(j*20+1, i*20+1, 18, 18);
          g.drawLine(j*20+18, i*20+2, j*20+18, i*20+18);
          g.drawLine(j*20+16, i*20+3, j*20+16, i*20+16);
          g.drawLine(j*20+4, i*20+16, j*20+16, i*20+16);
         	g.setColor(Color.gray);
          g.drawLine(j*20+17, i*20+2, j*20+17, i*20+18);
          g.drawLine(j*20+3, i*20+17, j*20+17, i*20+17);
          g.drawLine(j*20+2, i*20+18, j*20+17, i*20+18);
          g.setColor(Color.white);
          g.drawLine(j*20+2, i*20+2, j*20+17, i*20+2);
          g.drawLine(j*20+2, i*20+2, j*20+2, i*20+18);
          g.drawLine(j*20+3, i*20+2, j*20+3, i*20+17);
          g.drawLine(j*20+4, i*20+2, j*20+4, i*20+16);
          
        }
      }
    }
  }}
  
  public void dessineObjet(Graphics g) {
    // Dessin d'un objet
    PieceGenerique piece = jeu.getPiece();
     
    int X = piece.getX();
    int Y = piece.getY();
    int [][] matrice = piece.getMatrice();
    
    
    if ((!rotate) && (entre)) {
    				
    		
      
      
      
      
      /*for(int i = piece.getExtremaHaut() + Y; i <= piece.getExtremaBas()+Y;i++){
    		
        if (jeu.getMatrice()[i][x] >=1){
        g.setColor(PieceGenerique.getCouleur(jeu.getMatrice()[i][x]));
        dessineCarre(g, x, i);
        }
        else if (jeu.getMatrice()[i][x] == -1)          
        g.drawImage(image[jeu.getNiveau()-1],
        (x)*20,
          						  (i)*20,
                                                          (X+1)*20,
                                                          (i+1)*20,
                                                          (x)*20,
                                                          (i)*20,
                                                          (x+1)*20,
                                                          (i+1)*20,
                                                          null);
                                                          }
    	
                                                          
                                                          for (int i = piece.getExtremaHaut(); i <= piece.getExtremaBas(); i++) {
        for (int j = piece.getExtremaGauche(); j <= piece.getExtremaDroite(); j++) {
        if (matrice[i][j] >= 1 || jeu.getMatrice()[Y+i][X+j] >=1){
        
        g.setColor(PieceGenerique.getCouleur(jeu.getMatrice()[Y+i][X+j]));
        dessineCarre(g, X+j, Y+i);
        }
        else if (jeu.getMatrice()[Y+i][X+j] == -1)
        
        g.drawImage(image[jeu.getNiveau()-1],(X+j)*20, (Y+i)*20,
                        (X+j+1)*20, (Y+i+1)*20,
                        X*20+j*20, Y*20+i*20,
                        X*20+j*20+20, Y*20+i*20+20,
                        null);
        }
      }
      
//       System.out.println("X = ," + X + "Y = ,"+ Y + ", x = " + x +", y = "+ y);
//       System.out.println(piece.getExtremaDroite() - piece.getExtremaGauche() + 1);
//       for (int i = piece.getExtremaGauche();i <= piece.getExtremaDroite();i++){
//         g.drawImage(image[1],
//                     (x+i)*20, (y+piece.getExtremaHaut())*20, (x+i)*20+20, (y+piece.getExtremaHaut())*20+20,
//                     0, 0, 20, 20,
//                     null);
//       }
                  
    }
    /*for (int i = 0;i < piece.getTaille(); i++){
      for (int j = 0; j < piece.getTaille(); j++){
        if (matrice[i][j] >= 1){
          g.setColor(PieceGenerique.getCouleur(jeu.getMatrice()[y][i]));
          dessineCarre(g, i, y);
        }
      }*/
    }
    entre=true;
    rotate=false;
  }
  
  public static void setEntre(){
    
    entre = false;
  }
  
  public void dessineCarre(Graphics g, int X, int Y){

    g.fillRect((X) * 20, (Y) * 20, 20, 20);
    g.setColor(Color.black);
    g.drawLine((X)*20, (Y) * 20, (X) * 20 + 19, (Y) * 20);
    g.drawLine((X)*20, (Y) * 20, (X) * 20, (Y) * 20 + 19); 
    g.drawRect((X) * 20+1, (Y) * 20+1, 18, 18);
    g.drawLine((X) * 20+18, (Y) * 20+2, (X) * 20+18, (Y) * 20+18);
    g.setColor(Color.gray);
    g.drawLine((X) * 20+17, (Y) * 20+2, (X) * 20+17, (Y) * 20+18);
    g.drawLine((X) * 20+3, (Y) * 20+17, (X) * 20+17, (Y) * 20+17);
    g.drawLine((X) * 20+2, (Y) * 20+18, (X) * 20+17, (Y) * 20+18);
    g.setColor(Color.white);
    g.drawLine((X) * 20+2, (Y) * 20+2, (X) * 20+17, (Y) * 20+2);
    g.drawLine((X) * 20+2, (Y) * 20+2, (X) * 20+2, (Y) * 20+18);
    g.drawLine((X) * 20+3, (Y) * 20+2, (X) * 20+3, (Y) * 20+17);
    g.drawLine((X) * 20+4, (Y) * 20+2, (X) * 20+4, (Y) * 20+16);
  
	}

  public void update(Graphics g){
    
    PieceGenerique piece = jeu.getPiece();
    
        
    Graphics offgc;
    Image offscreen = null; 
    Dimension d = getSize();
    
    offscreen = createImage(d.width, d.height);
    offgc = offscreen.getGraphics();
    paintComponent(offgc);
    g.drawImage(offscreen, 0, 0, this);
  }

  public void repaint(){
    
    System.out.println("repaint");
    update(getGraphics());
  }
}












