
if (typeof MET == "undefined" || !MET) {
var MET = {};
}
if (typeof MET.DND == "undefined") {
MET.DND = {};
}
MET.DND.Manager = function() {
this.PointerX = 0;
this.PointerY = 0;
this.RelativePointerX = 0;
this.RelativePointerY = 0;
this.OffsetPointerX = 0;
this.OffsetPointerY = 0;
this.Containers = new Array();
this.BlockInMovement = null;
this.DestinationSlot = null;
this.preDragAction  = function (e) { return true; };
this.postDragAction = function (e) { return true; };
this.BlockDragDivContent = "[MOVER]";
this.activeDragDiv       = true;
this.BlockButtonUpDivContent   = "^";
this.BlockButtonDownDivContent = "v";
this.activeMovementButtons     = false;
this.SlotClassInactive = "slot";
this.SlotClassActive   = "slot_drag";
this.getMousePosition = function (e) {
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
this.PointerX = e.pageX;
this.PointerY = e.pageY;
} else if (e.clientX || e.clientY) {
this.PointerX = e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
this.PointerY = e.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
}
this.RelativePointerX = e.clientX;
this.RelativePointerY = e.clientY;
}
this.clearSelection = function () {
try {
if (isOpera || isSafari) {
if(window["getSelection"]) {
if(isSafari){
window.getSelection().collapse();
} else {
window.getSelection().removeAllRanges();
}
} else if((document.selection)&&(document.selection.clear)) {
document.selection.clear();
} else if(document.selection) {
document.selection.empty;;
}
}
return true;
} catch(e) {
}
};
this.doScroll = function() {
var availableY = 0;
if (document.documentElement.clientHeight) {
availableY = document.documentElement.clientHeight;
} else if (document.body.clientHeight) {
availableY = document.body.clientHeight;
}
var distanceToDoScroll = parseInt(availableY * 0.1);
if ( (this.RelativePointerY < distanceToDoScroll) && ((document.documentElement.scrollTop || document.body.scrollTop) > 0) ) {
if (document.documentElement.scrollTop) {
document.documentElement.scrollTop -= 20;
} else if (document.body.scrollTop) {
document.body.scrollTop -= 20;
}
} else if ( ((availableY - this.RelativePointerY) < distanceToDoScroll) && 
(
((document.documentElement.scrollTop + availableY) < document.body.offsetHeight ) || 
((document.documentElement.scrollTop + availableY) < document.documentElement.offsetHeight)) 
) {
if (typeof document.documentElement.scrollTop != "undefined") {
document.documentElement.scrollTop += 20;
}
if (typeof document.body.scrollTop != "undefined" && !isOpera) {
document.body.scrollTop += 20;
}
}
};
this.moveBlock = function (block) {
block.Div.style.left = (this.PointerX - this.OffsetPointerX) + "px";
block.Div.style.top  = (this.PointerY - this.OffsetPointerY) + "px";
this.doScroll();
this.clearSelection();
};
this.getNearestElement = function(pointerX, pointerY, elementsArray) {
var distX = 0;
var distY = 0;
var dist  = 0;
var minDist = 99999999;
var nElement = null;
for (var i = 0; i != elementsArray.length; i++) {
var arrayPosElement = METUtils_calcAbsPosition(elementsArray[i].Div);
var pLeft = arrayPosElement[0];
var pTop  = arrayPosElement[1];
if ((pTop < pointerY) &&
((pTop + elementsArray[i].Div.offsetHeight) > pointerY) &&
(pLeft < pointerX) &&
((pLeft + elementsArray[i].Div.offsetWidth) > pointerX)) {
return elementsArray[i];
} else {
distY = Math.abs(pTop - pointerY);
if (Math.abs(pTop + elementsArray[i].Div.offsetHeight - pointerY) < distY) {
distY = Math.abs(pTop + elementsArray[i].Div.offsetHeight - pointerY);
}

distX = Math.abs(pLeft - pointerX);
if (Math.abs(pLeft + elementsArray[i].Div.offsetWidth - pointerX) < distX) {
distX = Math.abs(pLeft + elementsArray[i].Div.offsetWidth - pointerX);
}

dist = Math.abs(Math.sqrt((distX*distX) + (distY*distY)));
if (dist < minDist) {
minDist = dist;
nElement = elementsArray[i];
}
}
}
return nElement;
}
this.getNearestContainer = function () {
return this.getNearestElement (this.PointerX, this.PointerY, this.Containers);
}
this.getDestinationSlot = function (block) {
var dropContainer = this.getNearestContainer();
if (dropContainer == null) {
dropContainer = block.parentContainer;
}
var dropSlot = dropContainer.getDropSlot(this.PointerX, this.PointerY);
if (dropSlot != this.DestinationSlot) {
if (this.DestinationSlot) {
this.DestinationSlot.Div.className = this.DestinationSlot.classInactive;
}
dropSlot.Div.className = dropSlot.classActive;
}
return(dropSlot);
};
this.manageLayerMovement = function(e) {
if (this.BlockInMovement) {
if (!this.BlockInMovement.inMovement) {
this.OffsetPointerX = 
this.PointerX - parseInt(this.BlockInMovement.Div.style.left);
this.OffsetPointerY = 
this.PointerY - parseInt(this.BlockInMovement.Div.style.top);
this.BlockInMovement.inMovement = true;
} else {
this.getMousePosition(e);
}
this.moveBlock(this.BlockInMovement);
this.DestinationSlot = this.getDestinationSlot(this.BlockInMovement);
}
if (!e) e = window.event;
if (isIE && (typeof e.button != "undefined") && e.button == 0) {
this.endLayerMovement(e);
}
if( typeof e.preventDefault == 'function' && e.cancelable ) { 
e.preventDefault(); 
} else { 
this.clearSelection();
}
if (e.stopPropagation) {
e.stopPropagation = true;
} else {
e.cancelBubble = true;
} 
};    
this.endLayerMovement = function (e) {
if (this.BlockInMovement) {
if (!this.DestinationSlot) {
this.DestinationSlot = this.getDestinationSlot(this.BlockInMovement);
}
var bDiv = this.BlockInMovement.Div;
if (isOpera) { bDiv.style.visibility = "hidden"; }
bDiv.style.zIndex = 1;
bDiv.style.position = "relative";
bDiv.style.top = "";
bDiv.style.left = "";
bDiv.style.width = "";
bDiv.style.height = "";
if (isOpera) { bDiv.style.visibility = "visible"; }
var container = this.DestinationSlot.parentContainer;
container.Div.insertBefore(bDiv, this.DestinationSlot.Div);
var newSlot = container.addSlot('', bDiv);
container.Blocks.push(this.BlockInMovement);
this.BlockInMovement.Div.style.cssFloat = container.floatValue;
this.DestinationSlot.Div.className = this.DestinationSlot.classInactive;
this.BlockInMovement.parentContainer = container;
this.BlockInMovement.inMovement = false;
this.BlockInMovement = null;
this.DestinationSlot = null;
}
if (!e) e = window.event;
document.onmouseup = null;
document.onmousemove = null;
document.onmousedown = null;
if (e.stopPropagation) {
e.stopPropagation = true;
} else {
e.cancelBubble = true;
} 
if (isGecko) { document.body.style.MozUserSelect = "text"; }
if (isSafari) { document.body.style.KhtmlUserSelect = "text"; }
if (isIE) { document.body.unselectable = "off"; }
document.body.style.userSelect = "text";
this.postDragAction(e);
};
this.addContainer = function (idContainer, floatValue) {
if (!document.getElementById(idContainer)) {
alert("No existe el elemento " + idContainer);
return(0);
}
var divContainer = document.getElementById(idContainer);
if (divContainer.nodeName != "DIV") {
alert("El elemento " + idContainer + " no tiene el tipo correcto (DIV)");
return(0);        
}
var newContainer = new MET.DND.Container(divContainer, this, floatValue);
if (newContainer) {
this.Containers.push(newContainer);
}
};
this.getBlocksPositions = function () {
var arrayPositions = Array();
for (var i = 0; i != this.Containers.length; i++) {
arrayPositions[this.Containers[i].Div.id] = Array();
for (var j = 1; j != this.Containers[i].Div.childNodes.length; j = j + 2) {
arrayPositions[this.Containers[i].Div.id].push(this.Containers[i].Div.childNodes[j].lastChild.id);
}
}
return(arrayPositions);
}
this.setPreDragAction   = function (action) { 
this.preDragAction  = action;
};
this.setPostDragAction  = function (action) { 
this.postDragAction = action;
};
this.setBlockDragDivContent = function (htmlCode) {
this.BlockDragDivContent = htmlCode;
}
this.setSlotClassInactive   = function (className) {
this.SlotClassInactive = className;
}
this.setSlotClassActive   = function (className) {
this.SlotClassActive = className;
}
this.activateMovementButtons = function () {
for (var i = 0; i != this.Containers.length; i++) {
for (var j = 0; j != this.Containers[i].Blocks.length; j++) {
this.Containers[i].Blocks[j].addMovementButtons();
}
}
}
this.setActiveDragDiv = function (status) {
this.activeDragDiv = status;
}
this.setActiveMovementButtons = function (status) {
this.activeMovementButtons = status;
}
}
MET.DND.Container = function (divContainer, DNDobj, floatValue) {
this.DND = DNDobj;
this.Div = divContainer;
this.floatValue = floatValue || "none";
this.Slots = new Array();
this.Blocks = new Array();
this.idDragElement = "";
this.addSlot = function (slotId, insertBeforeThisDiv) {
var newSlot = new MET.DND.Slot(this, slotId);
if (newSlot) {
this.Slots.push(newSlot);
if (insertBeforeThisDiv) {
this.Div.insertBefore(newSlot.Div, insertBeforeThisDiv);
} else {
this.Div.appendChild(newSlot.Div);
}
}
};
this.delSlot = function (slotDiv) {
var newIdx = 0;
for (var i = 0; i != this.Slots.length; i++) {
if (this.Slots[i].Div != slotDiv) {
this.Slots[newIdx] = this.Slots[i];
newIdx++;
}
}
this.Slots.pop();
this.Div.removeChild(slotDiv);
};
this.addBlock = function (blockDiv, insertBeforeThisDiv) {
var newBlock = new MET.DND.Block(blockDiv, this.DND, this);
if (newBlock) {
this.Blocks.push(newBlock);
if (insertBeforeThisDiv) {
this.Div.insertBefore(newBlock.Div, insertBeforeThisDiv);
} else {
this.Div.appendChild(newBlock.Div);
}
}
}
this.removeBlock = function (block) {
var newIdx = 0;
for (var i = 0; i != this.Blocks.length; i++) {
if (this.Blocks[i] != block) {
this.Blocks[newIdx] = this.Blocks[i];
newIdx++;
}
}
this.Blocks.pop();
}
this.removeBlockByDiv = function (blockDiv) {
var newIdx = 0;
for (var i = 0; i != this.Blocks.length; i++) {
if (this.Blocks[i].Div != blockDiv) {
this.Blocks[newIdx] = this.Blocks[i];
newIdx++;
}
}
this.Blocks.pop();
}
this.getDropSlot = function (pointerX, pointerY) {
return this.DND.getNearestElement (pointerX, pointerY, this.Slots);
}
this.setDragElement = function(idDragElement) {
this.idDragElement = idDragElement;
for (var i = 0; i != this.Blocks.length; i++) {
var err = this.Blocks[i].addDragElement(this.Blocks[i], this.Blocks[i].Div);
if (!err) {
}
}
}
for (var i = divContainer.childNodes.length-1; i >= 0; i--) {
if (divContainer.childNodes[i].nodeName != "DIV") {
divContainer.removeChild(divContainer.childNodes[i]);
}
}    
var slotsCount = 0;
for (var i = 0; i != this.Div.childNodes.length; i=i+2) {
block = this.Div.childNodes[i];
if (this.Div.childNodes[i+1]) {
this.addBlock(block, this.Div.childNodes[i+1]);
} else {
this.addBlock(block);
}
this.addSlot(slotsCount, this.Div.childNodes[i]);
slotsCount++;
}
this.addSlot(slotsCount);
}
MET.DND.Slot = function (container, slotId) {
this.Div = document.createElement("DIV");
this.parentContainer = container;
if (!slotId) {
var now = new Date();
slotId = now.getTime();
}
this.classInactive = this.parentContainer.DND.SlotClassInactive;
this.classActive   = this.parentContainer.DND.SlotClassActive;
this.Div.id = "s_" + slotId;
this.Div.className = this.classInactive;
this.Div.style.cssFloat = this.parentContainer.floatValue;
}
MET.DND.Block = function (blockDiv, DNDobj, container) {
this.Div = document.createElement("DIV");
this.DND = DNDobj;
this.parentContainer = container;
this.inMovement = false;
this.startDrag = function (e) {
this.block.DND.preDragAction(e);
if (this.block.DND.BlockInMovement) {
this.block.DND.endLayerMovement(e);
}
this.block.parentContainer.delSlot(this.block.Div.nextSibling);
if (isGecko) { document.body.style.MozUserSelect = "none"; }
if (isSafari) { document.body.style.KhtmlUserSelect = "none"; }
if (isIE) { document.body.unselectable = "on"; }
document.body.style.userSelect = "none";
this.block.Div.style.position = "absolute";
var arrayBlockAbsPosition = METUtils_calcAbsPosition(this.block.Div);
this.block.Div.style.left = arrayBlockAbsPosition[0] + "px";
this.block.Div.style.top = arrayBlockAbsPosition[1] + "px";
this.block.Div.style.width = this.block.Div.offsetWidth + "px";
this.block.Div.style.height = this.block.Div.offsetHeight + "px";
this.block.Div.style.zIndex = 100;
this.block.DND.BlockInMovement = this.block;
this.block.DND.getMousePosition(e);
if (this.block.DND.PointerX > (arrayBlockAbsPosition[0] + this.block.Div.offsetWidth)) {
this.block.Div.style.left = (this.block.DND.PointerX-this.block.Div.offsetWidth+10) + "px";
}
if (this.block.DND.PointerY < arrayBlockAbsPosition[1]) {
this.block.Div.style.top = (this.block.DND.PointerY-10) + "px";
}
this.block.DND.DestinationSlot = this.block.DND.getDestinationSlot(this.block);
document.body.appendChild(this.block.Div);
this.block.parentContainer.removeBlock(this.block);
document.DND = this.block.DND;
document.onmousemove = function (e) { 
document.DND.manageLayerMovement(e);
};
document.onmouseup   = function (e) { 
document.DND.endLayerMovement(e);
};
document.onmousedown = function (e) { 
if( typeof e.preventDefault == 'function' && e.cancelable ) { 
e.preventDefault(); 
}
if (e.stopPropagation) {
e.stopPropagation = true;
} else {
e.cancelBubble = true;
}
}
}
this.moveUp = function () {
if (this.block.parentContainer.Div.childNodes.length > 3) {
var position = 1;
for (var i = 1; i != this.block.parentContainer.Div.childNodes.length; i = i + 2) {
if ((this.block.parentContainer.Div.childNodes[i].id == this.block.Div.id) && (position > 1)) {
var blockUp = this.block.parentContainer.Div.childNodes[i];
this.block.parentContainer.Div.replaceChild(this.block.parentContainer.Div.childNodes[i-2], this.block.parentContainer.Div.childNodes[i]);
this.block.parentContainer.Div.insertBefore(blockUp, this.block.parentContainer.Div.childNodes[i-2]);
break;
}
position++;
}
}
}
this.moveDown = function () {
if (this.block.parentContainer.Div.childNodes.length > 3) {
var position = 1;
for (var i = 1; i != this.block.parentContainer.Div.childNodes.length; i = i + 2) {
if ((this.block.parentContainer.Div.childNodes[i].id == this.block.Div.id) && (i < (this.block.parentContainer.Div.childNodes.length-2))) {
var blockDown = this.block.parentContainer.Div.childNodes[i];
this.block.parentContainer.Div.replaceChild(this.block.parentContainer.Div.childNodes[i+2], this.block.parentContainer.Div.childNodes[i]);
this.block.parentContainer.Div.insertBefore(blockDown, this.block.parentContainer.Div.childNodes[i+2]);
break;
}
position++;
}
}
}
this.addMovementButtons = function () {
var buttonUpDiv   = document.createElement("DIV");
var buttonDownDiv = document.createElement("DIV");
buttonUpDiv.id   = this.Div.id + "_buttonup";
buttonDownDiv.id = this.Div.id + "_buttondown";
buttonUpDiv.block   = this;
buttonDownDiv.block = this;
buttonUpDiv.innerHTML   = this.DND.BlockButtonUpDivContent;
buttonDownDiv.innerHTML = this.DND.BlockButtonDownDivContent;
buttonUpDiv.onmousedown = this.moveUp;
buttonDownDiv.onmousedown = this.moveDown;
this.Div.insertBefore(buttonUpDiv, this.Div.lastChild);
this.Div.insertBefore(buttonDownDiv, this.Div.lastChild);
}
this.addDragElement = function(block, obj) {
for (var i = 0; i != obj.childNodes.length; i++) {
if (obj.childNodes[i].id == this.parentContainer.idDragElement) {
obj.childNodes[i].block = this;
obj.childNodes[i].onmousedown = this.startDrag;
return(true);
} else {
if (obj.childNodes[i].hasChildNodes()) {
var err = block.addDragElement(block, obj.childNodes[i]);
if (err) {
return(true);
}
}
}
}
return(false);
}
if (blockDiv.id) {
this.Div.id = "b_" + blockDiv.id;
} else {
var now = new Date();
this.Div.id = "b_" + now.getTime() + this.parentContainer.Blocks.length;
}
this.Div.style.cssFloat = this.parentContainer.floatValue;
if (this.DND.activeDragDiv) {
var dragDiv = document.createElement("DIV");
dragDiv.id = this.Div.id + "_drag";
dragDiv.block = this;
dragDiv.innerHTML = this.DND.BlockDragDivContent;
dragDiv.onmousedown = this.startDrag;
this.Div.appendChild(dragDiv);
}
this.Div.appendChild(blockDiv);
if (this.parentContainer.idDragElement != "") {
this.addDragElement (this, this.Div)
}
if (this.DND.activeMovementButtons) {
this.addMovementButtons();
}
} 

