function DragDropList () {
	this.lists = new Array ();
}

DragDropList.prototype.addList = function (domNode) {

	DragDropList.findCentre (domNode);

	var item = domNode.firstChild;
	while (item) {
		if (item.nodeType == 1) {
			item.dragDropList = this;
			new DraggableObject (item);
		}
		item = item.nextSibling;
	}

	this.lists.push (domNode);
}

DragDropList.prototype.findListClosestTo = function (x, y) {
	if (this.lists.length == 1) {
		return this.lists [0];
	}

	var closestList, closestDistance;
	for (var i = 0; i < this.lists.length; i++) {

		var list = this.lists [i];
		var distX = Math.round (x - list.centreX);
		var distY = Math.round (y - list.centreY);
		var distH = distX * distX + distY * distY;

		if (!closestList || distH < closestDistance) {
			closestList = list;
			closestDistance = distH;
		}
	}
	return closestList;
}

DragDropList.findCentre = function (domNode) {
	var left = 0, top = 0, parent = domNode;
	while (parent) {
		left += parent.offsetLeft;
		top += parent.offsetTop;
		parent = parent.offsetParent;
	}

	domNode.totalOffsetLeft = left;
	domNode.totalOffsetTop = top;
	domNode.centreX = left + domNode.offsetWidth / 2;
	domNode.centreY = top + domNode.offsetHeight / 2;
}

DraggableObject.prototype.customMouseMove = function (event) {

	if (this.domNode.className != 'dragging') {
		this.blank = this.domNode.cloneNode (true);
		this.blank.className = 'blank';
		this.domNode.parentNode.insertBefore (this.blank, this.domNode);

		this.domNode.className = 'dragging';
	}

	var mouseLeft = DraggableObject.getLeft (event);
	var mouseTop = DraggableObject.getTop (event);
	var left = mouseLeft - this.dragStartX;
	var top = mouseTop - this.dragStartY;

	this.domNode.style.left = left + 'px';
	this.domNode.style.top = top + 'px';

	var dragDropList = this.domNode.dragDropList;
	var closestList = dragDropList.findListClosestTo (mouseLeft, mouseTop);

	top -= this.domNode.offsetHeight / 2;

	var itemsInOrder = closestList.childNodes;
	for (var i = 0; i < itemsInOrder.length; i++) {
		var item = itemsInOrder [i];

 		if (item == this.blank) {
			top += this.domNode.offsetHeight;
		} else if (item != this.domNode && top < item.offsetTop + (navigator.appName == 'Microsoft Internet Explorer' ? item.parentNode.totalOffsetTop : 0)) {
			closestList.insertBefore (this.blank, item);
			return;
		}
	}
	closestList.insertBefore (this.blank, null);

	for (var i = 0; i < dragDropList.lists.length; i++) {
		DragDropList.findCentre (dragDropList.lists [i]);
	}
}

DraggableObject.prototype.customMouseUp = function (event, cancel) {

	if (this.blank && this.blank.parentNode) {
		if (cancel) {
			this.blank.parentNode.removeChild (this.blank);
		} else {
			this.blank.parentNode.replaceChild (this.domNode, this.blank);
		}
	}

	this.domNode.className = '';
	this.domNode.style.left = '';
	this.domNode.style.top = '';
}
