/*
 * ResultPane.java
 *
 * Created on June 28, 2001, 10:25 AM
 */

package cse605;

/**
 *
 * @author  adev
 * @version 
 */
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.geom.*;
import java.awt.font.*;

public class ResultPane extends javax.swing.JSplitPane {

    private JScrollPane rightPane, leftPane;
    public LinkedList adjMatrix;
    private JComponent circuitPane;
    private CircuitCanvas ccanvas;
    public AnswerPanel answerPane;
    private CobUI parent;
    private JPanel resultPane;
    private JRadioButton rb1, rb2, rb3, rb4;

    /** Creates new ResultPane */
    public ResultPane(CobUI par) {
        super(JSplitPane.VERTICAL_SPLIT);
	
	parent  = par;
        adjMatrix = parent.canvas.adjMatrix ;
        setSize( parent.getSize() );

        //create panes
	ccanvas = new CircuitCanvas(this) ;
	circuitPane = new JPanel(new BorderLayout());
        circuitPane.add(new JLabel("Circuit :  Click on any component to see it's Input and Result Constraints"), BorderLayout.NORTH);
	JScrollPane jsp = new JScrollPane( ccanvas, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
	jsp.getViewport().setViewPosition(new Point((int)ccanvas.minX, (int)ccanvas.minY));
        circuitPane.add(jsp, BorderLayout.CENTER);
	circuitPane.add( getFilterPane(), BorderLayout.SOUTH );
        answerPane = new AnswerPanel(this, new Dimension( getWidth(), (int)(getHeight()*0.35) ) );

	setTopComponent(circuitPane);
        setBottomComponent(answerPane);
	setDividerLocation(0.65);
	resultPane = new JPanel();
	showCompleteResult();
    }


   public void paintComponent(Graphics g) {
      Rectangle leftRect = new Rectangle(getWidth(), (int)(parent.getHeight()*0.65) ) ;
      Rectangle rightRect = new Rectangle(getWidth(), (int)(parent.getHeight()*0.35)) ;
      
      circuitPane.scrollRectToVisible( leftRect );
      answerPane.scrollRectToVisible( rightRect );

      circuitPane.setPreferredSize(parent.canvas.area.getSize());
      circuitPane.setMinimumSize(parent.canvas.area.getSize());
      answerPane.setPreferredSize(rightRect.getSize());
      
      setDividerLocation(0.65);
      
      answerPane.revalidate();
      circuitPane.revalidate();
      resultPane.revalidate();
      actualPaintComponent(g);
   } // end paint

   public void actualPaintComponent(Graphics g) {
       super.paintComponent(g);       
   }
   
   public void showCompleteResult()
   {
	resultPane = new JPanel(new BorderLayout());
	resultPane.setPreferredSize( new Dimension(getWidth(), (int)(getHeight()*0.35)) ) ;
	resultPane.setMaximumSize( new Dimension(getWidth(), (int)(getHeight()*0.35)) ) ;
	
	JTextPane rtTPane = CodeTracer.getTextPane(CobLib.getOutput(), Color.black);
	resultPane.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
	resultPane.setBorder(BorderFactory.createTitledBorder("Answer Constraints for the Circuit"));
	resultPane.add(new JScrollPane(rtTPane), BorderLayout.CENTER );

	remove(answerPane);
        setBottomComponent(resultPane);
	setDividerLocation(0.65);

	invalidate();
	validate();	
   }
   
   public void showPartialResult()
   {
	remove(resultPane);
        setBottomComponent(answerPane);
	setDividerLocation(0.65);
	invalidate();
	validate();	
   
   }
   
   private JPanel getFilterPane()
   {
   	JPanel pane = new JPanel();
	pane.setLayout(new FlowLayout(FlowLayout.LEFT));
	rb1 = new JRadioButton("Nodes");
	rb2 = new JRadioButton("Currents");
	rb3 = new JRadioButton("Components");
	rb4 = new JRadioButton("All");

	rb1.setSelected(true);
	rb2.setSelected(true);
	rb3.setSelected(true);
	rb4.setSelected(true);
	
	rb1.addActionListener(new ActionListener() {
	  public void actionPerformed(ActionEvent e) {
	     buttonClickAction();
	  }
        });
	rb2.addActionListener(new ActionListener() {
	  public void actionPerformed(ActionEvent e) {
	     buttonClickAction();
	  }
        });
	
	rb3.addActionListener(new ActionListener() {
	  public void actionPerformed(ActionEvent e) {
	     buttonClickAction();
	  }
        });

	rb4.addActionListener(new ActionListener() {
	  public void actionPerformed(ActionEvent e) {
	     if(rb4.isSelected())
	     {
	     	rb1.setSelected(true);
	     	rb2.setSelected(true);
	     	rb3.setSelected(true);
	     }
	     else
	     {
	     	rb1.setSelected(false);
	     	rb2.setSelected(false);
	     	rb3.setSelected(false);
	     }
	     buttonClickAction();
	  }
        });

	
	pane.add( new JLabel("Filter  : "));
	pane.add(rb4);
	pane.add(new JLabel("    "));
	pane.add(rb1);
	pane.add(rb2);
	pane.add(rb3);
	
	return pane;
   }
   
   private void buttonClickAction()
   {
   	if(rb1.isSelected()) ccanvas.showNodes(false);
	else  ccanvas.showNodes(true);
	
	if(rb2.isSelected()) ccanvas.showCurrents(false);
	else ccanvas.showCurrents(true) ;
	
	if(rb3.isSelected()) ccanvas.showComponents(false);	
	else ccanvas.showComponents(true);

	if(rb1.isSelected() && rb2.isSelected() && rb3.isSelected() )
	    rb4.setSelected(true) ;
	if(!rb1.isSelected() || !rb2.isSelected() || !rb3.isSelected() )
	    rb4.setSelected(false) ;

        ccanvas.cleanup();

   }
   
   
}

/*
 *
 * Class CircuitCanvas
 *
 */

class CircuitCanvas extends JPanel implements MouseListener, ActionListener
{
    private LinkedList adjMatrix;
    private ResultPane parent;
    private int count = 0;
    private boolean nodeVisible = false;
    private boolean currentVisible = false;
    private boolean componentVisible = false;
    private boolean selected = false;
    public float minX;
    public float minY;

    /** Creates new ResultPane */
    public CircuitCanvas(ResultPane par) {
        parent = par;
        adjMatrix = parent.adjMatrix ;
        addMouseListener(this);

	setSize(parent.getSize());
	setPreferredSize( new Dimension(parent.getWidth(), (int)(parent.getHeight()))) ;
	setMinimumSize( new Dimension(parent.getWidth(), (int)(parent.getHeight()))) ;
	setMaximumSize( new Dimension(parent.getWidth(), (int)(parent.getHeight()))) ;


   	for(int i=0; i< adjMatrix.size(); i++){
	    Node n = (Node)adjMatrix.get(i) ;
	    if(i==0){
	    	minX = n.x ;
		minY = n.y ;
	    }
	    else{
	    	if(minX > n.x) minX = n.x;
		if(minY > n.y) minY = n.y;
	    }

	    for(int j=0; j< n.edges.size() ; j++){
	        ((Edge)n.edges.get(j)).clearPick();
	    }
	}
	
	if(minX>20) minX -= 20;
	else minX = 0;
	if(minY>20) minY -= 20;
	else minY = 0;

    }

    public void mouseClicked(MouseEvent evt) {

    }
   
   /**
    * Needed for MouseListener.
    * @param evt the MouseEvent
    */
   public void mousePressed(MouseEvent evt) {
   	for(int i=0; i< adjMatrix.size(); i++){
	    Node n = (Node)adjMatrix.get(i) ;
	    for(int j=0; j< n.edges.size() ; j++){
	        ((Edge)n.edges.get(j)).clearPick();
	    }
	}
	
	selected = false;
   	for(int i=0; i< adjMatrix.size(); i++){
	    Node n = (Node)adjMatrix.get(i) ;
	    for(int j=0; j< n.edges.size() ; j++){
	    	if( ((ElecComponent)n.edges.get(j)).center.contains(evt.getX(), evt.getY()) )
	    	{
		    selected = true;
   	            Graphics g = getGraphics();
		    /* highlight the component */
	    	    ((Edge)n.edges.get(j)).picked(g);
		    /* Display the corressponding results */
		    parent.showPartialResult();
		    parent.answerPane.setEdge(  (Edge)n.edges.get(j) );
	    	}
	    }
	}
	
	if(!selected)
	{
	   parent.answerPane.clear();
	   parent.showCompleteResult();
	}	
	
   	repaint();
   }
   
   /**
    * Needed for MouseListener.
    * @param evt the MouseEvent
    */
   public void mouseReleased(MouseEvent evt) {
   }
   
   /**
    * Needed for MouseListener.
    * @param evt the MouseEvent
    */
   public void mouseEntered(MouseEvent evt) {
      // nothing needed here
   }
   
   /**
    * Needed for MouseListener.
    * @param evt the MouseEvent
    */
   public void mouseExited(MouseEvent evt) {
      // nothing needed here
   }

    public void mouseDragged(java.awt.event.MouseEvent p1) {
    }    
    
    public void mouseMoved(java.awt.event.MouseEvent p1) {
    }

    public void actionPerformed(ActionEvent e) {
    }

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      ListIterator enum = adjMatrix.listIterator();
      Node node;
      while (enum.hasNext()) {
	 node = (Node) enum.next();
	 g2.setColor(node.getColor());
	 g2.fill(node);
	 if(nodeVisible && !selected)
	 {
             int fontStyle = Font.ITALIC ;
             FontRenderContext frc = g2.getFontRenderContext();
             Font f = new Font("Times", fontStyle, 10);
             String s = new String("n"+ node.nodeID+", V"+node.nodeID);
             TextLayout tl = new TextLayout(s, f, frc);
             g2.setColor(new Color(179,17,179) );
             tl.draw(g2, node.x - 10, node.y - 10);
	 }
	 
         for(int i = 0; i< node.edges.size(); i++)
	 {
            ((Edge)(node.edges.get(i))).basicDraw(g);
	    ((Edge)(node.edges.get(i))).pickdraw(g);
	    
	    if(currentVisible && !selected )
	    	((Edge)node.edges.get(i)).showVals(g);

	    if(componentVisible && !selected )
	    	((Edge)node.edges.get(i)).showID(g);
	 }
      }
   } // end paint
   
   public void cleanup()
   {
   	for(int i=0; i< adjMatrix.size(); i++){
	    Node n = (Node)adjMatrix.get(i) ;
	    for(int j=0; j< n.edges.size() ; j++){
	        ((Edge)n.edges.get(j)).clearPick();
	    }
	}
	parent.answerPane.clear();
	parent.showCompleteResult();
	repaint();
   }
   
   public void showNodes(boolean b)
   {
   	nodeVisible = b;
   }
   
   public void showCurrents(boolean b)
   {
	currentVisible = b;
   }
   
   public void showComponents(boolean b)
   {
	componentVisible = b;
   }

}

/*
 *
 * AnswerCanvas
 *
 */
class AnswerPanel extends javax.swing.JSplitPane
{
    private InputPanel inputPane;
    private OutputPanel outputPane;
    public Edge edge;
    private ResultPane parent;
    public void setEdge(Edge edg)
    {
    	edge = edg;
	inputPane.showInput();
	outputPane.showOutput();
    }
    
    public void clear()
    {
    	inputPane.clear();
	outputPane.clear();
    }
    
    public AnswerPanel(ResultPane par, Dimension dim){
        super(JSplitPane.HORIZONTAL_SPLIT);
	parent = par;
	setSize( dim );
	setPreferredSize( dim );
	setMinimumSize( dim );
	setMaximumSize( dim );
	inputPane = new InputPanel(this);
	outputPane = new OutputPanel(this);
        setTopComponent(inputPane) ;
        setBottomComponent(outputPane);
        setDividerLocation((int)(dim.getWidth()*0.5));
        setBackground(Color.white);
    }
}

class InputPanel extends JPanel
{
    private AnswerPanel parent;
    private JTextPane iPane;
    private JScrollPane sPane;

    public InputPanel(AnswerPanel parent)
    {
    	this.parent = parent;
	setLayout(new BorderLayout());
	add( new JLabel("Input Constraints"), BorderLayout.NORTH);
	iPane = new JTextPane();
	iPane.setEditable(false);
	sPane = new JScrollPane( iPane );
	add( sPane, BorderLayout.CENTER );
    }

    public void showInput()
    {
       String text = "";
       Edge edge = parent.edge;
       Font font = CobLib.font; 
       iPane = new JTextPane();
       iPane.setEditable(false);
       remove(sPane);
       sPane = new JScrollPane( iPane );
       add( sPane, BorderLayout.CENTER );
       invalidate();
       validate();
       repaint();
       text += "Value : "+edge.getValue();
       text +="\nCurrent : "+edge.getCurrent();
       text +="\nConstraints :\n";
       String[] clist = edge.getInstanceConstraint();
       String lcText = "";
       for(int i=0; i<clist.length; i++)
       	  lcText+= clist[i]+"\n";
       if(clist.length==0)
	  lcText+= "NIL\n";
	
       text += lcText;		  
       Document doc = iPane.getDocument();
       try {
          int len = doc.getLength();
          doc.remove(0,len);
       }
       catch (BadLocationException ble) {
       }
       String showText = "The Inputs for the "+parent.edge.getType()+" ("+parent.edge.getID()+") are :-\n"+text;

       MutableAttributeSet attr = new SimpleAttributeSet();
       StyleConstants.setFontFamily (attr, font.getFamily());
       StyleConstants.setFontSize (attr, font.getSize());
       StyleConstants.setBold (attr, font.isBold());
       StyleConstants.setItalic (attr, font.isItalic());
       iPane.setCharacterAttributes(attr, false); 

       try{
           doc.insertString(doc.getLength(), showText, attr );
       }
       catch (BadLocationException ble) {
//           System.err.println("Couldn't insert initial text.");
       }       
    }
    
    public void clear()
    {
	iPane.setText("");
    }
}

class OutputPanel extends JPanel
{
    private AnswerPanel parent;
    private JTextPane oPane;
    private JScrollPane sPane;
    
    OutputPanel(AnswerPanel parent)
    {
    	this.parent = parent;
	setLayout(new BorderLayout());
	add( new JLabel("Answer Constraints"), BorderLayout.NORTH);
	oPane = new JTextPane();
	oPane.setEditable(false);
	sPane = new JScrollPane( oPane );
	add( sPane, BorderLayout.CENTER );
    }
    
    public void showOutput()
    {
       Edge edge = parent.edge;
       Font font = CobLib.font; 
       
       oPane = new JTextPane();
       oPane.setEditable(false);
       remove(sPane);
       sPane = new JScrollPane( oPane );
       add( sPane, BorderLayout.CENTER );
       invalidate();
       validate();
       repaint();

       Document doc = oPane.getDocument();
       try {
          int len = doc.getLength();
          doc.remove(0,len);
       }
       catch (BadLocationException ble) {
//          System.err.println("Couldn't insert initial text.");
       }
       String showText = "The Result for the "+parent.edge.getType()+" ("+parent.edge.getID()+") are:-\n\n";

       String newText = CobLib.getResult(new String[]{edge.getCurrentID(),edge.getID() }) ;

       String finaltext = showText + parser(newText);

       MutableAttributeSet attr = new SimpleAttributeSet();
       StyleConstants.setFontFamily (attr, font.getFamily());
       StyleConstants.setFontSize (attr, font.getSize());
       StyleConstants.setBold (attr, font.isBold());
       StyleConstants.setItalic (attr, font.isItalic());
       oPane.setCharacterAttributes(attr, false); 

       try{
           doc.insertString(doc.getLength(), finaltext, attr );
       }
       catch (BadLocationException ble) {
//           System.err.println("Couldn't insert initial text.");
       }       
    }
        
    public void clear()
    {
	oPane.setText("");
    }
    

   public String parser(String input)
   {
      String st1,Id="",num1 ="",num2 ="",finalstring="";
      Double n1,n2,n3;
      double ni1, ni2, ni3;
      StringTokenizer str = new StringTokenizer(input,"\n");
      
      while ( str.hasMoreTokens())
      {   
	 st1 = str.nextToken();
	 StringTokenizer str2 = new StringTokenizer(st1,"[");
	 if (str2.countTokens() > 1)
	 {  Id="";
	    Id = str2.nextToken();
	    
	    if (str2.hasMoreTokens())
	       num1 = str2.nextToken(",");
	    if (num1.length() > 1)
	       num1 = num1.substring(1);
	    if (str2.hasMoreTokens())
	       num2 = str2.nextToken("]");    
	    if (num2.length() > 1)
	       num2 = num2.substring(1);
	    
	    try
	    {
	       n1 = new Double(num1);
	       n2 = new Double(num2);
	       ni1 = n1.doubleValue();
	       //ni1 = (Math.round(ni1 * 10000))/10000;
	       ni2 = n2.doubleValue();
	       //ni2 = Math.round(ni2 * 10000)/10000;
	       ni3 = Math.sqrt(ni1*ni1 + ni2*ni2);
	       n3 = new Double(ni3);
	       Id +=  n3.toString()+"\n";
	       
	    }
	    catch (NumberFormatException e) 
	    { 
	       Id+= num1+","+num2+"\n";
	    }
	 }
	 else 
	 {
	    Id = "";
            Id = st1+"\n";
	 }
	 

	 finalstring+=Id;
      }
      
      return finalstring;
   }

}

