/**
 * @fileoverview
 * 
 * <p>Copyright (c) 2006 Peter Michaux. All rights reserved.<br />
 * Code licensed under the MIT License:<br />
 * http://michaux.ca/svn/dragdrop/trunk/MIT-LICENSE.txt</p>
 *
 * @author Peter Michaux - http://peter.michaux.ca
 * @version 0.1 (August 2006)
 */

/**
 * @class
 * <p>AbstractEdge is an abstract base class. It defines much of the
 * basic behavior for one edge of a donut proxy.
 * Subclasses must complete the definition by defining
 * the size and placement of each instance.</p>
 *
 * <p>Each instance is a div HTMLElement with class attribute
 * "proxy" which may be used for CSS styling.</p>
 * 
 * @private
 *
 * @constructor
 */
function AbstractEdge() {  
	this.element = document.createElement("div");
	this.element.className = "proxy";
	var s = this.element.style;
	s.position = "absolute";
	s.display = "none";
	s.zIndex = "999";
	s.margin = "0";
	s.padding = "0";
	document.body.appendChild(this.element);
}

AbstractEdge.prototype = {
  
 /**
  * <p>Hides the HTMLElement by setting the element's display style to "none".</p>
  */
	hide: function() {
		this.element.style.display = "none";
	},
	
 /**
  * <p>Shows the HTMLElement by setting the element's display style to "block".</p>
  */
	show: function() {
		this.element.style.display = "block";
	},
	
 /**
  * <p>Relocates the instance's HTMLElement related to the arguments x and y.</p>
  *
  * <p>Before this method is called, the instance's integer hOffset and
  * vOffset properties must be set. These represent the horizontal and 
  * vertical pixel displacements of the left and top of the HTMLElement
  * from the cursor event location. A positive hOffset will position the
  * element below the cursor and negative value will position the element
  * above the cursor. A positive vOffset will position the element right
  * of the cursor and a negative value will position the element left
  * of the cursor.</p>
  *
  * @param {Integer} x The new pixel location to be used as a horizontal reference
  * for repositioning the HTMLElement. The value of x is relative to the
  * left of the document.
  * @param {Integer} y The new pixel location to be used as a vertical reference
  * for repositioning the HTMLElement. The value of y is relative to the
  * top of the document.
  */	
	moveTo: function(x, y) {
		this.element.style.left = (x + this.hOffset) + "px";
		this.element.style.top = (y + this.vOffset) + "px";
	}
};

// ----------------------------------------------------------------------------

/**
 * @class
 * <p>AbstractDonut is an abstract base class. It defines much of the
 * basic behavior for a donut proxy with multiple edges.</p>
 *
 * <p>Subclasses must complete the definition by defining
 * the edges of the proxy. A donut proxy
 * typically will have four edges: top, left, bottom and right. These edges
 * are defined in the subclasses constructor and are properties of the
 * edges property.</p>
 *
 * @constructor
 */

function AbstractDonut() {
  this.edges = {};
}

AbstractDonut.prototype = {
 /**
  * <p>Calls the hide method on each of the edges.</p>
  *
  * @private
  */
  hide: function() {
		for (var e in this.edges) {
			this.edges[e].hide();
		}
	},
	
 /**
  * <p>Calls the show method on each of the edges.</p>
  *
  * @private
  */
	show: function() {
		for (var e in this.edges) {
			this.edges[e].show();
		}
	},
	
 /**
  * <p>Relocates the proxy's edges relative to the arguments x and y.</p>
  *
  * @param {Integer} x The new pixel location to be used as a horizontal reference
  * for repositioning the edges. The value of x is relative to the
  * left of the document.
  * @param {Integer} y The new pixel location to be used as a vertical reference
  * for repositioning the edges. The value of y is relative to the
  * top of the document.
  *
  * @private
  */
	moveTo: function(x, y) {
		for (var e in this.edges) {
			this.edges[e].moveTo(x, y);
		}
	},
  
 /**
  * <p>Locates the proxy relative to the mouse event and then shows the proxy.</p>
  * <p>Called by the dragdrop manager at the start of a drag.</p>
  *
  * @param {MouseEvent} e The mouse event object that initiated the drag.
  */
  onDragStart: function(e) {
	  this.moveTo(YAHOO.util.Event.getPageX(e), YAHOO.util.Event.getPageY(e));
		this.show();
	},
	
 /**
  * <p>Relocates the proxy relative to the mouse event.</p>
  * <p>Called by the dragdrop manager for every drag. This is called very often 
  * so try to keep this method efficient.</p>
  *
  * @param {MouseEvent} e The mousemove's mouse event object.
  */
  onDrag: function(e) {
	  this.moveTo(YAHOO.util.Event.getPageX(e), YAHOO.util.Event.getPageY(e));
	},
	
 /**
  * <p>Hides the proxy.</p>
  * <p>Called by the dragdrop manager at the end of a drag.</p>
  */
  onDragEnd: function() {
	  this.hide();
	}
	
};