
gekkoDragAndDrop = new Object();

gekkoDragAndDrop.zIndex = new Number(1000);
gekkoDragAndDrop.controls = new Array();

gekkoDragAndDrop.createContainer = function () {
	var container = document.createElement('DIV');
	container.className = 'gekkoBlockPlacer';
	return container;
}
gekkoDragAndDrop.setOption = function (control, option, value) {
	eval('gekkoDragAndDrop.controls['+control+'].'+option+' = '+value);
}
gekkoDragAndDrop.getOption = function (control, option) {
	eval ('var value = gekkoDragAndDrop.controls['+control+'].'+option);
	return value;
}

// control for configuring some drag options
gekkoDragAndDrop.newControl = function () {
	var control = new Object();
	control.containers = new Array();
	control.dragOnly = false;
	gekkoDragAndDrop.controls.push(control);
	return (gekkoDragAndDrop.controls.length-1);
}

// container where the user can drop the dragged item
gekkoDragAndDrop.addContainer = function (control, container) {

	if (this.getOption(control, 'showContainerId')) {
		var div = document.createElement('DIV');
		div.className = 'containerId';
		div.innerHTML = container.id;
		container.appendChild(div);
	}

	gekkoDragAndDrop.controls[control].containers.push(container);
}

// restores the object to its original position
gekkoDragAndDrop.staticPosition = function (object) {
	object.style.position = 'static';
	object.style.left = object.orig.style.left;
	object.style.top = object.orig.style.top;
	object.style.width = object.orig.style.width;
	object.style.height = object.orig.style.height;
}

// sets a item to be draggable
gekkoDragAndDrop.makeDraggable = function (control, object) {
	object.dragControlId = control;
	object.style.cursor = 'move';
	object.onmousedown = function(e) {
		if (e.which == 1) {
			var target = document.getEventTarget(e);
			while (target) {
				if (target.className == 'dragIgnore')
					return false;
				target = target.parentNode;
			}
			gekkoDragAndDrop.dragStart(this);
		}
	}
}
// 5392

// converts an item from relative position to absolute
gekkoDragAndDrop.absolutePosition = function (object) {
	object.style.zIndex = gekkoDragAndDrop.zIndex++;

	object.orig = new Object();
	object.orig.style = new Object();
	object.orig.style.left = object.style.left;
	object.orig.style.top = object.style.top;
	object.orig.style.width = object.style.width;
	object.orig.style.height = object.style.height;

	object.style.width = object.offsetWidth+'px';
	//object.style.height = object.offsetHeight+'px';

	object.style.position = 'absolute';
}

// returns true when a dragged item is inside a container
// both elements are required to have a .geom parameter that
// containts the element's geometry
gekkoDragAndDrop.isInside = function (object, container) {
	var top = parseInt(object.style.top);
	var left = parseInt(object.style.left);
	return (container.geom.top <= top+(object.geom.height/2) &&
		container.geom.left <= left+(object.geom.width/2) &&
		container.geom.left+container.geom.width >= left+(object.geom.width/2) &&
		container.geom.top+container.geom.height >= top+(object.geom.height/2));
}

// starts dragging an object
gekkoDragAndDrop.dragStart = function (object) {

	if (object.ondragstart)
		object.ondragstart(object);

	object.geom = document.getElementGeometry(object);

	var coords = new Object();
	coords.left = document.mouseX - object.geom.left;
	coords.top = document.mouseY - object.geom.top;

	gekkoDragAndDrop.absolutePosition(object);

	//object.style.opacity = '0.8';

	object.stopDragging = function (e) {

		//object.style.opacity = '1';

		if (gekkoDragAndDrop.getOption(object.dragControlId, 'dragOnly') == false) {
			var dropPlace = document.getElementById('dragPreview');
			if (dropPlace) {
				dropPlace.parentNode.insertBefore(object, dropPlace);
				dropPlace.parentNode.removeChild(dropPlace);
			}
			gekkoDragAndDrop.staticPosition(object);
		}

		if (object.ondragstop)
			object.ondragstop(e);

		document.delEventListener(document, 'mousemove', object.startDragging);
		document.delEventListener(document, 'mouseup', object.stopDragging);
	};

	object.startDragging = function (e) {

		if (object.ondrag)
			object.ondrag();

		object.style.left = (document.mouseX-coords.left)+'px';
		object.style.top = (document.mouseY-coords.top)+'px';

		if (gekkoDragAndDrop.getOption(object.dragControlId, 'dragOnly') == false) {
			for (var i = 0; i < gekkoDragAndDrop.controls[object.dragControlId].containers.length; i++) {
				var container = gekkoDragAndDrop.controls[object.dragControlId].containers[i];

				if (gekkoDragAndDrop.isInside(object, container)) {
					var dragPreview = document.getElementById('dragPreview');

					if (dragPreview) {
						dragPreview.parentNode.removeChild(dragPreview);
					} else {
						dragPreview = document.createElement('DIV');
						dragPreview.id = 'dragPreview';
					}

					if (container.brothers.length) {
						for (var j = 0; j < container.brothers.length; j++) {
							var brother = container.brothers[j];
							if (gekkoDragAndDrop.isInside(object, brother)) {
								// comparing halfs
								if (brother.geom.top+(brother.geom.height/2) >= parseInt(object.style.top)+(object.geom.height/2)) {
									container.insertBefore(dragPreview, brother);
								} else {
									// the final element
									if (j+1 == container.brothers.length)
										container.appendChild(dragPreview);
									else
										container.insertBefore(dragPreview, container.brothers[i+1]);
								}
								placed = true;
							}
						}
					} else {
						container.insertBefore(dragPreview, container.firstChild);
					}
				} else {
					container.style.border = container.origBorder;
				}
			}
		}

		document.cancelEvent(e);

		return false;
	}

	for (var i = 0; i < gekkoDragAndDrop.controls[object.dragControlId].containers.length; i++) {
		var container = gekkoDragAndDrop.controls[object.dragControlId].containers[i];
		container.geom = document.getElementGeometry(container);
		container.origBorder = container.style.border;
		container.brothers = new Array();
		for (var j = 0; j < container.childNodes.length; j++) {
			var brother = container.childNodes[j];
			if (brother.className == 'gekkoBlockPlacer') {
				brother.geom = document.getElementGeometry(brother);
				container.brothers.push(brother);
			}
		}
	}

	document.setEventListener(document, 'mousemove', object.startDragging);
	document.setEventListener(document, 'mouseup', object.stopDragging);

	gekkoDragAndDrop.object = object;
}