/**
 * @fileoverview
 * 
 * <p>Copyright (c) 2006 Peter Michaux All rights reserved<br />
 * All rights reserved <br />
 * This file is not licensed for use or redistribution.</p>
 *
 * @author Peter Michaux
 * @version 0.1 (June 2006)
 */

PM.ProxyPart = function() {
  var element = document.createElement("div");
  PM.ProxyPart.superclass.call(this, element);
  document.body.appendChild(element);
  var s = element.style;
  s.position = "absolute";
  s.display = "none";
  s.zIndex = 999; // TODO increase?
  s.margin = "0";
  s.padding = "0";
  s.overflow="hidden";
YAHOO.util.Dom.setStyle(this.element, "opacity", "0.8")};
PM.extend(PM.ProxyPart, PM.Dual);

PM.ProxyPart.prototype.init = function(height, width, topOffset, leftOffset) {
  if (height<0){height=0;}
  if (width<0){width=0;}
  var s = this.element.style;
  s.height = height+"px";
  s.width = width+"px";
  //s.background = "lightgrey";
  s.top = "0px";
  s.left="0px";
  // TODO setHeight method to avoid mismatch of inline css and property
  this.height = height;
  this.width = width;
  this.topOffset = topOffset;
  this.leftOffset = leftOffset;
  
};

PM.ProxyPart.prototype.moveTo = function(left, top) {
  this.element.style.top = (top+this.topOffset)+"px";
  this.element.style.left = (left+this.leftOffset)+"px";
};

PM.ProxyPart.prototype.show = function() {
  this.element.style.display = "block";
};

PM.ProxyPart.prototype.hide = function() {
  this.element.style.display = "none";
};

PM.ProxyPart.prototype.clearFilling = function() {
  var fc = this.element.firstChild;
  while(fc) {
    this.element.removeChild(fc);
    fc = this.element.firstChild;
  }
};

PM.ProxyPart.prototype.addFilling = function(x, y, clusters) {
  for(var c in clusters) {
    var cluster = clusters[c];
    for (var d in cluster.duals) {
      var dual = cluster.duals[d];
      var el = dual.element.cloneNode(true);
      el.style.position = "absolute";
      el.style.margin="0";
      el.style.top = (dual.region.top - (y+this.topOffset)) + "px";
      el.style.left = (dual.region.left - (x+this.leftOffset)) + "px";
      this.element.appendChild(el);
    }
  }  
};

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

PM.Proxy = function() {
  this.parts = {};
  this.parts.top = new PM.ProxyPart();
  this.parts.left = new PM.ProxyPart();
  this.parts.right = new PM.ProxyPart();
  this.parts.bottom = new PM.ProxyPart();
  PM.Proxy.superclass.call(this, [this.parts.top, this.parts.left,
                                  this.parts.right, this.parts.bottom], "proxy");
};
PM.extend(PM.Proxy, PM.Cluster);

PM.Proxy.prototype.moveTo = function(left, top) {
  for (var i in this.parts) {
    this.parts[i].moveTo(left, top);
  }
};

// TODO move
PM.Cluster.prototype.getRegion = function() {
  var top=null, left=null, bottom=null, right=null;
  for (e in this.duals) {
    var el = this.duals[e];
    el.region = YAHOO.util.Dom.getRegion(el.element);
    if (!left || el.region.left < left) {left = el.region.left;}
    if (!right || el.region.right > right) {right = el.region.right;}
    if (!top || el.region.top < top) {top = el.region.top;}
    if (!bottom || el.region.bottom > bottom) {bottom = el.region.bottom;}
  }
  return {top:top,left:left,right:right,bottom:bottom};
};

PM.Cluster.getCombinedRegion = function(clusters) {
  var top=null, left=null, bottom=null, right=null;

  for (var c in clusters) {
    var r = clusters[c].getRegion();
    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};
};

PM.Proxy.prototype.prep = function(e, clusters) {
  
  var x = YAHOO.util.Event.getPageX(e);
  var y = YAHOO.util.Event.getPageY(e);
  
  this.holeRadius = 6;
  
  var combinedRegion = PM.Cluster.getCombinedRegion(clusters);
  logMessage(combinedRegion.top+" "+combinedRegion.bottom+" "+
             combinedRegion.right+" "+combinedRegion.left);
  var height = combinedRegion.bottom - combinedRegion.top;
  var width = combinedRegion.right - combinedRegion.left;
  
  var top_height = y-combinedRegion.top-this.holeRadius;
  this.parts.top.init(top_height,
                      width,
                      combinedRegion.top-y,
                      combinedRegion.left-x);

  var bottom_height = combinedRegion.bottom-y-this.holeRadius;
  this.parts.bottom.init(bottom_height,
                         width,
                         this.holeRadius,
                         combinedRegion.left-x);
                         
  this.parts.left.init(height-top_height-bottom_height,
                       x-combinedRegion.left-this.holeRadius,
                       combinedRegion.top-y+top_height,
                       combinedRegion.left-x);

  this.parts.right.init(height-top_height-bottom_height,
                        combinedRegion.right-x-this.holeRadius,
                        combinedRegion.top-y+top_height,
                        this.holeRadius);
                        
  for (var i in this.parts) {
    this.parts[i].addFilling(x, y, clusters);
  }

};

PM.Proxy.prototype.clearFilling = function() {
  for (var i in this.parts) {
    this.parts[i].clearFilling();
  }
};

PM.Proxy.prototype.show = function() {
  for (var i in this.parts) {
    this.parts[i].show();
  }
};

PM.Proxy.prototype.hide = function() {
  for (var i in this.parts) {
    this.parts[i].hide();
  }
};

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

PM.DDProxy = function(id, groups) {
  PM.DDProxy.superclass.call(this, id, groups);
  this.promoteAllToHandle();
};
PM.extend(PM.DDProxy, PM.Draggable);

// private. Do not call this. Only to be run once when page loads.
PM.DDProxy._createDefaultProxy = function() {
  PM.DDProxy.defaultProxyEl = new PM.Proxy();
};
YAHOO.util.Event.addListener(window, "load", PM.DDProxy._createDefaultProxy);

PM.DDProxy.prototype.onMouseDown = function(e) {
  this.select();
  PM.Target.primeTargets(PM.Draggable.selected);
  PM.DDProxy.defaultProxyEl.prep(e, PM.Draggable.selected);
};

PM.DDProxy.prototype.onDragStart = function(e) {
  PM.DDProxy.defaultProxyEl.show();
  
  // enable autoscrolling
  var x = PM.Draggable.startPageX;
  var y = PM.Draggable.startPageY;
  PM.DDProxy.defaultProxyEl.moveTo(x, y);
  
  var proxyRegion = PM.DDProxy.defaultProxyEl.getRegion();
  logMessage(proxyRegion.top + "-" + y);
  this.setScrollBox(proxyRegion.top-y, proxyRegion.left-x,
                    proxyRegion.bottom-y, proxyRegion.right-x);
};

PM.DDProxy.prototype.onDrag = function(e) {
  var x = YAHOO.util.Event.getPageX(e); 
  var y = YAHOO.util.Event.getPageY(e);
  
  var proxy = PM.DDProxy.defaultProxyEl;
  proxy.moveTo(x, y);
};

PM.DDProxy.prototype.onDragEnd = function(e) {
  PM.DDProxy.defaultProxyEl.hide();
  PM.DDProxy.defaultProxyEl.clearFilling();
};

PM.DDProxy.prototype.onMouseUp = function(e) {
  PM.Draggable.unselectAll();
  PM.Target.unprimeAllTargets();
  delete this.scrollBox;
}
