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 = 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("-")) currents[edges.indexOf(edg)] = "(0"+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;
    }
*/
}// Node

