/*
   Drag'n'drop script to move pop-ups made of the groups of related elements
   Victor Starenky, 2007
*/

var dom = document.getElementById;
var ns6 = document.getElementById && !document.all;
var ie4 = document.all;

var movablePopUps = [];

    // to be set by the calling script
var movablePopUpLayers = [];
var movablePopUpOptions = [];

    // top level objects we can move
var moveableObjects=new Array();

    //object currently moving
var mObj=null;


function newDiv(x, y, width, height, bg, id, opacity, zi, parentElement) {
  var nd = document.createElement('div');
  nd.setAttribute('id', id);
  nd.style.position = 'absolute';
  nd.style.left = x + 'px';
  nd.style.top = y + 'px';
  nd.style.width = width + 'px';
  nd.style.height = height + 'px';
  if ((null!=bg)&&(bg.length>0)) nd.style.backgroundColor = bg;
  nd.style.visibility = 'hidden';
  nd.style.padding = '0px';

  nd.style.opacity = opacity;
  if(dom&&ie4) {
    nd.style.filter = "alpha(opacity="+(opacity*100)+")";
  } else {
    nd.style.MozOpacity = opacity
  }

  nd.style.zIndex = zi;
  if(null!=parentElement) {
    parentElement.appendChild(nd);
  } else {
    document.body.appendChild(nd);
  }

  return nd;
}

function getZIndex(element) {
  var currStyle = null;
  if (element.currentStyle) {
    currStyle = element.currentStyle;
  } else if (document.defaultView && document.defaultView.getComputedStyle) {
    currStyle = document.defaultView.getComputedStyle(element,"");
  }
  var result;
  if (currStyle) {
    result = parseInt(currStyle.zIndex);
  } else {
    result = parseInt(element.style.zIndex);
  }
  return result;
}

function addShadow(popUpId) {
  var shadowOffset = 8;
  var shadowColor = "black";

  if((null==movablePopUpLayers[popUpId])||(movablePopUpLayers[popUpId].length<=0)) return;
  if(!(dom||ns6||ie4)) return;

  var mainLayerId = movablePopUpLayers[popUpId][0];

  var d = dom?document.getElementById(mainLayerId):(ie4?document.all(mainLayerId):null);
  if(null!=d) {
    // here we creating 3 DIVs for horizontal, vertical and corner shadows
    // we can't use one bid square because our main layer's top part is transparent and we'd get shadow where it shouldn't be
    // and using just 2 DIVs (for horizontal and vertical) somehow doesn't match up in the corner in IE only, while 3 work fine

    var dX = parseInt(0+d.offsetLeft);
    var dY = parseInt(0+d.offsetTop);
    var dW = parseInt(0+d.offsetWidth);
    var dH = parseInt(0+d.offsetHeight);
    var dZ = getZIndex(d);

    var shadowZIndex = dZ - 5;

//    var coverS = newDiv(dX, dY, dW, dH, "#FFFFFF", mainLayerId + "_cover",1,dZ - 1);
//    movablePopUpLayers[popUpId].push(coverS.id);

    var x = dX + dW;
    var y = dY + shadowOffset;
    var h = dH - shadowOffset;
    var w = shadowOffset;

    var shdwV = newDiv(x, y, w, h, shadowColor, mainLayerId + "_vshadow",.5,shadowZIndex,d.parentElement);
    movablePopUpLayers[popUpId].push(shdwV.id);

    var x = dX + shadowOffset;
    var y = dY + dH;
    var h = shadowOffset;
    var w = dW - shadowOffset;

    var shdwH = newDiv(x, y, w, h, shadowColor, mainLayerId + "_hshadow",.5,shadowZIndex,d.parentElement);
    movablePopUpLayers[popUpId].push(shdwH.id);

    var x = dX + dW;
    var y = dY + dH;
    var h = shadowOffset;
    var w = shadowOffset;

    var shdwC = newDiv(x, y, w, h, shadowColor, mainLayerId + "_cshadow",.5,shadowZIndex,d.parentElement);
    movablePopUpLayers[popUpId].push(shdwC.id);


  }

}

    // layers is array of element IDs with the first one being the master element
    // or just a single string id of one element
function MoveableObject(layerIds) {
  var layers = new Array();
  if("string" == typeof(layerIds)) layers[0] = layerIds;
  else layers = layerIds;

  if((dom||ns6||ie4)&&(layers.length>0)) {
    this.id = layers[0];
    var d = dom?document.getElementById(this.id):(ie4?document.all(this.id):null);
    if(null!=d) {
      d.style.zIndex = getZIndex(d);
      this.element = d;
      this.style = d.style;
      this.defaultX=parseInt(0+d.offsetLeft);
      this.defaultY=parseInt(0+d.offsetTop);
      this.initialX=this.defaultX;
      this.initialY=this.defaultY;
      this.sticky = new Array();
      for(var i=1; i<layers.length; i++) {
        if("string"==typeof(layers[i])) {
          // creating new related moveable object
          var sEl = new MoveableObject(layers[i]);
          if(null!=sEl.id) {
            this.sticky[sEl.id] = sEl;
          }
        } else {
          //object already pre-created
          if((null!=layers[i])&&(null!=layers[i].id)) {
            this.sticky[layers[i].id] = layers[i];
          }
        }
      }

      this.rememberPosition = function(mouseX,mouseY) {
        this.initialX=parseInt(0+this.element.offsetLeft);
        this.initialY=parseInt(0+this.element.offsetTop);
        this.mouseInitialX=mouseX;
        this.mouseInitialY=mouseY;
        for(var i in this.sticky) {
          this.sticky[i].rememberPosition(mouseX,mouseY);
        }
      }

      this.moveTo = function(mouseX,mouseY) {
        this.style.left = this.initialX - this.mouseInitialX + mouseX+"px";
        this.style.top = this.initialY - this.mouseInitialY + mouseY+"px";
        for(var i in this.sticky) {
          this.sticky[i].moveTo(mouseX,mouseY);
        }
      }

      this.resetPosition = function () {
        this.style.left = this.defaultX+"px";
        this.style.top = this.defaultY+"px";
        for(var i in this.sticky) {
          this.sticky[i].resetPosition();
        }
      }
        //placeholder
      this.onReset = function() {}

        //placeholder
      this.onMoveStart = function() {}

      this.reset = function () {
        this.hide();
        this.resetPosition();
        this.onReset();
      }

      this.show = function() {
        this.style.display='block';
        this.style.visibility='visible';
        for(var i in this.sticky) {
          this.sticky[i].show();
        }
      }

      this.hide = function() {
        for(var i in this.sticky) {
          this.sticky[i].hide();
        }
        this.style.display='none';
        this.style.visibility='hidden';
      }
    } else {
      this.id = null;
    }
  }
}

function initMovablePopUp(popUpId) {
  if(null==movablePopUpLayers[popUpId]) return;
  addShadow(popUpId);
  if(null==movablePopUps[popUpId]) movablePopUps[popUpId] = new MoveableObject(movablePopUpLayers[popUpId]);
  if(null!=movablePopUps[popUpId].id) {
    var initialWhite = false;
    if((null!=movablePopUpOptions[popUpId])&&((""+movablePopUpOptions[popUpId].indexOf("initialWhite"))>=0)) {
      initialWhite = true;
    }
    movablePopUps[popUpId].onMoveStart = function () {
      this.style.backgroundColor = "transparent";
    }
    movablePopUps[popUpId].onReset = function () {
       this.style.backgroundColor = (initialWhite?"#FFFFFF":"transparent");
    }
    moveableObjects[movablePopUps[popUpId].id] = movablePopUps[popUpId];
  }
}

function showMovablePopUp(popUpId) {
  if(null==movablePopUps[popUpId]) initMovablePopUp(popUpId);
  if((null==movablePopUps[popUpId])||(null==movablePopUps[popUpId].id)) return;

  movablePopUps[popUpId].show();
}

function hideMovablePopUp(popUpId) {
  if(null==movablePopUps[popUpId]) return;

  movablePopUps[popUpId].hide();
  movablePopUps[popUpId].reset();
}

  // find if the clicked object resides in something moveable. if so, return that moveable object.
function checkObject(obj) {
  var o = null;
  if(null!=obj) {
    if((null!=obj.id)&&(null!=moveableObjects[obj.id])) {
      o = moveableObjects[obj.id];
    } else {
      var parent = ie4?obj.parentElement:obj.parentNode;
      if(null!=parent) {
        o = checkObject(parent);
      }
    }
  }
  return o;
}

function mouseDown(e) {
  var element = ie4?event.srcElement:e.target;
  mObj =  checkObject(element);
  if(null!=mObj) {
     mObj.onMoveStart();
     mObj.rememberPosition(ie4?event.clientX:e.clientX, ie4?event.clientY:e.clientY);
     document.onmousemove=mouseMove;
     return false;
  }
}

function mouseMove(e) {
  if(null!=mObj) {
    mObj.moveTo(ie4?event.clientX:e.clientX, ie4?event.clientY:e.clientY);
  }
  return false;
}

function mouseUp() {
  mObj = null;
}

document.onmousedown = mouseDown;
document.onmouseup = mouseUp;
