package Nodepad;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


/**
 * ParentNode.java
 *
 *
 * Created: Mon Dec 23 16:22:55 2002
 *
 * @author <a href="mailto:shapiro@cse.buffalo.edu">Stuart C. Shapiro</a>
 * @version
 *
 * An abstract integer-valued node that can be moved around a sketch Pad.
 */

public abstract class ParentNode extends JComponent
    implements MouseListener, MouseMotionListener {

    protected Pad pad; // The sketch Pad this node is on.
    protected Point locpt; // This node's location.
    protected Dimension size = new Dimension(70, 40); // This node's dimension.
    protected int value; // This node's integer value.
    protected String label; // This node's integer value as a string.
    protected int dx, // The distance between locpt and the cursor
	dy;         // during movement.
    protected boolean shouldmove; // true if this node should follow the cursor.

    /**
     * Creates a Node, with a given Pad, location, and value.
     *
     * @param p the Pad this node is on.
     * @param x the x value of this node's initial location.
     * @param y the y value of this node's initial location.
     * @param v the integer value of this node.
     */
    public ParentNode (Pad p, int x, int y, int v) {
	pad = p;
	setLocation(x,y);
	locpt = getLocation();
	setSize(size);
	value = v;
	label = "" + v;
	setBackground(Color.white);
	pad.addMouseListener(this);
	pad.addMouseMotionListener(this);
    }

    public abstract void paintComponent(Graphics g);

    /**
     * Ignores mouse clicking.
     */
    public void mouseClicked (MouseEvent evt){
    }

    /**
     * Initializes cursor following
     * if the mouse is pressed inside this node.
     */
    public void mousePressed (MouseEvent evt){
	if (this.getBounds().contains(evt.getX(), evt.getY())) {
	    if (pad.getMovingNodes()) {
	    shouldmove = true;
	    dx = getLocation().x - evt.getX();
	    dy = getLocation().y - evt.getY();
	    } // end of if (pad.getMovingNodes())
	    else {
		GhostNode gn = new GhostNode(pad, locpt.x, locpt.y, value);
		gn.dx = getLocation().x - evt.getX();
		gn.dy = getLocation().y - evt.getY();
		pad.setAcc(value);
		pad.add(gn);
	    } // end of else
	    
	}
    }

    public abstract void mouseReleased (MouseEvent evt);

    /**
     * Ignores mouse entering.
     */
    public void mouseEntered (MouseEvent evt){
    }

    /**
     * Ignores mouse exiting.
     */
    public void mouseExited (MouseEvent evt){
    }

    /**
     * Ignores mouse movement.
     */
    public void mouseMoved (MouseEvent evt){
    }

    /**
     * Causes this node to follow the cursor
     * if the mouse had been pressed inside it.
     */
    public void mouseDragged (MouseEvent evt){
	if (shouldmove) {
	    moveTo(evt.getX()+dx, evt.getY()+dy);
	}
    }

    /**
     * Moves this node to a new location.
     * 
     * @param x the new x location.
     * @param y the new y location.
     */
    protected void moveTo(int x, int y){
	Rectangle bounds = getBounds();
	locpt.move(x, y);
	setLocation(locpt);
	pad.repaint(bounds.union(getBounds()));
    }
}// ParentNode
