/** updated on Oct.11 by Qian Li to support Forwarding Mechanism */
package graph;

import java.awt.*;
import java.net.*;
import java.io.*;

public class Node extends GraphObject implements java.io.Serializable {

//***** Variables *****

//protected

protected Point position = new Point ( 0, 0 );  // left upper most point of the node
protected URL content;
protected MIME_Type contentType;
protected URL hypergraphs[ ];
protected int nhypergraphs;
protected int currenthypergraph;
protected Color color;

protected boolean valid = true;
protected boolean selected = false;

protected boolean forwarded = false;
protected URL forwardURL=null;
protected URL backwardURL=null;
// ??? backward reference???

protected Point center = new Point ( 0, 0 );  // in global graph space
protected Point labeloffset = new Point ( 0, 0 );  //
protected Point wh = new Point ( 0, 0 );  // relative to node

public static int DEFAULT_MARGIN=6;
//***** Constructors *****

	Node() {
		super ();
		init ();
	}  // end Node() constructor

	Node ( String lbl ) {
		super( lbl );
		init ();
	}  // end Node(String lbl) constructor

	public Node( URL u ) {
		super ( u );
	    init();
	}  // end Node() constructor

	public Node( URL u, String l ) {
		super( u, l );
	    init();
	}  // end Node( URL u, String l ) constructor

//***** Methods *****

public void init ( )  {
    wh = new Point ( 50, 30);
    nhypergraphs = 0;
    hypergraphs = new URL[10];

}  // end init ()

public synchronized void setLabel(String label,int xleng, int yleng) {
    super.setLabel(label);
    //this.setNodeSize(g,DEFAULT_MARGIN);
    //FontMetrics fm;
    int x, y;
    int margin=DEFAULT_MARGIN;
    //fm = g.getFontMetrics ();
    x = xleng + 4*margin;
    //System.out.println("new string width:"+xleng+"  "+label);
    //System.out.println("new width:"+x);
    y = yleng + 2*margin;
    wh.x = x;
    wh.y = y;
    x = wh.x/2;
    y = wh.y/2;
    center.x = x;    // offset
    center.y = y;    // offset
    x = position.x + 2*margin;
    y = position.y + margin + yleng;
    labeloffset.x = x;
    labeloffset.y = y;

}

/*
public synchronized void setNodeSize ( Graphics g, int margin )  {
    FontMetrics fm;
    int x, y;
    fm = g.getFontMetrics ();
    x = fm.stringWidth(label) + 4*margin;
    System.out.println("new string width:"+fm.stringWidth(label)+"  "+label);
    System.out.println("new width:"+x);
    y = fm.getAscent() + 2*margin;
    wh.x = x;
    wh.y = y;
    x = wh.x/2;
    y = wh.y/2;
    center.x = x;    // offset
    center.y = y;    // offset
    x = position.x + 2*margin;
    y = position.y + margin + fm.getAscent();
    labeloffset.x = x;
    labeloffset.y = y;
}  // end setNodeSize
*/

public synchronized void setPosition ( Point p ) {
    labeloffset.x = labeloffset.x - ( position.x - p.x);
    labeloffset.y = labeloffset.y - ( position.y - p.y);
    position.x = p.x;
    position.y = p.y;
}  // end setPosition ( Point p )

public Point getPosition ( )  {
    return position;
}  // end getPosition ( )

public Point getWh ( )  {
    return wh;
}  // end getgetWh ( )

public Point getLabelOffset ( )  {
    return labeloffset;
}  // end getgetWh ( )

public Point getCenter ( ) {
    Point p = new Point ( position.x, position.y);
    p.x += center.x;
    p.y += center.y;
    return p;
}  // end getCenter

public void setContent ( URL url ) {
    content = url;
}  // end setContent ( URL url )

public URL getContent ( )  {
    return content;
}  // end getContent ( )

public void setContentType ( MIME_Type type ) {
    contentType = type;
}  // end setContentType ( MIME_Type type )

public MIME_Type getContentType ( )  {
    return contentType;
}  // end getContentType ( )

public void setColor ( Color c ) {
    color = c;
}  // end setcolor ( URL url )

public Color getcolor ( )  {
    return color;
}  // end getcolor ( )

public void setValid ( boolean b ) {
    valid = b;
}  // end setValid ( boolean b )

public boolean getValid ( )  {
    return valid||forwarded;
}  // end getValid ( )

public void setSelected ( boolean b ) {
    selected = b;
}  // end setSelected ( boolean b )

public boolean getSelected ( )  {
    return selected;
}  // end getSelected ( )

    public boolean touched ( Point p )
    {
        if ( p.x >= position.x  &&
             p.x <= position.x + wh.x &&
             p.y >= position.y  &&
             p.y <= position.y + wh.y )
             return true;
             else return false;
    }  // end touched ( Point p )


    public boolean addHyperGraph( URL hg)
    {
        if ( nhypergraphs < hypergraphs.length ) {
            hypergraphs [ nhypergraphs ] = hg;
            nhypergraphs++;
        }
        else {
            bumpHyperGraphsArray ();
            hypergraphs [ nhypergraphs ] = hg;
            nhypergraphs++;
        }
        return true;
    }  // end addHyperGraph ()

    public URL getFirstHyperGraph ( )
    {
        currenthypergraph = 0;
        if ( nhypergraphs < 1 ) return null;
        else return hypergraphs[ 0 ];
    }  // end getFirstHyperGraph ( )

    public URL getNextHyperGraph ( )
    {
        currenthypergraph++;
        if ( currenthypergraph > nhypergraphs ) return null;
        else return hypergraphs[currenthypergraph];
    }  // end getNextHyperGraph ( )


    private void bumpHyperGraphsArray () {
        int i = hypergraphs.length;
        URL temp [ ] = new URL [ i ];
        temp = hypergraphs;
        hypergraphs  = new URL [ i + 10 ];
        for ( int j = 0; j < temp.length; j++ )  {
        hypergraphs[ j ] = temp[ j ];
       }  // end for
    }  // end bumpHyperGraphsArray ()

    public void setForwarded(boolean value) {
        this.forwarded=value;
    }

    public boolean getForwarded() {
        return this.forwarded;
    }

    public void setForwardURL(URL forwardurl) {
        this.forwardURL=forwardurl;
    }
    public void setBackwardURL(URL backwardurl) {
        this.backwardURL=backwardurl;
    }
    public URL getForwardURL() {
        return this.forwardURL;
    }
    public URL getBackwardURL() {
        return this.backwardURL;
    }

}  // end Node


