package cse605;
import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.io.*;
import java.lang.ref.*;
import java.util.*;

abstract class Bar extends Component implements Edge, Cloneable, Serializable
{

    String ID;
    boolean currentCenterCheck = false;
	
	String elasticity, sy, length, width, height, f_bk, f_bn;
    String f_t, sigma, bar_i, bar_f, angle;        

    public Node l_node, r_node;
    protected LinkedList instanceConstraints = new LinkedList();
    protected boolean prevPainted = false;
    protected boolean isPicked;
    public transient Shape center;
    
    public String getID(){
        return ID;
    }
    
    public void exchangeNode(Node n, int whichNode, String flag) {

        if(whichNode == RIGHT_NODE){
            for(int i=0; i<r_node.edges.size(); i++){
                if( ((Edge)r_node.edges.get(i)).getID().equals(ID)){
                    if(flag.equals("add")) n.edges.add(this);
                    r_node = n;
                    return;
                }
                //ERROR element should have been found here.
            }//end for

        }
        else if(whichNode == LEFT_NODE){ 
            for(int i=0; i<l_node.edges.size(); i++){
                if(((String)((Edge)l_node.edges.get(i)).getID()).equals(ID)){
                    if(flag.equals("add")) n.edges.add(this);
                    l_node = n;
                    return;
                }
                //ERROR element should have been found here.
            }//end for

        }

        if(whichNode == RIGHT_NODE){ 
             if(flag.equals("add")) n.edges.add(this);
             r_node = n;
        }
        else if(whichNode == LEFT_NODE){ 
             if(flag.equals("add")) n.edges.add(this);
             l_node = n;
        }        
        
    }
    
    public Node[] getNodes() {
        Node[] nodes = {l_node, r_node };
        return nodes;
    }
    
    public Bar getClone(){
        try{
            return (Bar)clone();
        }
        catch(CloneNotSupportedException cnse){//error message
        }
        return null;
    }
    
 
    public void adjustNodes()
    {
        if(l_node.x > r_node.x)//swap thw nodes
        {
            Node temp = (Node)(new WeakReference(r_node)).get() ;
            r_node = l_node;
            l_node = temp;
        }
    }
    
    public void showVals(Graphics g)
    {
        adjustNodes();
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);

        g2.setRenderingHint(RenderingHints.KEY_RENDERING,
                            RenderingHints.VALUE_RENDER_QUALITY);

       DrawingUtility.showVals(l_node.x + Node.w/2, l_node.y+Node.h/2,
       r_node.x+Node.w/2, r_node.y+Node.h/2 ,g2, length);
    }

    public void showID(Graphics g)
    {
        adjustNodes();
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);

        g2.setRenderingHint(RenderingHints.KEY_RENDERING,
                            RenderingHints.VALUE_RENDER_QUALITY);
		int dist = (int)Math.pow((Math.pow((r_node.x-l_node.x),2)+Math.pow((r_node.y-l_node.y),2)),0.5) ;
        int fontSize =(int)(dist/4) ;
        if(fontSize>12) fontSize = 12;
        if(fontSize <6) fontSize = 8;
        int fontStyle ;
        if(fontSize<9) fontStyle = Font.BOLD ;
        else fontStyle = Font.PLAIN;
        FontRenderContext frc = g2.getFontRenderContext();
        Font f = new Font("Times", fontStyle, fontSize);
        String s = new String(ID);
        TextLayout tl = new TextLayout(s, f, frc);
        DrawingUtility.showID(l_node.x + Node.w/2, l_node.y+Node.h/2, r_node.x+Node.w/2, r_node.y+Node.h/2 ,g2, tl);
    }


    
    public String getValue(String s) {

		String value = "";
		
		if(s.equalsIgnoreCase("elasticity") && elasticity.equalsIgnoreCase(""))
		value = "ESteel";
		else if(s.equalsIgnoreCase("elasticity"))
		value = elasticity;

		if(s.equalsIgnoreCase("Sy") && sy.equalsIgnoreCase(""))
		value = "Sy";
		else if(s.equalsIgnoreCase("Sy"))
		value = sy;

		if(s.equalsIgnoreCase("length") && length.equalsIgnoreCase(""))
		value = "L" + Integer.toString(getIDVal());
		else if(s.equalsIgnoreCase("length"))
		value = length;

	
		if(s.equalsIgnoreCase("width") && width.equalsIgnoreCase(""))
		value = "W" + Integer.toString(getIDVal());
		else if(s.equalsIgnoreCase("width"))
		value = width;

		if(s.equalsIgnoreCase("height") && height.equalsIgnoreCase(""))
		value = "H" + Integer.toString(getIDVal());
		else if(s.equalsIgnoreCase("height"))
		value = height;

		if(s.equalsIgnoreCase("f_bn") && f_bn.equalsIgnoreCase(""))
		value = "F" + Integer.toString(getIDVal()) + "_bn";
		else if(s.equalsIgnoreCase("f_bn"))
		value = f_bn;

		if(s.equalsIgnoreCase("f_bk") && f_bk.equalsIgnoreCase(""))
		value = "F" + Integer.toString(getIDVal()) + "_bk";
		else if(s.equalsIgnoreCase("f_bk"))
		value = f_bk;

		if(s.equalsIgnoreCase("f_t") && f_t.equalsIgnoreCase(""))
		value = "F" + Integer.toString(getIDVal()) + "_t";
		else if(s.equalsIgnoreCase("f_t"))
		value = f_t;

		if(s.equalsIgnoreCase("sigma") && sigma.equalsIgnoreCase(""))
		value = "Sigma" + Integer.toString(getIDVal());
		else if(s.equalsIgnoreCase("sigma"))
		value = sigma;

		if(s.equalsIgnoreCase("bar_i") && bar_i.equalsIgnoreCase(""))
		value = "I" + Integer.toString(getIDVal());
		else if(s.equalsIgnoreCase("bar_i"))
		value = bar_i;

		if(s.equalsIgnoreCase("bar_f") && bar_f.equalsIgnoreCase("") )
		value = "F" + Integer.toString(getIDVal());
		else if(s.equalsIgnoreCase("bar_f"))
		value = bar_f;
			
	   	//if( value.equals("?") || value.equals("") ||((String)value == null) ) return ID ;
	      // else return value;
	      
	      return value;
    }

    public void setValue(Object[] input)
    {
        elasticity 	=	(String)input[0];
        sy 			= 	(String)input[1];
        length 		= 	(String)input[2];
        width 		= 	(String)input[3];
        height 		= 	(String)input[4];
        f_bn		= 	(String)input[5];
        f_bk 		= 	(String)input[6];
        f_t 		= 	(String)input[7];
        sigma 		= 	(String)input[8];
        bar_i 		= 	(String)input[9];
        bar_f 		= 	(String)input[10];
		
    }
    
    public boolean bothEndsSelected() {
        if(l_node.isSelected && r_node.isSelected) return true;
        else return false;
    }

    public void adjustCenter(){
        double dist = Math.sqrt( Math.pow((l_node.x-r_node.x),2) + Math.pow((l_node.y-r_node.y),2) );        
        float x = (float)(l_node.x + 0.35*dist );
        float y = (float)(l_node.y - 0.1*dist );
        float w = (float)(0.3*dist);
        float h = (float)(0.2*dist);
        Shape temp = new Ellipse2D.Float(x,y,w,h);
        double phi = Math.atan((r_node.y - l_node.y)/(r_node.x - l_node.x) ) ;
        AffineTransform at = new AffineTransform() ;
        at.rotate(phi, l_node.x, l_node.y);    
        center  =  at.createTransformedShape(temp) ;
    }
    
    public boolean centerSelected(int x, int y, boolean leftClicked) {
        boolean selected = center.contains(x,y);

   //if rightClicked...
         
        if(!leftClicked){
            return selected ;
        }        


   //if left clicked...
 
         
        if(currentCenterCheck) {
            currentCenterCheck = false;
            return false;
        }
        else currentCenterCheck = true;
            
        if(selected){
            if( l_node.isSelected && r_node.isSelected ){
                l_node.disSelect();
                r_node.disSelect();
                l_node.isDraggable = false;            
                r_node.isDraggable = false;            
                l_node.unsetToMove();
                r_node.unsetToMove();
            }
            else{
                l_node.select();
                r_node.select();
                l_node.isDraggable = true;            
                r_node.isDraggable = true;
            }
        }
        return selected;
    }

    public abstract String getType();
    public abstract void picked(Graphics g);
    public abstract void draw(Graphics g);
    public abstract void basicDraw(Graphics g);
    
    public void pickdraw(Graphics g)
    {
   	if(isPicked) picked(g);
    }
    
    public void clearPick()
    {
    	isPicked =false;
    }
    
    public  int getIDVal() {
        return Integer.parseInt(ID.substring(1)) ; 
    }
    
 
    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 addInstanceConstriant(String constraint) {
        instanceConstraints.add(constraint);
    }

    public void removeAllInstanceConstriant() {
        instanceConstraints.clear();
    }

    
    
}


