
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.geom.Point2D;


import java.io.*;
import java.util.ArrayList;

public class Node 
{

	public static int    		RADIUS = 50;
    private String              label;
    private Point2D             location;
    private ArrayList<EdgeObj>  incidentEdges;
    private boolean             selected;
    private boolean				loopback_status;
    private boolean				reset_status;
    
    private LoopbackObj 		loop_obj;
 //   private ArrayList<LoopbackObj>  loopback;
    
    
    public Node() 
    { 
    	this("", new Point2D.Double(0,0)); 
    }
    
    public Node(String aLabel) 
    { 
    	this(aLabel, new Point2D.Double(0,0) {}); 
  	}

    public Node(Point2D aPoint)
    { 
    	this("", aPoint);
   	}
    
    public Node(double x, double y) 
    { 
    	this("", new Point2D.Double(x,y)); 
   	}
    
    public Node(String aLabel, Point2D aPoint) 
    {
        label = aLabel;
        location = aPoint;
        incidentEdges = new ArrayList<EdgeObj>();
        selected = false;
        loopback_status = false;
        reset_status = false;
    
        int radius = 50;
        int x1  = (int) (location.getX() - RADIUS);
        int y1  = (int) (location.getY() - RADIUS);
        int x2  = (int) (location.getX() + RADIUS);
        int y2 =  (int) (location.getY() + RADIUS);
        
        
        loop_obj = new LoopbackObj( label, (int)location.getX(), (int)location.getY(), x1, y1,  x2,  y2);
        
        //loop_obj = new LoopbackObj();
        
    }

    public String getLabel() { return label; }
    public Point2D getLocation() { return location; }
    public void setLabel(String newLabel) { label = newLabel; }
    public void setLocation(Point2D aPoint) { location = aPoint; }
    public void setLocation(double x, double y) { location = new Point2D.Double(x, y); }
    public boolean isSelected() { return selected; }
    
    public void setSelected(boolean state) { selected = state; }
    
    public void setUnSelected(boolean state) { selected = state; }
    
    
    public LoopbackObj getLoopBack()
    {
    	return loop_obj;
    }
    
    public void toggleSelected() { selected = !selected; }

    
    public void LoopToggleSelected() 
    { 
    	loopback_status = !loopback_status; 
   	}
   
    public void Set_loopback_status(boolean state)
    {
    	loopback_status = state;
    }

    public boolean Get_loopback_status()
    {
    	return loopback_status;
    }
    

    public void Set_reset_status(boolean state)
    {
    	reset_status = state;
    }

    public boolean Get_reset_status()
    {
    	return reset_status;
    }
    
    
    public ArrayList<EdgeObj> incidentEdges() { return incidentEdges; }
    public void addIncidentEdge(EdgeObj e) { incidentEdges.add(e); }
    
    
    public LoopbackObj getloopback() 
    { 
    	return loop_obj; 
    }
    
    public void setLoop(LoopbackObj obj) 
    { 
    	loop_obj = obj;
   	}
    

    // Return a list of all neighbouring Nodes
    public ArrayList<Node> neighbours() 
    {
        ArrayList<Node> result = new ArrayList<Node>();

        for (EdgeObj e: incidentEdges)
            result.add(e.otherEndFrom(this));

        return result;
    }

    // Nodes look like this: label(12,43)
    public String toString() 
    {
        return(label + "(" + location.getX() + "," + location.getY() + ")");
    }
    
    // Draw the Node using the given pen
    public void draw(Graphics g) 
    {
    	if (selected)
            g.setColor(Color.RED);
        else
            g.setColor(Color.blue);
               
        g.drawOval((int)location.getX() - RADIUS, (int)location.getY() - RADIUS, RADIUS*2, RADIUS*2);
        
        // reset sur le state
        if(	reset_status == true)
        {
        	  int rayon = RADIUS - 5;	
        	
        	  g.drawOval((int)location.getX() - rayon, (int)location.getY() - rayon, rayon*2, rayon*2);
        }
        
        Font myFont = new Font("Arial", 1, 14);
        g.setFont(myFont);
        g.drawString(label, (int)location.getX() + RADIUS, (int)location.getY() - RADIUS);
    }

    // Save node to given file.  Note that incident edges are not saved.
    public void saveTo(PrintWriter aFile) 
    {
        aFile.println(label);
        aFile.println((int)location.getX());
        aFile.println((int)location.getY());
        aFile.println(selected);
      
        aFile.println(loopback_status);
        aFile.println(loopback_status);


    }
    
    // Load a node from given file.  Note that incident edges are not connected
    public static Node loadFrom(BufferedReader aFile) throws IOException 
    {
        Node   aNode = new Node();

        aNode.setLabel(aFile.readLine());
        aNode.setLocation(Integer.parseInt(aFile.readLine()), Integer.parseInt(aFile.readLine()));
        aNode.setSelected(Boolean.valueOf(aFile.readLine()).booleanValue());
        
        aNode.Set_loopback_status(Boolean.valueOf(aFile.readLine()).booleanValue());
        aNode.Set_reset_status(Boolean.valueOf(aFile.readLine()).booleanValue());
        
        return aNode;
    }

    private Color Color(double d, double d0, double d1) 
    {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    
    
    public void updateCoordLoopBack(int xcentre, int ycentre)
    {
    	//loop_obj.x0 = val;
    	
    	loop_obj.calculationLoopbackObj(xcentre, ycentre);
    }
    
    
    
    public void mise_a_jour_CoordLoopBack(int xcentre, int ycentre)
    {
    	
    	//loop_obj.calculationLoopbackObj(xcentre, ycentre);
    	loop_obj.traitement(xcentre, ycentre);
    }
    
    
    public void debug_loop()
    {
    	
    	loop_obj.debug_loop();
    }
    
    
    public void recalculation()
    {
    	
    	loop_obj.recalculation();
    }
    
    
}
