/* software_license
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
# 
# Creado por Fco. Javier Pérez Pacheco
# javi.pacheco@terra.es
# http://www.agali.org/javielinux/
*/

var TYPELAYER_NORMAL = 0;
var TYPELAYER_FIX = 1;
var TYPELAYER_WINDOW = 2;

var DRAG_MOUSE = 0;
var DRAG_TOPLEFT = 1;
var DRAG_TOPCENTER = 2;
var DRAG_TOPRIGHT = 3;
var DRAG_MIDDLELEFT = 4;
var DRAG_MIDDLECENTER = 5;
var DRAG_MIDDLERIGHT = 6;
var DRAG_BOTTOMLEFT = 7;
var DRAG_BOTTOMCENTER = 8;
var DRAG_BOTTOMRIGHT = 9;

var MOUSEOVER_TOPLEFT = 0;
var MOUSEOVER_TOPCENTER = 1;
var MOUSEOVER_TOPRIGHT = 2;
var MOUSEOVER_MIDDLELEFT = 3;
var MOUSEOVER_MIDDLERIGHT = 4;
var MOUSEOVER_BOTTOMLEFT = 5;
var MOUSEOVER_BOTTOMCENTER = 6;
var MOUSEOVER_BOTTOMRIGHT = 7;

/*****************************************
	CLASE Fix
*****************************************/

function Fix(name, x1, y1, x2, y2) {
	this.name = name;
	this.x1 = x1;
	this.y1 = y1;
	this.x2 = x2;
	this.y2 = y2;
	
	this.empty = true;
	
	this.setEmpty = setEmpty;
	this.getEmpty = getEmpty;
	
	this.setFixRect = setFixRect;
	this.verifyCollision = verifyCollision;
	this.getName = getName;
	this.getX1 = getX1;
	this.getX2 = getX2;
	this.getY1 = getY1;
	this.getY2 = getY2;
}

function setEmpty(e) {
    this.empty = e;
} 
function getEmpty() {
    return this.empty;
} 

function getName() {
    return this.name;
} 

function getX1() {
    return this.x1;
} 
function getX2() {
    return this.x2;
} 
function getY1() {
    return this.y1;
} 
function getY2() {
    return this.y2;
} 

function setFixRect(x1, y1, x2, y2) {
	this.x1 = x1;
	this.y1 = y1;
	this.x2 = x2;
	this.y2 = y2;
}

function verifyCollision(objMov) {
	if ( (this.getEmpty()) && (this.x2>pxToNumber(objMov.objectToMove.style.left)) && (this.y2>pxToNumber(objMov.objectToMove.style.top)) && ((pxToNumber(objMov.objectToMove.style.left)+objMov.getWidth())>this.x1) && ((pxToNumber(objMov.objectToMove.style.top)+objMov.getHeight())>this.y1)) {
		return true;
	}
	return false;
}

/*****************************************
	CLASE ObjectMovable
*****************************************/

function ObjectMovable(i) {
	//datos
    this.id = i;
    this.object = document.getElementById(i);
    this.objectToMove = document.getElementById(i);
	this.typeLayer = TYPELAYER_NORMAL;
	this.typeDrag = DRAG_MOUSE;
	this.zIndexOld = 0;
	this.oldX = 0;
	this.oldY = 0;
	this.dragX = 0;
	this.dragY = 0;
	this.cursor = "";
	this.opacity = 50;
	this.sepLayerMouseOver = 6;
	
    this.setId = setId;
    this.getId = getId;
    this.setDragX = setDragX;
    this.getDragX = getDragX;
    this.setDragY = setDragY;
    this.getDragY = getDragY;
	
	// control de movimiento Drag&Drop
	
	this.startDrag = startDrag;
	this.move = move;
	
	this.moveV = true;
	this.moveH = true;
    this.setMoveV = setMoveV;
    this.setMoveH = setMoveH;
	this.setMove = setMove;
	this.getMove = getMove;
	
	this.endDrag = endDrag;
	
	// control de movimiento MouseOver
	
	this.typeMouseOver = MOUSEOVER_TOPLEFT;
	
	this.isControlObjectOnMouseOver = false;
	
	this.objectOnMouseOver = null;
	
	this.controlObjectOnMouseOver = controlObjectOnMouseOver;
	
	this.startMoveMouseOver = startMoveMouseOver;
	this.moveMouseOver = moveMouseOver;
	this.endMoveMouseOver = endMoveMouseOver;
	
	this.setTypeMouseOver = setTypeMouseOver;
	this.getTypeMouseOver = getTypeMouseOver;
	
	// control de zona de movimiento de la capa
	
	this.moveRect = false;
	this.moveRectX1 = 0;
	this.moveRectY1 = 0;
	this.moveRectX2 = 0;
	this.moveRectY2 = 0;
	
	this.setMoveRect = setMoveRect;
	this.delMoveRect = delMoveRect;
	
	// control de zonas donde se puede fijar la capa
	
	this.fix = new Array();
	
	this.nFix = 0;
	this.nFixSelected = -1;
	
	this.addFixRect = addFixRect;
	this.delFixRect = delFixRect;
	this.setFixSelected = setFixSelected;
	this.setFixSelectedName = setFixSelectedName;
	this.getFixSelected = getFixSelected;
	this.getFixSelectedName = getFixSelectedName;
	
	this.getWidth = getWidth;
	this.getHeight = getHeight;
	
	this.setZIndex = setZIndex;
	this.show = show;
	this.hidden = hidden;
	
	this.setOpacity = setOpacity;
	this.getOpacity = getOpacity;
	
	this.setCursor = setCursor;
	this.getCursor = getCursor;
	
	this.setTypeLayer = setTypeLayer;
	this.getTypeLayer = getTypeLayer;
	
	this.setTypeDrag = setTypeDrag;
	this.getTypeDrag = getTypeDrag;
	
	this.setSepLayerMouseOver = setSepLayerMouseOver;
	this.getSepLayerMouseOver = getSepLayerMouseOver;
	
	this.setObjectToMove = setObjectToMove;
} 

function show() {
	this.objectToMove.style.visibility = "visible";
}
function hidden() {
	this.objectToMove.style.visibility = "hidden";
}

function setZIndex(z) {
	this.objectToMove.style.zIndex = z;
}

function setObjectToMove(o) {
    this.objectToMove = o;
} 

function setSepLayerMouseOver(s) {
    this.sepLayerMouseOver = s;
} 
function getSepLayerMouseOver() {
    return this.sepLayerMouseOver;
} 

function setTypeDrag(t) {
    this.typeDrag = t;
} 
function getTypeDrag() {
    return this.typeDrag;
} 

function setTypeLayer(t) {
    this.typeLayer = t;
} 
function getTypeLayer() {
    return this.typeLayer;
} 

function setTypeMouseOver(t) {
    this.typeMouseOver = t;
} 
function getTypeMouseOver() {
    return this.typeMouseOver;
} 

function setId(i) {
    this.id = i;
} 
function getId() {
    return this.id;
} 

function setOpacity(o) {
    this.opacity= o;
} 
function getOpacity() {
    return this.opacity;
} 

function setCursor(c) {
    this.cursor= c;
} 
function getCursor() {
    return this.cursor;
} 

function setDragX(x) {
    this.dragX= x;
} 
function getDragX() {
    return this.dragX;
} 

function setDragY(y) {
    this.dragY= y;
} 
function getDragY() {
    return this.dragY;
} 

function setMoveH(h) {
    this.moveH= h;
} 
function setMoveV(v) {
    this.moveV= v;
} 

function setMove(m) {
    this.moveV= m;
	this.moveH= m;
} 
function getMove() {
    if (this.moveV || this.moveH) {
		return true;
	} else {
		return false;
	}
} 

function getWidth() {
	if (navigator.appName == "Netscape")
	    return pxToNumber(this.objectToMove.style.width) + pxToNumber(this.objectToMove.style.paddingLeft) + pxToNumber(this.objectToMove.style.paddingRight);
	else 
	    return pxToNumber(this.objectToMove.style.width);
} 

function getHeight() {
	if (navigator.appName == "Netscape") 
	    return pxToNumber(this.objectToMove.style.height) + pxToNumber(this.objectToMove.style.paddingTop) + pxToNumber(this.objectToMove.style.paddingBottom);
	else
	    return pxToNumber(this.objectToMove.style.height) + pxToNumber(this.objectToMove.style.paddingBottom);
} 

function setMoveRect(x1, y1, x2, y2) {
	this.moveRect = true;
	this.moveRectX1 = x1;
	this.moveRectY1 = y1;
	this.moveRectX2 = x2;
	this.moveRectY2 = y2;
} 

function delMoveRect() {
	this.moveRect = false;
	this.moveRectX1 = 0;
	this.moveRectY1 = 0;
	this.moveRectX2 = 0;
	this.moveRectY2 = 0;
}

function addFixRect(name) {
	this.typeLayer = TYPELAYER_FIX;
	
	if (isFix(name)>=0) {
		this.fix[this.nFix] = name;
		this.nFix++;
	}
}

function delFixRect() {
	this.typeLayer = TYPELAYER_NORMAL;
	this.nFix = 0;
	this.nFixSelected = -1;
}

function setFixSelected(position) {
	if ( (this.nFixSelected>=0) && (this.nFixSelected<this.nFix) )
    	fixs[isFix(this.fix[this.nFixSelected])].setEmpty(true);

	this.nFixSelected = position;
	fixs[isFix(this.fix[this.nFixSelected])].setEmpty(false);
} 

function setFixSelectedName(name) {
	var position = isFix(name);
	if ( (this.nFixSelected>=0) && (this.nFixSelected<this.nFix) )
    	fixs[isFix(this.fix[this.nFixSelected])].setEmpty(true);

	this.nFixSelected = position;
	fixs[isFix(this.fix[this.nFixSelected])].setEmpty(false);
} 

function getFixSelected() {
    return this.nFixSelected;
} 

function getFixSelectedName() {
	if ( (this.nFixSelected>=0) && (this.nFixSelected<this.nFix) )
    	return fixs[isFix(this.fix[this.nFixSelected])].getName();
	else 
		return "";
} 

function controlObjectOnMouseOver(obj) {
	this.object.onmouseover = onMouseOver;
	this.object.onmouseout = onMouseOut;
	this.isControlObjectOnMouseOver = true;
	this.objectOnMouseOver = document.getElementById(obj);
}

function startMoveMouseOver(e) {
	if (this.objectOnMouseOver) {
		var x;
		var y;
		var w;
		var h;
		
		if (navigator.appName == "Netscape") {
	    	w = pxToNumber(this.objectOnMouseOver.style.width) + pxToNumber(this.objectOnMouseOver.style.paddingLeft) + pxToNumber(this.objectOnMouseOver.style.paddingRight);
			h = pxToNumber(this.objectOnMouseOver.style.height) + pxToNumber(this.objectOnMouseOver.style.paddingTop) + pxToNumber(this.objectOnMouseOver.style.paddingBottom);
		} else {
		    w = pxToNumber(this.objectOnMouseOver.style.width);
		    h = pxToNumber(this.objectOnMouseOver.style.height) + pxToNumber(this.objectOnMouseOver.style.paddingBottom);
		}
		
		var sep = this.sepLayerMouseOver;
	
		switch(this.typeMouseOver) {
			case MOUSEOVER_TOPLEFT:
				x = -w+sep;
				y = -h-sep;
			break;
			case MOUSEOVER_TOPCENTER:
				x = -w/2;
				y = -h-sep;
			break;
			case MOUSEOVER_TOPRIGHT:
				x = sep;
				y = -h;
			break;
			case MOUSEOVER_MIDDLELEFT:
				x = -w-sep;
				y = -h/4;
			break;
			case MOUSEOVER_MIDDLERIGHT:
				x = sep;
				y = -h/4;
			break;
			case MOUSEOVER_BOTTOMLEFT:
				x = -w;
				y = sep;
			break;
			case MOUSEOVER_BOTTOMCENTER:
				x = -w/2;
				y = sep;
			break;
			case MOUSEOVER_BOTTOMRIGHT:
				x = sep;
				y = sep;
			break;
		}
	
		this.setDragX (x);
	    this.setDragY (y);
		
		this.objectOnMouseOver.style.zIndex = 100;
	}
}

function endMoveMouseOver(e) {
	if (this.objectOnMouseOver) {
		this.objectOnMouseOver.style.visibility = "hidden";
	}
}

function moveMouseOver(e) {
	if (this.isControlObjectOnMouseOver) {
		this.objectOnMouseOver.style.left = String(this.getDragX() + getMouseX(e)) + "px";
		this.objectOnMouseOver.style.top = String(this.getDragY() + getMouseY(e)) + "px";
		this.objectOnMouseOver.style.visibility = "visible";
	}
}

function startDrag(e) {
	this.endMoveMouseOver(e);
	// guardamos los datos antiguos
	this.zIndexOld = this.objectToMove.style.zIndex;
	this.oldX = this.objectToMove.style.left;
	this.oldY = this.objectToMove.style.top;
	
	// establecemos donde empezará el drag X Y
	var x = 0;
	var y = 0;
	switch(this.typeDrag) {
		case DRAG_MOUSE:
			x = pxToNumber(this.objectToMove.style.left) - getMouseX(e);
			y = pxToNumber(this.objectToMove.style.top) - getMouseY(e);
		break;
		case DRAG_TOPLEFT:
			x = 0;
			y = 0;
		break;
		case DRAG_TOPCENTER:
			x = -this.getWidth()/2;
			y = 0;
		break;
		case DRAG_TOPRIGHT:
			x = -this.getWidth();
			y = 0;
		break;
		case DRAG_MIDDLELEFT:
			x = 0;
			y = -this.getHeight()/2;
		break;
		case DRAG_MIDDLECENTER:
			x = -this.getWidth()/2;
			y = -this.getHeight()/2;
		break;
		case DRAG_MIDDLERIGHT:
			x = -this.getWidth();
			y = -this.getHeight()/2;
		break;
		case DRAG_BOTTOMLEFT:
			x = 0;
			y = -this.getHeight();
		break;
		case DRAG_BOTTOMCENTER:
			x = -this.getWidth()/2;
			y = -this.getHeight();
		break;
		case DRAG_BOTTOMRIGHT:
			x = -this.getWidth();
			y = -this.getHeight();
		break;
	}
	
    this.setDragX (x);
    this.setDragY (y);
	
	this.objectToMove.style.zIndex = 100;
}

function move(e) {
	if (this.cursor != "") {
		this.objectToMove.style.cursor = this.cursor; 	
	}
	this.objectToMove.style.opacity = "." + (this.opacity/10); 
	this.objectToMove.style.filter = "alpha(opacity=" + this.opacity + ")"; 

	if (this.moveH) { 
		if (!this.moveRect) {
			this.objectToMove.style.left = String(this.getDragX() + getMouseX(e) ) + "px";
		} else {
			var mX = getMouseX(e);
			if ( (mX>this.moveRectX1-this.getDragX()) && (mX<this.moveRectX2-this.getDragX()-this.getWidth()) ) {
				this.objectToMove.style.left = String(this.getDragX() + mX ) + "px";
			} else {
				if (mX<this.moveRectX1-this.getDragX()) {
					this.objectToMove.style.left = this.moveRectX1;
				}
				if (mX>this.moveRectX2-this.getDragX()-this.getWidth()) {
					this.objectToMove.style.left = this.moveRectX2-this.getWidth();
				}
			}
		}
	}
    if (this.moveV) {
		if (!this.moveRect) {
			this.objectToMove.style.top = String(this.getDragY() + getMouseY(e) ) + "px";
		} else {
			var mY = getMouseY(e);
			if ( (mY>this.moveRectY1-this.getDragY()) && (mY<this.moveRectY2-this.getDragY()-this.getHeight()) ) {
				this.objectToMove.style.top = String(this.getDragY() + mY ) + "px";
			} else {
				if (mY<this.moveRectY1-this.getDragY()) {
					this.objectToMove.style.top = this.moveRectY1;
				}
				if (mY>this.moveRectY2-this.getDragY()-this.getHeight()) {
					this.objectToMove.style.top = this.moveRectY2-this.getHeight();
				}
			}
		}
	}
}

function endDrag() {
	this.objectToMove.style.zIndex = this.zIndexOld;
	if (this.cursor != "") {
		this.objectToMove.style.cursor = ""; 	
	}
	this.objectToMove.style.opacity = "0.9"; 
	this.objectToMove.style.filter = "alpha(opacity=90)"; 
	
	// en el caso que el layer sea de tipo FIX lo fijamos en el lugar
	// si ha colisionado con el sino lo devolvemos a su lugar original
	if (this.typeLayer == TYPELAYER_FIX) {
		var posOld = true;
		for (var i=0; i<this.nFix; i++) {
			if (fixs[isFix(this.fix[i])].verifyCollision(this)) {
				move2Position(this.id,fixs[isFix(this.fix[i])].getX1(), fixs[isFix(this.fix[i])].getY1(), 2);
				this.setFixSelected(i);
				posOld = false;
				break;
			}
		}
		if (posOld) {
			move2Position(this.id, pxToNumber(this.oldX), pxToNumber(this.oldY), 3);
		}
	}
}

/*****************************************
	DRAG&DROP
*****************************************/

var currentObjectMovable = null;
var currentObjectMouseOver = null;
var objectsMovables = new Array();
var nObjectsMovables = 0;
var fixs = new Array();
var nFixs = 0;

function getObject(id) {
	for (var i=0; i<nObjectsMovables; i++) {
		if (objectsMovables[i].id == id) {
			return objectsMovables[i];
		}
	}
	return null;
}

function isObjectMovable(id) {
	for (var i=0; i<nObjectsMovables; i++) {
		if (objectsMovables[i].getTypeLayer() == TYPELAYER_WINDOW) {
			if (objectsMovables[i].id + "_title" == id) {
				return i;
			}
		} else {
			if (objectsMovables[i].id == id) {
				return i;
			}
		}
	}
	if (id!="") {
		if (document.getElementById(id).parentNode) {
			return isObjectMovable(document.getElementById(id).parentNode.id);
		}
	}
	return -1;

}

function registerObjectMovable(obj) {
	objectsMovables[nObjectsMovables] = obj;
	nObjectsMovables++;
}

function registerFix(name, x1, y1, w, h) {
	var x2 = x1 + w;
	var y2 = y1 + h;
	var createFix = true;
	for (var i=0; i<nFixs; i++) {
		if (fixs[i].getName() == name) {
			createFix = false;
		}
	}
	if (createFix) {
		var obj = new Fix(name, x1, y1, x2, y2);
		fixs[nFixs] = obj;
		nFixs++;
	} else {
		alert(name + " ya está usado como nombre en objetos fix");
	}
}

function isFix(name) {
	for (var i=0; i<nFixs; i++) {
		if (fixs[i].getName() == name) {
			return i;
		}
	}
	return -1;
}

function isValueByRound(value, value2Round) {
	if ( (value>value2Round-5) && (value<value2Round+5) ) {
		return true;
	}
	return false;
}

function move2Position(name, x, y, factor) {
	getObject(name).objectToMove.style.left = pxToNumber(getObject(name).objectToMove.style.left) + (x-pxToNumber(getObject(name).objectToMove.style.left))/factor;
	getObject(name).objectToMove.style.top = pxToNumber(getObject(name).objectToMove.style.top) + (y-pxToNumber(getObject(name).objectToMove.style.top))/factor;

	if ( (!isValueByRound (pxToNumber(getObject(name).objectToMove.style.left), x)) || 
		(!isValueByRound (pxToNumber(getObject(name).objectToMove.style.top), y)) ) {
		setTimeout ('move2Position("' + name + '", ' + x + ',' +  y + ',' +  factor + ')', 30); 
	} else {
		getObject(name).objectToMove.style.left = x;
		getObject(name).objectToMove.style.top = y;
	}
	
}

function registerMouse() {
	document.onmousedown = onMouseDown;
	document.onmousemove = onMouseMove;
	document.onmouseup = onMouseUp;
}

function onMouseDown(e) {
	if (currentObjectMouseOver!=null) {
		currentObjectMouseOver.endMoveMouseOver(e);
		currentObjectMouseOver = null;
	}
	
	var object = getMouseObject(e);
	var nObj = isObjectMovable(object.id);
	if (nObj!=-1) {
		currentObjectMovable = objectsMovables[nObj];
		currentObjectMovable.startDrag(e);
		return(false);
	}
}

function onMouseMove(e) {
	if (currentObjectMovable) {
		currentObjectMovable.move(e);
		return(false);
	}
	if (currentObjectMouseOver) {
		currentObjectMouseOver.moveMouseOver(e);
		return(false);
	}

}

function onMouseUp(e) {
	if (currentObjectMovable!=null) {
		currentObjectMovable.endDrag();
		currentObjectMovable = null;
	}
}

function onMouseOver(e) {
	if (currentObjectMovable==null) {
		var object = getMouseObject(e);
		var nObj = isObjectMovable(object.id);
		if (nObj!=-1) {
			currentObjectMouseOver = objectsMovables[nObj];
			currentObjectMouseOver.startMoveMouseOver(e);
			return(false);
		}
	}
}

function onMouseOut(e) {
	if (currentObjectMouseOver!=null) {
		currentObjectMouseOver.endMoveMouseOver(e);
		currentObjectMouseOver = null;
	}
}

function getMouseObject(e) {
	return(e? e.target: window.event.srcElement);
}
function getMouseX(e) {
	return(e? e.clientX: window.event.clientX);
}
function getMouseY(e) {
	return(e? e.clientY: window.event.clientY);
}
function pxToNumber(s) {
	return( Number( s.substring(0, s.length - 2) ) );
}

