import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Random;

public class Node_Rectangular 
{
	 private String	              	id;
	 private String              	name;
	 private Point2D             	location;
	 
	 private Rectangle2D 			bounds;
	 
	 
	 private int					x1;
	 private int					y1;
	 private int					w;
	 private int					h;
	 
	 
	 	 
	 private ArrayList<Edge_transition>  incidentEdges;
	 
	
	 private boolean             	selected;
	 private boolean			 	loopback_status;
	 private boolean			 	reset_status;
	 private Color					state_color;
	 private Color					text_color;
	 private LoopbackObj 			loop_obj;
	 
	 private int					x_default_name = 0;
	 private int					y_default_name = 0;
	 
	 private int					xcentre = 0;
	 private int					ycentre = 0;
	 
	 
	 public Node_Rectangular() 
	 { 
		 
	 }
	
	 public Node_Rectangular(String name, Point2D aPoint) 
	 {
		 this.name = name;
	     location = aPoint;

	     
	     //0123456789 0123456789 01    22 caracteres
	     w = 240;
	     h = 60;
	     
	     xcentre = (int) aPoint.getX();
		 ycentre = (int) aPoint.getY();
		
		 x1 = xcentre - (w /2);
		 y1 = ycentre - (h /2);
		 // xcentre = x1 + (w /2);
 	     // ycentre = y1 + (h /2);
		 
	     // x1 = (int) aPoint.getX();
	     // y1 = (int) aPoint.getY();
	 
	     // xcentre = x1 + (w /2);
	     // ycentre = y1 + (h /2);
	     
	     incidentEdges = new ArrayList<Edge_transition>();
	     selected = false;
	     loopback_status = false;
	     reset_status = false;
    	 state_color = Color.BLACK;
	     text_color = Color.BLACK;
	     
		 id = generate_id();
	    	
	        
	}
	 
	 public void addIncidentEdge(Edge_transition e) 
	 { 
		 incidentEdges.add(e); 
	 } 
	 
	 public ArrayList<Edge_transition> incidentEdges() 
	 { 
		 return incidentEdges; 
	 }
	 
	 public void setX1(int val)
	 {
		 x1 = val;
	 }  
		    
	 public int getX1()
	 {
		 return x1;
	 }
			    
	 public void setY1(int val)
	 {
		 y1 = val;
	 }  
		    
	 public int getY1()
	 {
		 return y1;
	 }
	 
	 
	 public void setWidth(int val)
	 {
		 w = val;
	 }  
		    
	 public int getWidth()
	 {
		 return w;
	 }
			    
	 public void setHeight(int val)
	 {
		 h = val;
	 }  
		    
	 public int getHeight()
	 {
		 return h;
	 }
	 
	 /*************/
	 public void setCentreX()
	 {
		 xcentre = x1 + (w/2);
	 
		 
	 }  
		    
	 public int getCentreX()
	 {
		 return xcentre;
	 }
			    
	 public void setCentreY()
	 {
		 ycentre = y1 + (h/2);
	 }  
		    
	 public int getCentreY()
	 {
		 return ycentre;
	 }
	 
	 
	 
	 public boolean contains(Point2D p)
	 {
		 
		 Rectangle r = new Rectangle (x1,y1,w,h);    
		 
	      return r.contains(p);
	 }
	 
	 
	 public void draw02(Graphics2D g2)
	 {
		 int widthInPixels = 0;
		 int heightInPixels = 0;
    	 int cpt_ligne = 0;
    	 int x = 0;
    	 int y = 0; 
		 
    	 //
		 Font currentFont = g2.getFont();
		 FontMetrics fm=g2.getFontMetrics( currentFont );
    	 
		 // couloeur 
		 if( selected == true)
		 {
			 g2.setColor(Color.RED);
		 }
		 else
		 {	
			 g2.setColor(Color.BLACK);
		 }
		 
		 // detection des retours à la ligne
    	 String[] lines = name.split("\\r?\\n");
    	 // compte les lignes
         for (String line : lines) 
         {
        	 cpt_ligne++;
         }
    	 
    	 if(cpt_ligne == 1)
    	 {
    		 // taille de la font
    		 widthInPixels = fm.stringWidth(name);
    		 heightInPixels = fm.getHeight();
 	    	 x = xcentre - (widthInPixels /2);
 	    	 y = ycentre + (heightInPixels / 2); 
  	    	 g2.drawString(name, x, y );
  	    	 Rectangle2D rect_obj = new Rectangle2D.Double(x1, y1, w, h);
  	  	 	 g2.draw(rect_obj);
    	 }
    	 else
    	 {
    		 // recherche la chaine la plus longue
    		 String longestString = getLongestString(lines);
    		 widthInPixels = fm.stringWidth(longestString);
    		 heightInPixels = fm.getHeight();
    		 
    		 for (int i = 0; i < cpt_ligne; i++) 
   		  	 {
	   			  if( i == 0)
	   			  {	  
	   			     int delta_x = (w - widthInPixels) /2;
	       			 int delta_y = (h - heightInPixels) /2;
	       			 x = x1 + delta_x;
	       			 y = y1 + delta_y + heightInPixels;
	    	    	 g2.drawString(lines[i], x, y);
	   			  }   
	   			  else
	   			  {
   				     y = y + heightInPixels;
   					 g2.drawString(lines[i], x, y);
	   			  }
   			     
   		  	 }
   	
   		  	int new_h =  y + 30 - y1;
   		  	Rectangle2D rect_obj = new Rectangle2D.Double(x1, y1, w, new_h);
	    	g2.draw(rect_obj);
    	 }
	 
	 }
	 
	 public void draw(Graphics2D g2)
	 {
	 
		 int widthInPixels = 0;
		 int heightInPixels = 0;
		 
	//	 Font font = new Font("Verdana", Font.PLAIN, 12);  
	//	 FontMetrics metrics = new FontMetrics(font) {       	    };  
	//	 Rectangle2D rect_bounds = metrics.getStringBounds( name , null);  
	//	 int widthInPixels = (int) rect_bounds.getWidth(); 	
 	 //    int heightInPixels = (int) rect_bounds.getHeight(); 	
 	     
 	     // default
 	
	//   bien pour connaitre la taille de la font	 
	//	 https://stackoverflow.com/questions/368295/how-to-get-real-string-height-in-java
		 
		 Font currentFont = g2.getFont();
		 FontMetrics fm=g2.getFontMetrics( currentFont );
		 // int widthInPixels = fm.stringWidth(name);
		 //int heightInPixels = fm.getHeight();
 	     
		 
		
	    	 
    	 int cpt_ligne = 0;
    	 String[] lines = name.split("\\r?\\n");
    	
         for (String line : lines) 
         {
        	 cpt_ligne++;
         }
         
         //
         
         //int ligne = name.split(System.getProperty("line.separator")).length;
    	 System.out.println("------>  Nb ligne " + cpt_ligne);
         
    	
    	 
    	 if(cpt_ligne == 1)
    	 {
    		 widthInPixels = fm.stringWidth(name);
    		 heightInPixels = fm.getHeight();
    		 
    		 if( widthInPixels + (2 * 30) < w ) 
    		 {
    			 int delta_x = (w - widthInPixels) /2;
    			 int delta_y = (h - heightInPixels) /2;
 	    	 
    			 // identique
    			 int xtest = xcentre - (widthInPixels /2);
    			 int x = x1 + delta_x;
 	    	 
    			 // identique
    			 int ytest = ycentre + (heightInPixels / 2); 
    			 int y = y1 + delta_y + heightInPixels;
 			 
 	    	 	 System.out.println(" Centre un " + xcentre + "  " + ycentre);
 	    	 
 	    	 	 g2.drawString(name, x, y);
 	    	 
 	    	 	 Rectangle2D top = new Rectangle2D.Double(x1, y1, w, h);
 	    	 	 g2.draw(top);
 	    	  	    	 
 	    	 	 g2.setColor(Color.RED);
 	    	 	 Rectangle2D enveloppe = new Rectangle2D.Double(x, y -heightInPixels , widthInPixels, heightInPixels);
 	    	 	 g2.draw(enveloppe);
 	    	 
 	    	 	 System.out.println("un \n");
    		 }
    		 else
    		 {
     	    	 
     	    	 int x = xcentre - (widthInPixels /2);
     	    	 int y = ycentre + (heightInPixels / 2); 
     	    	 
      	    	 x1 = x - 30;
      	    	 y1 = ycentre - 30;
      	    	 
      	    	 int new_w =  widthInPixels + 60;
      	    	 
      	    	 g2.drawString(name, x, y );
     	    	 
     	    	 Rectangle2D top = new Rectangle2D.Double(x1, y1, new_w, h);
     	    	 g2.draw(top);
     	    	 
     	 	     System.out.print(" Centre deux " + xcentre + "  " + ycentre);

     	 	     g2.setColor(Color.RED);
    	    	 Rectangle2D enveloppe = new Rectangle2D.Double(x, y -heightInPixels , widthInPixels, heightInPixels);
    	    	 g2.draw(enveloppe); 
    		 }
     	     
    	 }
    	 // 
    	 
    	 if(cpt_ligne != 1)
    	 {
    		 
    		 String longestString = getLongestString(lines);
    		 widthInPixels = fm.stringWidth(longestString);
    		 heightInPixels = fm.getHeight();
    		 
    		 /*****  taille réduite  ****/
    		  if( widthInPixels + (2 * 30) < w ) 
    		  {
    			  System.out.println("Multiple line court..");
    			  
        		  int x = 0, y = 0;
        		 
        		  for (int i = 0; i < cpt_ligne; i++) 
        		  {
        			  
        			  if( i == 0)
        			  {	  
        			     widthInPixels = fm.stringWidth( lines[i] );
        			     heightInPixels = fm.getHeight();
        			     
        			     int delta_x = (w - widthInPixels) /2;
            			 int delta_y = (h - heightInPixels) /2;
            			 
            			 x = x1 + delta_x;
            			 y = y1 + delta_y + heightInPixels;
         	    	 
         	    	 	 g2.drawString(lines[i], x, y);
        			     
        			  }   
        			  else
        			  {
        				     y = y + heightInPixels;
        					 g2.drawString(lines[i], x, y);
        			  }
        			     
        		  }

        	
        		  int new_h =  y + 30 - y1;
        		  Rectangle2D top = new Rectangle2D.Double(x1, y1, w, new_h);
    	    	  g2.draw(top);
    			  
    		  }
    		  else
    		  {
	    			  System.out.println("Multiple line long..");
	    			  
	    			  int x = xcentre - (widthInPixels /2);
	      	    	  int y = ycentre + (heightInPixels / 2); 
	      	    	  
	      	    	  int new_w = widthInPixels + 2 * 30;
	      	    	 
	       	    	  x1 = x - 30;
	       	    	  y1 = y - 30;
	      	    	 
	       	    	  for (int i = 0; i < cpt_ligne; i++) 
	      		      {
	      			  
	       	    		 y = y + heightInPixels;
	 					 g2.drawString(lines[i], x, y);
	      			     
	      			  }   
	       	    	  
	       	    	 int new_h =  y + 30 - y1;
	       	    	 Rectangle2D top = new Rectangle2D.Double(x1, y1, new_w, new_h);
	       	    	 g2.draw(top);
      			 
      			     
      		  }
       	    	 
       	    	 
       	    	 
       	    	 
       	    	 
       	    	 
       	    
    		  
    			  
 /*   			  
    		  System.out.println("Multiple line ..");
    		  int x = 0, y = 0;
    		  
    		  String longestString = getLongestString(lines);
    		  
    		  
    		  
    		  /*****  taille réduite  ****/
/*    		  for (int i = 0; i < cpt_ligne; i++) 
    		  {
    			  
    			  if( i == 0)
    			  {	  
    			     widthInPixels = fm.stringWidth( lines[i] );
    			     heightInPixels = fm.getHeight();
    			     
    			     int delta_x = (w - widthInPixels) /2;
        			 int delta_y = (h - heightInPixels) /2;
        			 
        			 x = x1 + delta_x;
        			 y = y1 + delta_y + heightInPixels;
     	    	 
     	    	 	 g2.drawString(lines[i], x, y);
    			     
    			  }   
    			  else
    			  {
    				     y = y + heightInPixels;
    					 g2.drawString(lines[i], x, y);
    			  }
    			     
    		  }

    	
    		  int new_h =  y + 30 - y1;
    		  Rectangle2D top = new Rectangle2D.Double(x1, y1, w, new_h);
	    	  g2.draw(top);
  */  		  
    	 }
 	     
 	     //System.out.print("----> " + x1 + "  " + y1 + "  " + xcentre + "  " + ycentre);

    	 /*
    	 
 	     if(w > widthInPixels + 2 * 25 && h > heightInPixels + 2 * 15)
 	     {	 
 	    	 
 	    	 int delta_x = (w - widthInPixels) /2;
 	    	 int delta_y = (h - heightInPixels) /2;
 	    	 
 	    	 // identique
 	    	 int xtest = xcentre - (widthInPixels /2);
 	    	 int x = x1 + delta_x;
 	    	 
 	    	 // identique
 	    	 int ytest = ycentre + (heightInPixels / 2); 
 	    	 int y = y1 + delta_y + heightInPixels;
 			 
 	    	
 	    	//  System.out.print(" Position x et y : " + xtest + "  " + x + "  " + ytest + "  " + y );
 	    	 
 	 	     System.out.print(" Centre un " + xcentre + "  " + ycentre);

 	    	 
 	    	 
 	    	 g2.drawString(name, x, y);
 	    	 
 	    	 Rectangle2D top = new Rectangle2D.Double(x1, y1, w, h);
 	    	 g2.draw(top);
 	    	 
 	    	 
 	    	 g2.setColor(Color.RED);
 	    	 Rectangle2D enveloppe = new Rectangle2D.Double(x, y -heightInPixels , widthInPixels, heightInPixels);
 	    	 g2.draw(enveloppe);
 	    	 
 	    	 System.out.print("un \n");
 	     }
 	     
 	     if(w < widthInPixels + 2 * 25 && h > heightInPixels + 2 * 15)
 	     {
 	    	 
 	    	 ligne = name.split(System.getProperty("line.separator")).length;
 	    	 System.out.print(" Nb ligne \n" + ligne);
 	    	 
 	    	 int x = xcentre - (widthInPixels /2);
 	    	 int y = ycentre + (heightInPixels / 2); 
 	    	 
  	    	 x1 = x - 30;
  	    	 y1 = ycentre - 30;
  	    	 
  	    	 w =  widthInPixels + 60;
  	    	 //h =  60; //heightInPixels + 2 * 30;
  	    	 int h  = (ligne + ligne - 1) * g2.getFontMetrics().getHeight() + 2 * 30; 
	    	 
  	    	 
  	    	 for (String line : name.split("\n"))
     	        g2.drawString(line, x, y += g2.getFontMetrics().getHeight());
  	    	 
 	    	
  	    	 //g2.drawString(name, x, y);
 	    	 
// 	    	 int x = rect_milieu_x - (widthInPixels / 2);
// 	    	 int y = rect_milieu_y + (heightInPixels / 2 );
// 	    	 g2.drawString(name, x, y);

// 	    	x1 = x - 25;
// 	    	y1 = y - heightInPixels - 25;
// 	    	w = widthInPixels + 2 * 25;
// 	    	h =  heightInPixels + 2 * 25;
// 	    	 aaa
 	    	 
// 	    	 int delta_x = (w - widthInPixels) /2;
// 	    	 int delta_y = (h - widthInPixels) /2;
 	    	 
// 	    	 int x = x1 + delta_x;
// 	    	 int y = y1 + delta_y + heightInPixels;
 			 
 	    	 
 	    	 Rectangle2D top = new Rectangle2D.Double(x1, y1, w, h);
 	    	 g2.draw(top);
 	    	 
 	 	     System.out.print(" Centre deux " + xcentre + "  " + ycentre);

 	 	     g2.setColor(Color.RED);
	    	 Rectangle2D enveloppe = new Rectangle2D.Double(x, y -heightInPixels , widthInPixels, heightInPixels);
	    	 g2.draw(enveloppe);
 	 	     
 	     }
 	     */
 	    	 
	 }
	 
	 
	 public String getLongestString(String[] array) 
	 {
	      int maxLength = 0;
	      String longestString = null;
	      
	      for (String s : array) 
	      {
	          if (s.length() > maxLength) 
	          {
	              maxLength = s.length();
	              longestString = s;
	          }
	      }
	      return longestString;
	  }
	 
	 public void setName(String val)
	 {
		 name = val;
	 }
	 
	 public String getName()
	 {
		 return name;
	 }
	
	 
	  public boolean isSelected() { return selected; }
	    
	    public void setSelected(boolean state) { selected = state; }
	    
	    public void setUnSelected(boolean state) { selected = state; }
	    
	    public void toggleSelected() { selected = !selected; }
	    
	 public String generate_id()
	 {
		  int max = 100;
		  int min = 1;
		  Random randomNum = new Random();
		  int id = min + randomNum.nextInt(max);
		  System.out.println("Random id " + id );
		  String tmp = "ID"+ Integer.toString(id);
		  return tmp;
	 }
	    
	
	 public String getID()
	 {
		 return id;
	 }
	    
}
