import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Random;

public class ChartObj 
{
	// COMMON 
	private String	              			id;
	private String 							obj_type;
	private String							text;
	private Point							location;
	private int								xcentre = 0;
	private int								ycentre = 0;
	private boolean             			selected;
	private static Color					obj_color;
	private static Color					text_color;
	
	private ArrayList<TransitionObj>  		incidentEdges;     
	
	// Activity
	private int								w_activity;
	private int								h_activity;
	private int								x1;
	private int								y1;
	 
	// Decision
	private Point             				p1;
	private Point             				p2;
	private Point             				p3;
	private Point             				p4;
	private int								w_decision;
	private	int								h_decision;	
	
	public ChartObj() 
	{
		incidentEdges = new ArrayList<TransitionObj>();
	}

	public ChartObj(String obj_type, Point location) 
	{
		// commun
		//incidentEdges = new ArrayList<Edge_transition>();
		this.obj_type = obj_type;
		this.text = "none";
		this.location = location;
		this.xcentre = (int) location.getX();
		this.ycentre = (int) location.getY();
		this.selected = false;
		this.obj_color = Color.BLACK;
		this.text_color = Color.BLACK;
		
		incidentEdges = new ArrayList<TransitionObj>();
		
		if(obj_type.equals("ACTIVITY_OBJ"))
		{
			// default
			this.w_activity = 240;
			this.h_activity = 60;
			
            // x1, y1
	    	//        **************    
	        //        *            *
	        //        *            * 
	        //        *            *
	    	//        **************    
	        //         
						
			this.x1 = xcentre - (w_activity /2);
			this.y1 = ycentre - (h_activity /2);
	     
			id = generateObjUD("A");
		}	
		else
		{

	    	//         P2
	        //         *
	        //       *   * 
	        // P1  *       *  P3
	        //       *   *
	        //         *
	        //         P4
	        //
			
			// default
			this.w_decision = 100;
			this.h_decision = 100;
	    	
	    	p1 = new Point();
	    	p2 = new Point();
	    	p3 = new Point();
	    	p4 = new Point();
	    	
	    	//p1.setLocation( (int) (location.getX() - (w_decision/2))  , (int)location.getY());
	    	//p2.setLocation( (int) (location.getX() )  ,  (int) (location.getY() - (h_decision/2)) );
	    	//p3.setLocation( (int) (location.getX() + (w_decision/2))  , (int)location.getY());
	    	//p4.setLocation( (int) (location.getX() )  ,  (int) (location.getY() + (h_decision/2)) );
	    	
	    	p1.setLocation( xcentre - (w_decision/2) , ycentre );
	    	p2.setLocation( xcentre  ,  ycentre - (h_decision/2) );
	    	p3.setLocation( xcentre + (w_decision/2)  , ycentre );
	    	p4.setLocation( xcentre  ,  ycentre + (h_decision/2) );
			id = generateObjUD("D");
		}
		
	}
	
	public void addIncidentEdge(TransitionObj obj) { incidentEdges.add(obj); }
		 
	public ArrayList<TransitionObj> incidentEdges() { return incidentEdges; }
	
	public String generateObjUD(String type)
	{
		  int max = 100;
		  int min = 1;
		  Random randomNum = new Random();
		  int id = min + randomNum.nextInt(max);
		  //System.out.println("Random id " + id );
		  String tmp = type + Integer.toString(id);
		  return tmp;
	}
	    
	
	public boolean isSelected() { return selected; }
	
	public void toggleSelected() { selected = !selected; }
	    
	public void setSelected(boolean val) { selected = val; }
	    
	public void setUnSelected(boolean val) { selected = val; }
	    	
	/**/
	public void setID(String val) { id = val; }
	
	public String getID() { return id; }
	
	/**/
	public void setObjType(String val) { obj_type = val; }

	public String getObjType() { return obj_type; }
	
	/**/
	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_Activity(int val) { w_activity = val; }  
		    
	public int getWidth_Activity() { return w_activity; }
	
	/**/
	public void setHeight_Activity(int val) { h_activity = val; }  
		    
	public int getHeight_Activity()	{ return h_activity; }
	
	/**/
	
	public void setWidth_Decision(int val ) { w_decision = val; }
	
	public int getWidth_Decision() { return w_decision; }
	
	/**/

	public void setHeight_Decision(int val) { h_decision = val; }
	
	public int getHeight_Decision() { return h_decision; }
	
	/**/

	public void setCentreX(int val) { xcentre = val; }  
	
	public void setCentreY(int val) { ycentre = val; }  
	
	
	/**/
	public void setCentreX_Activity() { xcentre = x1 + (w_activity/2); }  
		    
	public int getCentreX_Activity() { return xcentre; }
	
	
	/**/
	public void setCentreY_Activity() { ycentre = y1 + (h_activity/2); }  
		    
	public int getCentreY_Activity() { return ycentre; }
	
	/**/
	
	public void setCentreX_Decision(int val) { xcentre = val; }  
	
	public void setCentreY_Decision(int val) { ycentre = val; }  
		
	/**/
	
	public Point getP1() { return p1; }
	    
    public Point getP2() { return p2; }
	    
    public Point getP3() { return p3; }
	    
    public Point getP4() { return p4; }
	    
    public void setP1(Point pval) {	p1 = pval; }
	    
    public void setP2(Point pval) {	p2 = pval; }
	    
    public void setP3(Point pval) {	p3 = pval; }
	    
    public void setP4(Point pval) {	p4 = pval; }
    
    public void set_obj_color(Color c) { obj_color = c; }
	    
	public Color get_obj_color() { return obj_color; }
		
	public void set_text_color(Color c)	{ text_color = c; }
		    
	public Color get_text_color() {	return text_color; }
		
	public boolean contains_Activity(Point2D p)
	{
		Rectangle r = new Rectangle (x1,y1,w_activity, h_activity);    
	    return r.contains(p);
	}
	
	public void draw(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);
		 }
		 
		 
		 if(obj_type.equals("ACTIVITY_OBJ"))	 
		 {	 
			 	// detection des retours à la ligne
			 	String[] lines = text.split("\\r?\\n");
			 	// compte les lignes
			 	for (String line : lines) 
		        {
			 		cpt_ligne++;
		        }
		    	 
			 	if(cpt_ligne == 1)
		    	{
		    		// taille de la font
			 		widthInPixels = fm.stringWidth(text);
		    		heightInPixels = fm.getHeight();
		 	    	x = xcentre - (widthInPixels /2);
		 	    	y = ycentre + (heightInPixels / 2); 
		  	    	g2.drawString(text, x, y );
		  	    	Rectangle2D rect_obj = new Rectangle2D.Double(x1, y1, w_activity, h_activity);
		  	  	 	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_activity - widthInPixels) /2;
			       			int delta_y = (h_activity - 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_activity, new_h);
			    	g2.draw(rect_obj);
		    	}
			 	
			 	// pour le marquage de la reference
    		 	g2.setFont(new Font("Arial", Font.PLAIN, 10));
    		 	g2.drawString(id, x1 + w_activity + 10 , y1  );
    	 
		 }
    	 
	 
		 if(obj_type.equals("DECISION_OBJ"))	 
    	 {
    		 	g2.drawLine( (int)p1.getX(), (int)p1.getY()  ,(int)p2.getX() , (int)p2.getY());
    		 	g2.drawLine( (int)p2.getX(), (int)p2.getY()  ,(int)p3.getX() , (int)p3.getY());
    		 	g2.drawLine( (int)p3.getX(), (int)p3.getY()  ,(int)p4.getX() , (int)p4.getY());
    		 	g2.drawLine( (int)p4.getX(), (int)p4.getY()  ,(int)p1.getX() , (int)p1.getY());
    		 	
    		 	//String fn1 = currentFont.getName(); 
    		 	//int fstyle = currentFont.getStyle();
    		 	//int fsize = currentFont.getSize();
    		 
    		 	widthInPixels = fm.stringWidth(text);
    		 	heightInPixels = fm.getHeight();
    		 	x = xcentre - (widthInPixels /2);
    		 	y = ycentre + (heightInPixels / 2); 
    		 	g2.drawString(text, x , y  );
 	    
    		 	// pour le marquage de la reference
    		 	g2.setFont(new Font("Arial", Font.PLAIN, 10));
    		 	g2.drawString(id, p2.x + (w_decision/4) + 10 , p2.y + (h_decision/4) );
    	 } 
    	 
    	 
	}
	
	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 setText(String val) { text = val; }
	 
	public String getText()	{ return text; }
	 
    public void saveTo(PrintWriter aFile) 
    {
        aFile.println(id);
        aFile.println(text);
        aFile.println(obj_type);
        
        if(obj_type.equals("ACTIVITY_OBJ"))	 
		{
        	aFile.println( Integer.toString(x1) );
        	aFile.println( Integer.toString(y1) );
        	aFile.println( Integer.toString(w_activity) );
        	aFile.println( Integer.toString(h_activity) );
		}
        else
        {
        	aFile.println( Integer.toString(w_decision) );
       	 	aFile.println( Integer.toString(h_decision) );
       	 	
       		aFile.println( Integer.toString(getP1().x) );
    		aFile.println( Integer.toString(getP1().y) );

       		aFile.println( Integer.toString(getP2().x) );
    		aFile.println( Integer.toString(getP2().y) );

       		aFile.println( Integer.toString(getP3().x) );
    		aFile.println( Integer.toString(getP3().y) );

       		aFile.println( Integer.toString(getP4().x) );
    		aFile.println( Integer.toString(getP4().y) );

    		
     	    
//         public void setP1(Point pval) {	p1 = pval; }
//         public void setP2(Point pval) {	p2 = pval; }
//         public void setP3(Point pval) {	p3 = pval; }
//         public void setP4(Point pval) {	p4 = pval; }
       	 	
       	 	
       	 	
        }
        aFile.println(xcentre);
        aFile.println(ycentre);
        //aFile.println( Integer.toString(obj_color.getRGB()) );
        //aFile.println( Integer.toString(text_color.getRGB()) );
        aFile.println(selected);
        
    }
    
    public static ChartObj loadFrom(BufferedReader aFile) throws IOException 
    {
        ChartObj   obj = new ChartObj();
        
        obj.setID( aFile.readLine() );
        obj.setText( aFile.readLine() );
        obj.setObjType( aFile.readLine() );
       
        if( obj.getObjType().equals("ACTIVITY_OBJ") )
		{
        	obj.setX1(  Integer.parseInt( aFile.readLine()) );
        	obj.setY1(  Integer.parseInt( aFile.readLine()) );
        	obj.setWidth_Activity( Integer.parseInt( aFile.readLine()) );
        	obj.setHeight_Activity( Integer.parseInt( aFile.readLine()) );
		}
        else
        {
        	obj.setWidth_Decision( Integer.parseInt( aFile.readLine()) );
        	obj.setHeight_Decision( Integer.parseInt( aFile.readLine()) );
        	
        	Point pt = new Point();
        	int x ,y ;
        	
        	x = Integer.parseInt( aFile.readLine() );
        	y = Integer.parseInt( aFile.readLine() );
        	pt.x = x;
        	pt.y = y;
        	obj.setP1(pt);

        	x = Integer.parseInt( aFile.readLine() );
        	y = Integer.parseInt( aFile.readLine() );
        	pt = new Point();
        	pt.x = x;
        	pt.y = y;
        	obj.setP2(pt);

        	x = Integer.parseInt( aFile.readLine() );
        	y = Integer.parseInt( aFile.readLine() );
        	pt = new Point();
        	pt.x = x;
        	pt.y = y;
        	obj.setP3(pt);

        	x = Integer.parseInt( aFile.readLine() );
        	y = Integer.parseInt( aFile.readLine() );
        	pt = new Point();
        	pt.x = x;
        	pt.y = y;
        	obj.setP4(pt);
        
        }
        
        obj.setCentreX( Integer.parseInt(aFile.readLine()) );
        obj.setCentreY( Integer.parseInt(aFile.readLine()) );
        
        //obj.set_obj_color(  new Color(Integer.parseInt( aFile.readLine()) ) );
        //obj.set_text_color(  new Color(Integer.parseInt( aFile.readLine()) )  );
        
        obj.setSelected(Boolean.valueOf(aFile.readLine()).booleanValue());
        
        
        return obj;
    }
	    
    
   
    
}
