/*
 * CobCode.java
 *
 * Created on May 6, 2001, 2:22 AM
 */

package cse605;

/**
 *
 * @author  adev
 * @version 
 */
import java.util.*;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JFrame;
import javax.swing.*;
import javax.swing.text.*;

public class CobCode extends Object {


    private String nodeText;
    private String resistorText;
    private String wireText;
    private String batteryText;
  
    private LinkedList wireList, resistorList, batteryList, nodeList;

    private String cobText = "";

    /** Creates new CobCode */
    public CobCode() {
        wireList = new LinkedList();
        resistorList = new LinkedList();
        batteryList = new LinkedList();        
    }
    
    public void clearAll()
    {
        wireList = new LinkedList();
        resistorList = new LinkedList();
        batteryList = new LinkedList();
        nodeList = new LinkedList();
    }

    public void generateCode(LinkedList list){

        nodeText = getNodeText();
        resistorText = getResistorText();
        wireText = getWireText();
        batteryText = getBatteryText();
      
        if(list.size()>0) identifyComponents(list);

        String nodeAmps ="";
        String constraintText = "";
        String circuitText = "";
        String newWiresText="";
        String newResistorsText="";
        String newBatteriesText="";
        String newNodesText="";

        circuitText+= nodeText+"\n\n\n\n"+resistorText+"\n\n\n\n"+wireText+"\n\n\n\n"+batteryText+"\n\n\n\n";

        circuitText+= "class circuit{\n   attributes\n      node ";
        for(int i=0; i< nodeList.size(); i++)
        {
	    circuitText+="N"+((Node)nodeList.get(i)).nodeID;
            if(i!=nodeList.size()-1) circuitText +=",";
            nodeAmps+="N"+((Node)nodeList.get(i)).nodeID+"amps";
            if(i!=nodeList.size()-1) nodeAmps +=",";
            newNodesText+="      N"+((Node)nodeList.get(i)).nodeID +" = new node("+"N"+((Node)nodeList.get(i)).nodeID+"amps,V"+((Node)nodeList.get(i)).nodeID+");\n";
        }
	
	if( resistorList.size() >0 )
            circuitText+=";\n      resistor ";

        for(int i=0; i< resistorList.size(); i++)
        {
            Edge e = (Edge)resistorList.get(i);
            Node[] ns = e.getNodes();
            circuitText+=((Edge)resistorList.get(i)).getID()+"x";
            if(i!=resistorList.size()-1) circuitText +=",";

	    String[] cArray = ((Edge)resistorList.get(i)).getInstanceConstraint();
	    for(int j=0; j<cArray.length; j++)
	      constraintText+="\n       "+cArray[j];
	      
	    if( ! ((String)e.getCurrentID()).equals(e.getCurrent()))
	    {
	       constraintText+="\n       "+e.getCurrentID()+" = "+e.getCurrent() +";";
	    }
            constraintText+="\n       "+e.getID()+" = "+e.getValue() +";";

            newResistorsText+="      "+e.getID()+"x = new resistor(N"+ns[1].nodeID+",N"+ns[0].nodeID+","+e.getCurrentID()+","+e.getID()+");\n";
        }

	if( wireList.size() >0 )
	    circuitText+=";\n      wire ";
        for(int i=0; i< wireList.size(); i++)
        {
            Edge e = (Edge)wireList.get(i);
            Node[] ns = e.getNodes();
            circuitText+=((Edge)wireList.get(i)).getID()+"x";
            if(i!=wireList.size()-1) circuitText +=",";

	    String[] cArray = ((Edge)wireList.get(i)).getInstanceConstraint();
	    for(int j=0; j<cArray.length; j++)
	      constraintText+="\n       "+cArray[j];

	    if( ! ((String)e.getCurrentID()).equals(e.getCurrent()))
	    {
	       constraintText+="\n       "+e.getCurrentID()+" = "+e.getCurrent() +";";
	    }

            newWiresText+="      "+e.getID()+"x = new wire(N"+ns[1].nodeID+",N"+ns[0].nodeID+","+e.getCurrentID()+");\n";
        }

	if( batteryList.size() >0 )
	    circuitText+=";\n      battery ";
        for(int i=0; i< batteryList.size(); i++)
        {
            Edge e = (Edge)batteryList.get(i);
            Battery b = (Battery)e;
            Node[] ns = e.getNodes();
            circuitText+=e.getID()+"x";
            if(i!=batteryList.size()-1) circuitText +=",";

	    String[] cArray = ((Edge)batteryList.get(i)).getInstanceConstraint();
	    for(int j=0; j<cArray.length; j++)
	      constraintText+="\n       "+cArray[j];

	    if( ! ((String)e.getCurrentID()).equals(e.getCurrent()))
	    {
	       constraintText+="\n       "+e.getCurrentID()+" = "+e.getCurrent() +";";
	    }
            constraintText+="\n       "+e.getID()+" = "+e.getValue() +";";

            if(b.positiveNode.equals("L"))
                newBatteriesText+="      "+e.getID()+"x = new battery(N"+ns[1].nodeID+",N"+ns[0].nodeID+","+e.getID()+");\n";
            else if(b.positiveNode.equals("R"))
                newBatteriesText+="      "+e.getID()+"x = new battery(N"+ns[0].nodeID+",N"+ns[1].nodeID+","+e.getID()+");\n";

        }
	
        constraintText+="\n"+getDump();


	/* check if there are instance constraints */
	if( new StringTokenizer(constraintText).hasMoreTokens() )
            circuitText+=";\n      Real [] "+nodeAmps+";\n constraints\n"+constraintText;
	else 
	    circuitText+=";\n      Real [] "+nodeAmps+";\n";
	    
	    
        circuitText+=" constructors circuit(X){\n";
        for(int i=0; i< nodeList.size(); i++)
        {
            Node n= (Node)nodeList.get(i);
            for(int j=0; j< n.currents.length; j++)
            {
                circuitText+="      N"+n.nodeID+"amps["+(j+1)+"]="+n.currents[j]+";\n";
            }
            circuitText+="\n";
        }
        circuitText+=newNodesText+"\n";
        circuitText+=newBatteriesText+"\n";
        circuitText+=newResistorsText+"\n";
        circuitText+=newWiresText+"\n";
        circuitText+="\n   }\n}\n\n$\n";
        
        cobText = circuitText;
    }
    
  /**
   * returns the Cob code. This is followed by the call to generateCode()
   */
    public String getCode(){
        return cobText;
    }

  /**
   * Identify the electrical components on the circuit drawn and categrizes them based on 
   * their type by forming list of the respective categories.
   */    
    public LinkedList[] identifyComponents(LinkedList list){
        nodeList = list;
        if(nodeList.isEmpty()) return null;
        
        for(int i=0; i<nodeList.size(); i++){
            LinkedList elist = (LinkedList)((Node)nodeList.get(i)).edges ;
            for(int j = 0; j<elist.size(); j++){
                Edge edg = (Edge)elist.get(j);
                if(edg.getID().startsWith("R")){
                    if(!resistorList.contains(edg)) resistorList.add(edg);
                }
                else if(edg.getID().startsWith("B")){
                    if(!batteryList.contains(edg)) batteryList.add(edg);
                }
                else{
                    if(!wireList.contains(edg)) wireList.add(edg);
                }
            }//end for j
        }//end for i
        
        LinkedList[] listArray = {resistorList, batteryList, wireList};
        return listArray;
    }
  
  private String getNodeText()
  {
    LinkedList list =  Node.getConstraints();
    String cText = "";
    for(int i=0; i< list.size(); i++)
      cText += "      "+ (String)list.get(i) + "\n";
    String text = "class node{\n   attributes\n      Real V;\n      real [] Current;\n   constraints\n"+ cText+"   constructors node(Curr, V1){\n      Current = Curr;\n      V = V1;\n   }\n}";
    return text;
  }

  private String getResistorText()
  {
    LinkedList list =  Resistor.getConstraints();
    String cText = "";
    for(int i=0; i< list.size(); i++)
      cText += "      "+ (String)list.get(i) + "\n";
    String text = "class resistor{\n   attributes\n      Real I,R;\n      node N1,N2;\n   constraints\n"+ cText+"   constructors resistor(Na, Nb, I1, R1){\n      N1 = Na;\n      N2 = Nb;\n      I = I1;\n      R = R1;\n   }\n}";
    return text;
  }

  private String getWireText()
  {
    LinkedList list =  Wire.getConstraints();
    String cText = "";
    for(int i=0; i< list.size(); i++)
      cText += "      "+ (String)list.get(i) + "\n";

    String text = "class wire{\n   attributes\n      Real I;\n      node N1,N2;\n   constraints\n"+ cText+"   constructors wire(Na, Nb, I1){\n      N1 = Na;\n      N2 = Nb;\n      I = I1;\n   }\n}";
    return text;
  }

  private String getBatteryText()
  {
    LinkedList list =  Battery.getConstraints();
    String cText = "";
    for(int i=0; i< list.size(); i++)
      cText += "      "+ (String)list.get(i) + "\n";

    String text = "class battery{\n   attributes\n      Real B;\n      node N1, N2;\n   constraints\n"+cText+"   constructors battery(Na,Nb,B1){\n      N1 = Na;\n      N2 = Nb;\n      B = B1;\n   }\n}";
    return text;
  }


  private String getDump()
  {
      String list = "";
      String text = "";
      int count= 0;
      for(int i = 0; i < resistorList.size(); i++){
        Edge edg = (Edge)resistorList.get(i);
      	list += edg.getID()+",";
	list += edg.getCurrentID();
        count+=2;
	if( count > 5 )
	{
	   text += "       dump(["+ list +"]);\n" ;
	   count = 0;
	   list = "";
	}
	if((i!= resistorList.size()-1 || batteryList.size()>0 || wireList.size()>0 ) && count != 0)
	   list += ",";
      }
      for(int i = 0; i < batteryList.size(); i++) {
        Edge edg = (Edge)batteryList.get(i);
      	list += edg.getID()+",";
	list += edg.getCurrentID();	
        count+=2;
	if( count > 5 )
	{
	   text += "       dump(["+ list +"]);\n" ;
	   count = 0;
	   list = "";
	}
	if( (i!= batteryList.size()-1 || wireList.size()>0) && count != 0)
	   list += ",";
      }
      for(int i = 0; i < wireList.size(); i++) {
        Edge edg = (Edge)wireList.get(i);
	list += edg.getCurrentID();	
        count+=1;
	if( count > 5 )
	{
	   text += "       dump(["+ list +"]);\n" ;
	   count = 0;
	   list = "";
	}
	if(i!= wireList.size()-1  && count != 0)
	   list += ",";
      }

      if(!list.equals("")) text += "       dump(["+ list +"]);\n" ;

      return text ;	
  }
  
  


}

class TestPane extends javax.swing.JTextPane
{
    String filename = "startpic3g_b.gif";
    java.awt.Image pic = java.awt.Toolkit.getDefaultToolkit().getImage(filename);

    public void paintComponent(java.awt.Graphics g) {
        super.paintComponent(g);
        g.drawImage(pic, 0, 0, this);
    }
}



