import java.io.*;  
import java.util.ArrayList;  
import java.awt.Graphics;  
import java.awt.Color;  
import java.awt.Point;  
public class Node {
	public static int    RADIUS = 15;
	
	// These are the instance variables
	private String    		  label;
	private Point     		  location;
	private ArrayList<Edge>   incidentEdges;
	private boolean   		  selected;
	
	// Some constructors
	public Node() {
		this("", new Point(0,0));
	}

	public Node(String aLabel) {
		this(aLabel, new Point(0,0));
	}

	public Node(Point aPoint) {
		this("", aPoint);
	}

	public Node(String aLabel, Point aPoint) {
		label = aLabel;
		location = aPoint;
		incidentEdges = new ArrayList<Edge>();
	}

	// The get & set methods
	public String getLabel() { return label; }
	public Point getLocation() { return location; }

	public void setLabel(String newLabel) { label = newLabel; }
	public void setLocation(Point aPoint) { location = aPoint; }
	public void setLocation(int x, int y) { location = new Point(x, y); }

    public ArrayList<Edge> incidentEdges() { return incidentEdges; }
    public void addIncidentEdge(Edge e) { incidentEdges.add(e); }
	
	public boolean isSelected() { return selected; }
	public void setSelected(boolean state) { selected = state; }
	public void toggleSelected() { selected = !selected; }
 
	public ArrayList<Node> neighbours() {
   		ArrayList<Node> result = new ArrayList<Node>();
    	for (Edge e: incidentEdges)
        	result.add(e.otherEndFrom(this));
    	return result;
	} 
	
	// Nodes look like this:  label(12,43)
	public String toString() {
		return(label + "(" + location.x + "," + location.y + ")");
	}
	
	public void draw(Graphics aPen) {
		if (selected)
			aPen.setColor(Color.red);
		else
			aPen.setColor(Color.blue);
			
		// Draw a blue-filled circle around the center of the node
		aPen.fillOval(location.x - RADIUS, location.y - RADIUS, RADIUS * 2, RADIUS * 2);
		
		// Draw a black border around the circle
		aPen.setColor(Color.black);
		aPen.drawOval(location.x - RADIUS, location.y - RADIUS, RADIUS * 2, RADIUS * 2);
		
		// Draw a label at the top right corner of the node
		aPen.drawString(label, location.x + RADIUS, location.y - RADIUS);
	}
	 
	// Save the node to the given file.  Note that the incident edges are not saved.
	public void saveTo(PrintWriter aFile) { 
		aFile.println(label); 
		aFile.println(location.x); 
		aFile.println(location.y); 
		aFile.println(selected); 
	}

	// Load a node from the given file.  Note that the 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());
	    return(aNode); 
	}
	 
}