/*
 * @(#)MovingRedBlackTree.java
 *
 * Last Modified: 9/15/01
 */

 import java.util.*;
 import java.lang.*;
 import java.awt.*;
 import java.awt.font.*;
 import java.awt.geom.*;

/** *
 	* The class provides the base structure for a <code>RedBlackTree</code> that can move to a new position
 	* in the Binary Search Tree. For that reason, it extends the BSTTree class.
    *
	* <p><hr>The MovingRedBlackTree defines methods necessary to move a RedBlackTree from one location
	* in a Binary Search Tree to another. Because the methods are moving, they require animation.
	* Consequently, the extension <b>must</b> be from an AnimatingBSTTree. The constructor ensures
	* this construction, however, changes cannot be made. To protect the changes from occuring,
	* the methods have been overiden to have no affect.
	*
	* @author  Corey Sanders
	* @version 2.2 9/15/01
 	*/

public class MovingRedBlackTree extends MovingBSTTree  {

	/**
	 * Node that the moving node can follow or imitates.
	 */
	protected RedBlackTree node = null;

	/**
	 * Constructor without a parent passed, indicating that <code>FOLLOW_PARENT_LEFT</code> and <code>FOLLOW_PARENT_RIGHT</code>
	 * are not accesible unless a parent is set. The MovingBSTTree constructs as an empty <code>ANIMATING_BST_TREE_TYPEM</code>
	 *, setting the value and key as the value and key of the given node. The MovingBSTTree imitates
	 * the <code>BSTTree</code> node given but does not affect the node.
	 *
	 * @param node BSTTree node that the MovingBSTTree imitates.
	 */
	public MovingRedBlackTree(BSTTree node) {
		this(node, null);
	}

	/**
	 * Constructor with a parent passed. The MovingBSTTree constructs as an empty <code>ANIMATING_BST_TREE_TYPEM</code>
	 *, setting the value and key as the value and key of the given node. The MovingBSTTree imitates
	 * the <code>BSTTree</code> node given but does not affect the node.
	 *
	 * @param node BSTTree node that the MovingBSTTree imitates.
	 * @param movingParent MovingBSTTree that is the parent of the current node, allowing the follow parent move positions.
	 */
	public MovingRedBlackTree(BSTTree node, MovingBSTTree movingParent) {
		super(node, movingParent);
	}


	/**
	 * Sets the node that the <code>MovingBSTTree</code> imitates. The key and value are set according
	 * to the given node.
	 *
	 * @param node BSTTree node that the MovingBSTTree imitates.
	 */
	public void setNode(RedBlackTree node) {
		this.node = node;
		this.setNode(node.getKey(), (DrawableKey)((DrawableKey)node.getValue()).clone());
	}

	/**
	 * Draws just the right link according to the NodeSettings currently set.
	 *
	 * @param g2 graphics to which the node and links are drawn.
	 * @param sectionHeight the height of the tree' section, to draw the correct lengths for the links.
	 * @param a transfrom to draw the node and links.
	 * @param drawingLevel the level in the tree to which the node is currently being drawn.
	 * @param powerLevel the power to which the links extend, depending on how many links are present.
	 */
	 protected void drawRightLink(Graphics2D g2, double sectionHeight, AffineTransform a, double drawingLevel, double powerLevel) {

		Rectangle2D bounds = g2.getClipBounds();

		// Right line
		Line2D.Double right = new Line2D.Double( (a.getTranslateX() + (3*a.getScaleX())/4.0) , (a.getTranslateY() + a.getScaleY()/2.0) , (a.getTranslateX() + a.getScaleX()/2.0 + bounds.getWidth()/powerLevel) , (sectionHeight * drawingLevel));

		// Set graphics information
		if (!(((RedBlackTree)getNode()).getRightTree().isEmpty()) && ((RedBlackTree)((RedBlackTree)getNode()).getRightTree()).isRedLink()) {
			g2.setStroke(((RedBlackTree)getNode()).getRedLinkStroke());
			g2.setPaint(((RedBlackTree)getNode()).getRedLinkPaint().getPaint());
		}
		else {
			g2.setStroke(getSettings().getRightLinkStroke());
			g2.setPaint(getSettings().getRightLinkPaint());
		}


		g2.setComposite(getSettings().getRightLinkComposite());
		g2.draw(right);

	}

	/**
	 * Draws just the left link according to the NodeSettings currently set.
	 *
	 * @param g2 graphics to which the node and links are drawn.
	 * @param sectionHeight the height of the tree' section, to draw the correct lengths for the links.
	 * @param a transfrom to draw the node and links.
	 * @param drawingLevel the level in the tree to which the node is currently being drawn.
	 * @param powerLevel the power to which the links extend, depending on how many links are present.
	 */
	 protected void drawLeftLink(Graphics2D g2, double sectionHeight, AffineTransform a, double drawingLevel, double powerLevel) {

		Rectangle2D bounds = g2.getClipBounds();

		// Draw the left and right links
		Line2D.Double left = new Line2D.Double( (a.getTranslateX() + a.getScaleX()/4.0) , (a.getTranslateY() + a.getScaleY()/2.0) , (a.getTranslateX() + a.getScaleX()/2.0 - bounds.getWidth()/powerLevel) , (sectionHeight * drawingLevel));

		// Set graphics information
		if (!(((RedBlackTree)getNode()).getLeftTree().isEmpty()) && ((RedBlackTree)((RedBlackTree)getNode()).getLeftTree()).isRedLink()) {
			g2.setStroke(((RedBlackTree)getNode()).getRedLinkStroke());
			g2.setPaint(((RedBlackTree)getNode()).getRedLinkPaint().getPaint());
		}
		else {
			g2.setStroke(getSettings().getRightLinkStroke());
			g2.setPaint(getSettings().getRightLinkPaint());
		}


		g2.setComposite(getSettings().getRightLinkComposite());
		g2.draw(left);
	}




}
