var DragDrop = {
  dropTargets :  new Array() ,
  /* draged object */
	obj : null,
  dropCallback:  null ,
  dragCallback:  null ,
  junkMoveCallback:  null ,
  hightLightBorder : "2px solid blue" ,
  normalBorder :  "1px solid #3c78b5" ,

  /* make  the  node dragable,  the DOM node can be div ,  image ... */
	init : function(o, oRoot) {
    //call  DragDrop.start when  user  click  on  the DOM Node
		o.onmousedown	= DragDrop.start;

    //keep  track  of the  root node  of  the  dragable  object
		o.root = oRoot && oRoot != null ? oRoot : o ;

		if (isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = "0px";
		if (isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = "0px";

    //create  minX, maxX ,  minY, maxY for  the DOM node. NOT USED
		o.minX	=  null;
		o.minY	=  null;
		o.maxX	=  null;
		o.maxY	=  null;
	},

  //init  the component  that  user can drag the other component and drop into it
  addDropTarget: function(ele) {
    DragDrop.dropTargets[DragDrop.dropTargets.length] = ele ;
  },

  //start draging the  object ,  'this' is  the  DOM node,   e is  the  event  object
	start : function(e) {
		var o = DragDrop.obj = this;
    o.onmouseup =  null ;
		e = DragDrop.fixE(e);
		var y = parseInt(o.root.style.top);
		var x = parseInt(o.root.style.left);
		//o.root.onDragStart(x, y);

		o.lastMouseX	= e.clientX;
		o.lastMouseY	= e.clientY;

		if (o.minX != null)	o.minMouseX	= e.clientX - x + o.minX;
		if (o.maxX != null)	o.maxMouseX	= o.minMouseX + o.maxX - o.minX;

		if (o.minY != null)	o.minMouseY	= e.clientY - y + o.minY;
		if (o.maxY != null)	o.maxMouseY	= o.minMouseY + o.maxY - o.minY;

    //back up  the  zindex  value
    o.root.oldZindex = o.root.style.zIndex ;
    o.root.style.zIndex = 20 ;
    
    //back up the coordination of  the  draged  object
    o.root.oldLeft = o.root.style.left;
    o.root.oldTop = o.root.style.top  ;
    o.root.oldWidth = o.root.style.width  ;
    o.root.oldHeight = o.root.style.height  ;

    o.root.style.opacity = 0.5  ;
    o.root.style.filter  = "alpha(opacity=50)" ;

		document.onmousemove	= DragDrop.drag;
		document.onmouseup		= DragDrop.end;
		return false;
	},

	  drag : function(e) {
		e = DragDrop.fixE(e);
		var o = DragDrop.obj;

		var ey	= e.clientY;
		var ex	= e.clientX;
		var y = parseInt(o.root.style.top);
		var x = parseInt(o.root.style.left);
		var nx, ny;

		if (o.minX != null) ex =  Math.max(ex, o.minMouseX) ;
		if (o.maxX != null) ex =  Math.min(ex, o.maxMouseX) ;
		if (o.minY != null) ey =  Math.max(ey, o.minMouseY) ;
		if (o.maxY != null) ey =  Math.min(ey, o.maxMouseY) ;

		nx = x + ((ex - o.lastMouseX) * 1);
		ny = y + ((ey - o.lastMouseY) * 1);

		DragDrop.obj.root.style["left"] = nx + "px";
		DragDrop.obj.root.style["top"] = ny + "px";
		DragDrop.obj.lastMouseX	= ex;
		DragDrop.obj.lastMouseY	= ey;

    var  mousexInPage = DragDrop.findMouseXInPage(e) ;
    var  mouseyInPage = DragDrop.findMouseYInPage(e) ;
    if(DragDrop.dragCallback != null) {
      var target = DragDrop.findDropTarget(mousexInPage, mouseyInPage) ;
      DragDrop.dragCallback(o, target) ;
    }
		return false;
	},

	end : function(e) {
    e = DragDrop.fixE(e) ;
    var o =  DragDrop.obj ;
		document.onmousemove = null;
		document.onmouseup   = null;
		//o.root.onDragEnd(parseInt(DragDrop.obj.root.style.left), parseInt(DragDrop.obj.root.style.top));
		//var mousey	= e.clientY;
		//var mousex	= e.clientX;
    var  mousexInPage = DragDrop.findMouseXInPage(e) ;
    var  mouseyInPage = DragDrop.findMouseYInPage(e) ;
    var  foundTarget = DragDrop.findDropTarget(mousexInPage, mouseyInPage) ;
    if(foundTarget == null || DragDrop.isJunkMove(DragDrop.obj.root, foundTarget)) {
      if(DragDrop.junkMoveCallback != null) {
        DragDrop.junkMoveCallback(DragDrop.obj.root) ;
      }
      //Do  not  find the  target container , so  restore  the  postion  of the draged object
      o.root.style["left"] = o.root.oldLeft ;
      o.root.style["top"]  = o.root.oldTop;
    } else {
      if(DragDrop.dropCallback != null) {
        DragDrop.dropCallback (DragDrop.obj.root, foundTarget) ;
      }
    }
    o.root.style.opacity = 1.0 ;
    o.root.style.filter  = "" ;
    o.root.style.zIndex = o.root.oldZindex 
		DragDrop.obj = null;
	},
  
  findDropTarget : function(mousexInPage , mouseyInPage) {
    var  foundTarget = null ;
    for(i = 0; i < DragDrop.dropTargets.length; i++) {
      var ele =  DragDrop.dropTargets[i] ;  
      if(DragDrop.obj.root != ele &&  
         !DragDrop.isDescendant(DragDrop.obj.root, ele) &&
         DragDrop.isIn(mousexInPage,mouseyInPage, ele)) {
        if(foundTarget == null) {
          foundTarget  =  ele ;
        } else {
          if(DragDrop.isDescendant(foundTarget, ele)) {
            foundTarget = ele ;
          }
        } 
      }
    }
    return foundTarget ; 
  } ,

  //correct the event
	fixE : function(e) {
		if (typeof e == 'undefined') e = window.event;
		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
		return e;
	},

  //find the x position of an element in the page
  findPosX : function(obj) {
    var curleft = 0;
    if (obj.offsetParent) {
      while (obj.offsetParent) {
        curleft += obj.offsetLeft ;
        obj = obj.offsetParent;
      }
    } else if (obj.x) {
      curleft += obj.x;
    }
    return curleft;
  },

  //find the x position of an element in the page
  findPosY : function(obj) {
    var curtop = 0;
    if (obj.offsetParent) {
      while (obj.offsetParent) {
        curtop += obj.offsetTop ;
        obj = obj.offsetParent;
      }
    } else if (obj.y) {
      curtop += obj.y;
    }
    return curtop;
  },
  
  //find the x position of the mouse in the page
  findMouseXInPage : function(e) {
    var posx = -1;
    if (!e) var e = window.event;
    if (e.pageX || e.pageY) {
      posx = e.pageX;
    } else if (e.clientX || e.clientY) {
      posx = e.clientX + document.body.scrollLeft;
    }
    return posx ;
  },

  //find the y position of the mouse in the page
  findMouseYInPage : function(e) {
    var posy = -1;
    if (!e) var e = window.event;
    if (e.pageY) {
      posy = e.pageY;
    } else if (e.clientX || e.clientY) {
      //IE 6
      if (document.documentElement && document.documentElement.scrollTop) {
       posy = e.clientY + document.documentElement.scrollTop;
      } else {
       posy = e.clientY + document.body.scrollTop;
      }
    }
    return  posy ;
  },

  isDescendant : function(ancestor , child) {
    var parent = child.parentNode ;
    while(parent != null) {
      if(parent == ancestor)  return true ;
      parent = parent.parentNode ;
    }
    return false ;
  },
  
  isIn : function(x, y, component) {
    var componentLeft = DragDrop.findPosX(component) ;
    var componentRight = componentLeft + component.offsetWidth;
    var componentTop = DragDrop.findPosY(component) ;
    var componentBottom = componentTop + component.offsetHeight;
    isover = false ;
    if(componentLeft < x && x < componentRight) {
      if(componentTop < y && y < componentBottom) {
        isover = true ;
      }
    }
    return isover ;
  },

  isJunkMove : function(src, target) {
    if(target == null)  return  true ;
    var block = src ;
    while(block != null) {
      block = block.parentNode ;
      if(block == null) return  false ;
      var clazz  =  block.className ;
      if('customizable-block' == clazz)  break ;
    }
    if(block.id ==  target.id)  return true ;
    return false ;
  } ,
  
  fixPagePosition :  function(mousex , mousey) {
    if (self.pageYOffset) { // all except Explorer
      self.pageXOffset =  self.pageXOffset;
      if(mousey == 0) {
        self.pageYOffset = self.pageYOffset - 5;
      }
    } else if (document.documentElement && document.documentElement.scrollTop) {
      // Explorer 6 Strict
      x = document.documentElement.scrollLeft;
      if(mousey == 0) document.documentElement.scrollTop -= 5 ;
    } else if (document.body) { // all other Explorers 
      x = document.body.scrollLeft;
      if(mousey < 10)  {
        document.body.scrollTop -= 5 ;
        window.status ="ey = "  + mousey + ", scrolltop: " + self.pageYOffset;
      }
    }
  }
};

//Confguration of  the drad and drop  for the exoportal.  This method  find out all
//the portlet  and the container and add init them with the  DragDrop javascript
function findDragableNode(node) {
  var divBlock =  node.getElementsByTagName('div') ;
  for(i = 0; i <  divBlock.length; i++ ) {
    var child =  divBlock.item(i) ;
    var clazz = child.className ;
    if('dragable' == clazz) {
      var customizableBlock =  findCustomizableBlock(child) ;
      DragDrop.init(child, customizableBlock);
      DragDrop.addDropTarget(customizableBlock);
      DragDrop.addDropTarget(findInfoBarBlock(child));
    //  alert('x :' + customizableBlock.id) ;
    }
  }
}

function findCustomizableBlock(ele) {
  var block = ele ;
  while(block != null) {
    block = block.parentNode ;
    var clazz  =  block.className ;
    if('customizable-block' == clazz)  return block ;
  }
  return block ;
}

function findInfoBarBlock(ele) {
  var block = ele ;
  while(block != null) {
    block = block.parentNode ;
    var clazz  =  block.className ;
    if('info-bar' == clazz)  return block ;
  }
  return block ;
}

