/*
 * 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 complexText;
    private String resistorText;
    private String wireText;
    private String batteryText;
    private String inductorText;
    private String capacitorText;
    private String acvText;
  
    private LinkedList wireList, resistorList, batteryList, nodeList,inductorList,capacitorList,acvList;

    private String cobText = "";

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

    public void generateCode(LinkedList list){

        nodeText = getNodeText();
	complexText = getComplexText();
        resistorText = getResistorText();
        wireText = getWireText();
        batteryText = getBatteryText();
        inductorText = getInductorText();
        capacitorText = getCapacitorText();
        acvText = getACVText();

        if(list.size()>0) identifyComponents(list);

        String nodeAmps ="";
        String constraintText = "";
        String constructorText ="";
        String circuitText = "";
        String newWiresText="";
        String newResistorsText="";
        String newInductorsText="";
        String newCapacitorsText="";
        String newACVsText="";
        String newBatteriesText="";
        String newNodesText="";
        String newVoltageText="";
        String newNegCurrentText="";

        circuitText+= nodeText+"\n\n\n\n"+complexText+"\n\n\n\n"+resistorText+"\n\n\n\n"+batteryText+"\n\n\n\n"+acvText+"\n\n\n\n"+wireText+"\n\n\n\n"+inductorText+"\n\n\n\n"+capacitorText+"\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";	   
		
	    newVoltageText+= "\n       V"+((Node)nodeList.get(i)).nodeID+" = new complex(_,_);";     
	}
	

	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()+" = new complex("+e.getCurrent() +",0);";
	    }
	    else {
	        constraintText+="\n       "+e.getCurrentID()+" = new complex(_,_);";
            
	    } // end of else
	    if (!e.getID().equals(e.getValue()))
            constraintText+="\n       "+e.getID()+" = new complex("+e.getValue() +",_);";
		else {
            constraintText+="\n       "+e.getID()+" = new complex(_,_);";		   
		} // end of else

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



	if( inductorList.size() >0 )
            circuitText+=";\n       inductor ";

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

	    String[] cArray = ((Edge)inductorList.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()+" = new complex(0,"+e.getCurrent() +");";
	    }
              else {
	        constraintText+="\n       "+e.getCurrentID()+" = new complex(_,_);";
            
	    } // end of else
             if (!e.getID().equals(e.getValue()))
		constraintText+="\n       "+e.getID()+" = "+e.getValue() +";";

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




        if( capacitorList.size() >0 )
            circuitText+=";\n       capacitor ";

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

	    String[] cArray = ((Edge)capacitorList.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()+" = new complex(0,"+e.getCurrent() +");";
	    }
             else {
	        constraintText+="\n       "+e.getCurrentID()+" = new complex(_,_);";
            
	    } // end of else
             if (!e.getID().equals(e.getValue()))
		constraintText+="\n       "+e.getID()+" = "+e.getValue() +";";

            newCapacitorsText+="       "+e.getID()+"x = new capacitor(N"+ns[1].nodeID+",N"+ns[0].nodeID+","+e.getCurrentID()+","+e.getID()+", W1);\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()+" = new complex("+e.getCurrent() +",0);";
	    }  
            else {
	        constraintText+="\n       "+e.getCurrentID()+" = new complex(_,_);";
            
	    } // end of else

            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()+" = new complex("+e.getCurrent() +",0);";
	    }
             else {
	        constraintText+="\n       "+e.getCurrentID()+" = new complex(_,_);";
            
	    } // end of else
            constraintText+="\n       "+e.getID()+" = new complex("+e.getValue() +",0);";
                 
            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";

	    if (acvList.size()==0)
             constraintText+= "\n       W1 = 0;";
        }


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

	    String[] cArray = ((Edge)acvList.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()+" = new complex("+e.getCurrent() +",0);";
	    }
	    else {
	        constraintText+="\n       "+e.getCurrentID()+" = new complex(_,_);";
            
	    } // end of else
            constraintText+="\n       "+e.getID()+" = new complex("+e.getValue()+",0);";
	    
          newACVsText+="       "+e.getID()+"x = new acv(N"+ns[1].nodeID+",N"+ns[0].nodeID+","+e.getID()+", W1);\n";
	  if (Omega!=null) {
	   constraintText+= "\n       W1 = "+ Omega+";";  
	  } // end of if (Omega!=null)
	  
          

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


	/* check if there are instance constraints */
	if( new StringTokenizer(constraintText).hasMoreTokens() )
            circuitText+=";\n       complex [] "+nodeAmps+";\n   constraints\n"+constraintText;
	else 
	    circuitText+=";\n       complex [] "+nodeAmps;
	    
	    
        circuitText+="   constructors circuit(X){\n";

	String temp_I;
        for(int i=0; i< nodeList.size(); i++)
        {
            Node n= (Node)nodeList.get(i);
            for(int j=0; j< n.currents.length; j++)
            {
	       if (n.currents[j].startsWith("N")) 
	       {
		  temp_I = n.currents[j].substring(1);
		  circuitText += "\n       "+n.currents[j]+" = new complex(_,_);";
		  circuitText += "\n        c_neg("+temp_I+".Re, "+temp_I+".Im, "+n.currents[j]+".Re, "+n.currents[j]+".Im);" ;
	       }
	       circuitText+="\n       N"+n.nodeID+"amps["+(j+1)+"]="+n.currents[j]+";\n";
            }
        }
        circuitText+=newNodesText+"\n";
        circuitText+=newBatteriesText+"\n";
        circuitText+=newResistorsText+"\n";
        circuitText+=newCapacitorsText+"\n";
        circuitText+=newInductorsText+"\n";
        circuitText+=newACVsText+"\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(edg.getID().startsWith("C")){
                    if(!capacitorList.contains(edg))capacitorList.add(edg);
                
                }
                 else if(edg.getID().startsWith("L")){
                    if(!inductorList.contains(edg))inductorList.add(edg);
                
                }
                else if(edg.getID().startsWith("A")){
                    if(!acvList.contains(edg))acvList.add(edg);
                
                }
                else{
                    if(!wireList.contains(edg)) wireList.add(edg);
                }
            }//end for j
        }//end for i
        
        LinkedList[] listArray = {resistorList, capacitorList,inductorList,batteryList,acvList,wireList,};
       
	
        return listArray;
    }
  
   private String getComplexText()
   {

      String text ="class complex{\n   attributes\n      Real Re,Im;\n   constraints\n\n   predicates\n      c_add(R1r, R1i, R2r, R2i, R3r, R3i):-\n        R3r = R1r + R2r,\n        R3i = R1i + R2i.\n      c_mult(R1r, R1i, R2r, R2i, R3r, R3i):-\n        R3r = (R1r*R2r) - (R1i*R2i),\n        R3i = (R1r * R2i) + (R2r * R1i).\n      c_sub(R1r, R1i, R2r, R2i, R3r, R3i):-\n        R3r = R1r - R2r,\n        R3i = R1i - R2i. \n      c_neg(R1r, R1i, R2r, R2i):-\n        R2r = 0-R1r,\n        R2i = 0-R1i.\n   constructors complex(Re1,Im1){\n      Re=Re1; \n      Im = Im1;\n   }\n}";
   
      return text;
   }


  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      complex V;\n      complex [] 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      complex I,R,T;\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      R.Im =0;\n}\n}";
    return text;
  }

  private String getCapacitorText()
  {
    LinkedList list =  Capacitor.getConstraints();
    String cText = "";
    for(int i=0; i< list.size(); i++)
      cText += "      "+ (String)list.get(i) + "\n";
    String text = "class capacitor{\n   attributes\n      complex I,T;\n      node N1,N2;\n      Real W,C;\n   constraints\n"+cText+"   constructors capacitor(Na, Nb, I1, C1, W1){\n      N1 = Na;\n      N2 = Nb;\n      I = I1;\n      C = C1;\n      W = W1;\n  }\n}";
    return text;
  }

 private String getInductorText()
  {
    LinkedList list =  Inductor.getConstraints();
    String cText = "";
    for(int i=0; i< list.size(); i++)
      cText += "      "+ (String)list.get(i) + "\n";
    String text = "class inductor{\n   attributes\n      complex I,T;\n      node N1,N2;\n      Real W,L; \n   constraints\n"+cText+"   constructors inductor(Na, Nb, I1, L1, W1){\n      N1 = Na;\n      N2 = Nb;\n      I = I1;\n      L = L1;\n      W = W1;\n }\n}";
    return text;
  }

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

    String text = "class acv{\n   attributes\n      complex B,X,T;\n      node N1, N2;\n      Real W;\n   constraints\n"+cText+"   constructors acv(Na,Nb,B1,W1){\n      N1 = Na;\n      N2 = Nb;\n      B = B1;\n      X.Re = 0;\n      X.Im = 0;\n      W = W1;\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      complex 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      complex B,X,T;\n      node N1, N2;\n      Real W;\n   constraints\n"+cText+"   constructors battery(Na,Nb,B1){\n      N1 = Na;\n      N2 = Nb;\n      B = B1;\n      X.Re = 0;\n      X.Im = 0;\n      W = 0;\n  }\n}";
    return text;
  }


  private String getDump()
  {
      String list = "";
      if (acvList.size()>0) {
	 list = "W1 ,";
      } // end of if (acvList.size()>0)
      
 
      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 > 2 )
	{
	   text += "       dump(["+ list +"]);\n" ;
	   count = 0;
	   list = "";
	}
	if((i!= resistorList.size()-1 || batteryList.size()>0 ||
	    wireList.size()>0 || capacitorList.size()>0 ||
	    inductorList.size()>0 || acvList.size()>0 ) && count != 0)
	   list += ",";
      }
       
       for(int i = 0; i < capacitorList.size(); i++){
        Edge edg = (Edge)capacitorList.get(i);
      	list += edg.getID()+",";
	list += edg.getCurrentID();
        count+=2;
	if( count > 2 )
	{
	   text += "       dump(["+ list +"]);\n" ;
	   count = 0; 
	   list = "";
	}
	if((i!= capacitorList.size()-1 || batteryList.size()>0 ||
	    wireList.size()>0 || inductorList.size()>0 || acvList.size()>0 ) && count != 0)
	   list += ",";
      }
          

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

       for(int i = 0; i < acvList.size(); i++){
        Edge edg = (Edge)acvList.get(i);
      	list += edg.getID()+",";
	list += edg.getCurrentID();
        count+=2;
	if( count > 2 )
	{
	   text += "       dump(["+ list +"]);\n" ;
	   count = 0; 
	   list = "";
	}
	if((i!= acvList.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 > 2 )
	{
	   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 > 2 )
	{
	   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);
    }
}



