/*
   Tamot --- Task Modelling Editor
   Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
   (CSIRO), Australia. All rights reserved. 

   The Software, owned by CSIRO Australia, has been developed by the CSIRO 
   Intelligent Interactive Technology group. 
   For more information, please see http://www.cmis.csiro.au/iit/.

   The Software is a beta-test version for internal research and evaluation purposes 
   by the Licensee. The Software is still at a development stage. 
   It has not undergone complete testing and may have inherent errors,
   bugs or deficiencies that can affect the operation of the Software. 

   We encourage your feedback and suggestions. Any bugs / suggestions found please email to
   Shijian.Lu@cmis.csiro.au and Thomas.Lo@cmis.csiro.au. 

   After you have signed the Beta-Test Software License Agreement with the CSIRO,
   CSIRO grants you a non-exclusive, non-transferable license to use it only for your 
   personal, non-commercial and lawful end use. Implied licenses are negated. 

   Warranty Disclaimer : 

   CSIRO supplies the Software on an "as is" basis and makes no warranties that use of
   the Software by the Licensee will not infringe any third party’s 
   Intellectual Property Rights nor that the Software will be of merchantable quality,
   or suitable for a particular purpose. CSIRO excludes all terms, conditions and
   warranties implied by custom, the general law or statute in relation to the
   Software.
*/

package taskModellingTool;

import java.util.*;
import java.awt.*;
import java.io.*;
import java.lang.reflect.*;
import java.awt.geom.Area;


public abstract class LinkableComponent extends GenericComponent implements Serializable{

    protected Vector linkList = new Vector();
        
    protected static final double w0=1;  //in u
    protected static final double h0=1;  //in u
    protected double w=1;  //in u
    protected double h=1;  //in u
    
    protected static final int FIRST_LOCATION_X=50;
    protected static final int FIRST_LOCATION_Y=50;
    
    protected double backupX;
    protected double backupY;
    protected boolean floating=false;
    
    public LinkableComponent(String name) {
    	super(name);
    }
    
    /*public LinkableComponent(LinkableComponent lc,Object [] obj){
    	super();
    	name=lc.name;
    	Class cl=lc.getClass();
    	Field field;
    	String type;
    	for (int i=0;i<obj.length;i++){
    	   try{
    	       field=(cl.getField((String)obj[i]));
    	       type=field.getType().getName();
    	       if (type.equals("java.lang.String"))
    	           field.set(this,field.get(lc));
    	       else if (type.equals("int"))
    	           field.setInt(this,field.getInt(lc));
    	       else if (type.equals("boolean")){
    	           field.setBoolean(this,field.getBoolean(lc));
    	           System.out.println("Fields: original: "+field.getBoolean(lc)+"   new: "+field.getBoolean(this));}
   	   } catch (Exception except){System.err.println(except.toString());}
       }    	
    }*/
    
    //--------------------------- IO ------------------------------/
    // for externalization purposes
    public LinkableComponent() {
    	super();
    }
    
    public void writeExternal(ObjectOutput out) throws IOException{
    	super.writeExternal(out);
    	out.writeDouble(backupX);
    	out.writeDouble(backupY);
    	//out.writeObject(linkList);
    }
    
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException{
    	super.readExternal(in);
    	backupX=in.readDouble();
    	backupY=in.readDouble();
    	//linkList=(Vector)in.readObject();  	
    }
    


    public void addLink(Link lc){
        linkList.add(lc);
    }
    
    public Vector getLinks(){
    	return linkList;
    }
    
    public void updateLinks(){
    	Link l;
    	for (int i=0;i<linkList.size();i++){
    	    //((Link)linkList.get(i)).updateLink();
    	    l=(Link)linkList.get(i);
    	    System.out.println(name+" is updating link "+l.getName());
            l.updateLink();
    	}
    }
    public void deleteLink(Link l){
    	LinkableComponent lc=((this==l.lc1)?l.lc2:l.lc1);
    	linkList.remove(l);
    	lc.linkList.remove(l);
    }
    
    //dangerous. Problem of coherence.
    public void deleteLinks(){
    	linkList.clear();
    }
       	
    public void paintComponent(Graphics g){
    	super.paintComponent(g);
    	Graphics2D g2 = (Graphics2D)g;
    	drawComponent(g2);
    }

    public boolean intersection(GenericComponent gc) {
    	boolean result = false;
        
    	if (!(gc instanceof Link)) {
    	    Area s1 = getArea();
    	    Area s2 = gc.getArea();

    	    int x1 = getX();
    	    int y1 = getY();
    	    int w1 = getWidth();
    	    int h1 = getHeight();
            
    	    int x2 = gc.getX();
    	    int y2 = gc.getY();
    	    int w2 = gc.getWidth();
    	    int h2 = gc.getHeight();
    	
    	
    	    // intersection of the two components' rectangles
    	    int xx=(x1>x2)?x1:x2;
    	    int yy=(y1>y2)?y1:y2;
    	    //                        inside  outside                   inside outside    
    	    int ww=(x1<x2)?(((x2+w2)<(x1+w1))?w2:(x1+w1-x2)):(((x1+w1)<(x2+w2))?w1:(x2+w2-x1));
    	    //                        inside  outside                   inside outside    
    	    int hh=(y1<y2)?(((y2+h2)<(y1+h1))?h2:(y1+h1-y2)):(((y1+h1)<(y2+h2))?h1:(y2+h2-y1));
    	        	
            //TMUtility.display("x1",x1);
            //TMUtility.display("y1",y1);
            //TMUtility.display("w1",w1);
            //TMUtility.display("h1",h1);
            
            //TMUtility.display("x2",x2);
            //TMUtility.display("y2",y2);
            //TMUtility.display("w2",w2);
            //TMUtility.display("h2",h2);

            //TMUtility.display("xx",xx);
            //TMUtility.display("yy",yy);
            //TMUtility.display("ww",ww);
            //TMUtility.display("hh",hh);

            if ((ww>=0)&&(hh>=0)){
    	        int xx2=xx+ww;
    	        int yy2=yy+hh;

                //TMUtility.display("xx2",xx2);
                //TMUtility.display("yy2",yy2);
                
    	        for (int i=xx+1;i<xx2;i++) for (int j=yy+1;j<yy2;j++){
    	            if ( (s1.contains(i-x1,j-y1))&&(s2.contains(i-x2,j-y2)) ) {
    	                result=true;
    	                break;
    	            }
    	        }
    	    }
    	}

        //TMUtility.display("LinkableComponent intersection : "+name+" - "+gc.getName(),result);
        
    	return result;
    }
    
    public abstract double giveWidth();

    /*public void setSize(int width,int height){
    	dWidth=width;
    	dHeight=height;
    	super.setSize(width,height);
    }
        
    public void setSize(Dimension d){
    	dWidth=d.width;
    	dHeight=d.height;
    	super.setSize(d);
    }
    
    public void setLocation(int x,int y){
    	dX=x;
    	dY=y;
    	super.setLocation(x,y);
    }
        
    public void setLocation(Point p){
    	dX=p.x;
    	dY=p.y;
    	super.setLocation(p.x,p.y);
    }
    
    public void setBounds(int x,int y,int width,int height){
    	dX=x;
    	dY=y;
    	dWidth=width;
    	dHeight=height;
    	super.setBounds(x,y,width,height);
    }
        
    public void setBounds(Rectangle r){
    	dX=r.x;
    	dY=r.y;
    	dWidth=r.width;
    	dHeight=r.height;
    	super.setBounds(r);
    }*/
        
        
}