/**
 * @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>An instance of JellyEdge is for use as an edge of an
 * instance of JellyDonut.</p>
 * 
 * @private
 *
 * @extends AbstractEdge
 *
 * @constructor
 */
function JellyEdge() {  
  JellyEdge.superclass.constructor.call(this);
  this.element.style.overflow="hidden";
  YAHOO.util.Dom.setStyle(this.element, "opacity", "0.8")
};
YAHOO.extend(JellyEdge, AbstractEdge);
  
JellyEdge.prototype.init = function(height, width, vOffset, hOffset) {
  if (height<0){height=0;}
  if (width<0){width=0;}
  var s = this.element.style;
  s.height = height+"px";
  s.width = width+"px";
  //s.top = "0px";
  //s.left = "0px";
  this.vOffset = vOffset;
  this.hOffset = hOffset;
};
  	
JellyEdge.prototype.clearFilling = function() {
  var fc = this.element.firstChild;
  while(fc) {
    this.element.removeChild(fc);
    fc = this.element.firstChild;
  }
};

/* selected can be just one or an array of HTMLElements */
JellyEdge.prototype.addFilling = function(x, y, selected) {
  if (selected.constructor !== Array) {
    selected = [selected];
  }
  
  for (var s in selected) {
    var el = selected[s].cloneNode(true);
    el.style.position = "absolute";
    el.style.margin="0";
    var r = YAHOO.util.Dom.getRegion(selected[s]);
    el.style.top = (r.top - (y+this.vOffset)) + "px";
    el.style.left = (r.left - (x+this.hOffset)) + "px";
    this.element.appendChild(el);
  }
};

/**
 * @class
 * <p>An instance of JellyDonut can be used with DragManager
 * or a subclass of DragManager. A JellyDonut proxy self-resizes at the the start
 * of each drag to look like the selected element or elements.</p>
 *
 * <p>Some
 * appearance differences may exist between the proxy and the selected elemnts.
 * This is because the proxy is not nested in the DOM
 * like the selected elements and so some inherited CSS properties may not apply to 
 * the proxy. You can account for this by explicitly specifying all properties for your 
 * draggables through the use of class name selectors (not id selectors) on the 
 * draggable elements or child elements in the CSS.</p>
 *
 * @extends AbstractDonut
 *
 * @constructor
 * @param {Integer} holeRadius The pixel radius for the donut hole
 * in the JellyDonut proxy object.
 */
function JellyDonut(holeRadius) {
  JellyDonut.superclass.constructor.call(this);
  var e = this.edges;
  e.top = new JellyEdge();
  e.left = new JellyEdge();
  e.right = new JellyEdge();
  e.bottom = new JellyEdge();
  this.holeRadius = holeRadius;
};
YAHOO.extend(JellyDonut, AbstractDonut);


//	JellyDonut.prototype.clearFilling = function() {
//		for (var e in this.edges) {
//			this.edges[e].clearFilling();
//		}
//	};
	
/* elements can be just one or an array of HTMLElements */
JellyDonut.prototype.getCombinedRegion = function(selected) {
  if (selected.constructor !== Array) {
    selected = [selected];
  }

  var top=null, left=null, bottom=null, right=null;

  for (var e in selected) {
    var r = YAHOO.util.Dom.getRegion(selected[e]);
    if (!left || r.left < left) {left = r.left;}
    if (!right || r.right > right) {right = r.right;}
    if (!top || r.top < top) {top = r.top;}
    if (!bottom || r.bottom > bottom) {bottom = r.bottom;}
  }
  return {top:top,left:left,right:right,bottom:bottom};
};
  
JellyDonut.prototype.addFilling = function(e, selected) {

  var x = YAHOO.util.Event.getPageX(e);
  var y = YAHOO.util.Event.getPageY(e);

  var combinedRegion = this.getCombinedRegion(selected);
  var height = combinedRegion.bottom - combinedRegion.top;
  var width = combinedRegion.right - combinedRegion.left;

  var top_height = y-combinedRegion.top - this.holeRadius;
  this.edges.top.init(top_height,
                      width,
                      combinedRegion.top-y,
                      combinedRegion.left-x);

  var bottom_height = combinedRegion.bottom-y-this.holeRadius;
  this.edges.bottom.init(bottom_height,
                         width,
                         this.holeRadius,
                         combinedRegion.left-x);

  this.edges.left.init(height-top_height-bottom_height,
                       x-combinedRegion.left-this.holeRadius,
                       combinedRegion.top-y+top_height,
                       combinedRegion.left-x);

  this.edges.right.init(height-top_height-bottom_height,
                        combinedRegion.right-x-this.holeRadius,
                        combinedRegion.top-y+top_height,
                        this.holeRadius);

  for (var i in this.edges) {
    this.edges[i].clearFilling();
    this.edges[i].addFilling(x, y, selected);
  }
  
};
  
JellyDonut.prototype.onDragStart = function(e, selected) {
  this.addFilling(e, selected);
  JellyDonut.superclass.onDragStart.call(this, e);
};