package cse605;

import java.awt.*;
import java.util.*;
import java.awt.geom.*;
import java.io.*;


public class Node extends java.awt.geom.Ellipse2D.Float implements Cloneable, Serializable
{

    public static int count;
    public int nodeID;
    public int parentID1, parentID2;
    public int childID;
    //   public float xpos, ypos;
    private Color dc = Color.black;
    public boolean isSelected;
    public boolean rectSelected;

    public LinkedList edges; // list of all the edges linked to this node
    
    public String[] currents;// list of currents coming into node from all edges linked to it
    
    public static LinkedList constraints;//constraints being transient dont get saved in file
    
    private LinkedList instanceConstraints ;
    
    static public int h = 6;
    static public int w = 6;
    private int ho,ko;
    private int dx, dy;
    public boolean isDraggable = false; 
    
   
    public Node (float x, float y)
    {
	super(x,y,w,h);
	if(count==0) initConstraint();
	this.x = x;
	this.y = y;
	edges = new LinkedList();
	count++;
	nodeID = count;
	isSelected = false;
	unsetToMove();
	instanceConstraints = new LinkedList();
    }

    private Node (LinkedList edg, Node n) 
    {
	super(n.x,n.y,n.w,n.h);
	this.x = n.x;
	this.y = n.y;
	edges = edg;
	nodeID = n.nodeID;
	isSelected = n.isSelected;
	childID = n.childID;
	parentID1 = n.parentID1;
	parentID2 = n.parentID2;
	unsetToMove();
	instanceConstraints = n.instanceConstraints;
    }
    
    public Node (Node n) 
    {
	super(n.x,n.y,n.w,n.h);
	this.x = n.x;
	this.y = n.y;
	count++;
	nodeID = count;
	parentID1 = n.parentID1;
	parentID2 = n.parentID2;
	childID = n.childID;
	edges = new LinkedList();
	unsetToMove();
	instanceConstraints = n.instanceConstraints;
    }
    
    private void initConstraint()
    {
        constraints = new LinkedList();
        constraints.add("sum I in Current: I.Re = 0;\n       sum I in Current: I.Im = 0;");
    }
    
    public static LinkedList getConstraints()
    {
        return constraints;
    }
    
    public static void addConstraints(String cnstr)
    {
        constraints.add(cnstr);
    }
    
    public String[] getInstanceConstraint() 
    {
        String[] list = new String[instanceConstraints.size()];
        for(int i=0 ; i < list.length; i++)
            list[i] = (String)instanceConstraints.get(i);
        return list ;
    }
    
    public void addInstanceConstraint(String constraint) 
    {
        instanceConstraints.add(constraint);
    }

    public void changePosition(int h, int k)
    {
	this.x += h-ho;
	this.y += k-ko;
	ho = h;
	ko = k;
    }
    
    public Color getColor()
    { 
	return dc; 
    }
    
    public void setColor(Color color)
    {
        dc = color;
    }
    public void select()
    {
	isSelected = true;
	dc = Color.red;
    }
    
    public void disSelect()
    {
	isSelected = false;
	dc = Color.black;
    }
    
    public Node getClone()
    {
        LinkedList list = new LinkedList();
        for(int i=0; i<edges.size(); i++){
	    //            list.add( ((ElecComponent)edges.get(i)).getClone() );
            list.add( edges.get(i) );
        }
        Node cnode = new Node(list, this);
	/*
	  for(int i=0; i<cnode.edges.size(); i++){
	  Edge edge = (Edge)cnode.edges.get(i);
	  Node[] parents = edge.getNodes();
	  if( parents[0].nodeID == cnode.nodeID) edge.exchangeNode(cnode,Edge.LEFT_NODE);
	  else if( parents[1].nodeID == cnode.nodeID) edge.exchangeNode(cnode,Edge.RIGHT_NODE);
	  }
	*/
        return cnode;
    }
    
    public boolean contains(Point2D p)
    {
	double dist = p.distance(x,y);
	if( dist < 20.0 ){
	    return true;
	}
	else return false;
    }

    private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException 
    {
        stream.defaultReadObject();
        x = stream.readFloat();
        y = stream.readFloat();
        width = stream.readFloat();
        height = stream.readFloat();
        w = (int)width;
        h = (int)height;
	constraints = (LinkedList)stream.readObject();
    }
    
    private void writeObject(java.io.ObjectOutputStream stream) throws IOException 
    {
        stream.defaultWriteObject();
        stream.writeFloat(x);
        stream.writeFloat(y);
        stream.writeFloat(width);
        stream.writeFloat(height);
	stream.writeObject(constraints);
    }                           
    
    public void setToMove(int h, int k)
    {
        ho = h;
        ko = k;
	
    }

    public void unsetToMove()
    {
        ho = (int)this.x;
        ko = (int)this.y;
    }
    
    public void makeCurrentList()
    {
        currents = new String[edges.size()];
    }
    
    public void assignCurrent(String ival, Edge edg)
    {
        
       currents[edges.indexOf(edg)] = ival.toUpperCase();
        if(ival.startsWith("-")) 
	{
	   ival = ival.substring(1);
	   currents[edges.indexOf(edg)] = "N"+ival.toUpperCase();

	}

    }
    
    public void displayCurrents()
    {
	//        System.out.println("Node ID =  "+nodeID);
	//        for(int i=0; i< edges.size(); i++) System.out.println("edge: "+ ((Edge)edges.get(i)).getID()+" has current "+currents[i]);
    }
    
    public int getCount()
    {
        return count;
    }

    public static void setCount(int val)
    {
        count = val;
    }
    
    public int getIDVal()
    {
        return nodeID;
    }
    
    /*
      public void setTemporaryPosition(int delx, int dely)
      {
      dx = delx;
      dy = dely;
      }
    */

}

