function DragSort(dragContainers){
	this.dragContainers = dragContainers;
	this.dragApproved = false;
	this.dragHandleOK = false;
	this.needHandle = false;
	this.dragObj = null;
	this.dBack = null;
	this.offX = 0;
	this.offY = 0;

	this.endDrag = function(){
		if (this.dragApproved == true){
			this.dragApproved = false;
			this.dBack.parentNode.replaceChild(this.dragObj,this.dBack);
			//this.dragObj.className = "drag";
			this.dragObj.style.position = "static";
			this.dragObj.style.width = this.dragObj.style.width;//"90%";  //firefox needs this line 
			if (document.selection){
				document.onselectstart = function() {}
			}
		}
	}

	this.dragDrop = function(evt){
		if (this.dragApproved) {
			if (document.selection) {
				document.selection.empty();
				document.onselectstart = function() {return false}
			}
			var e = evt || window.event;
			var x = e.clientX - this.offX + document.body.scrollLeft;
			var y = e.clientY - this.offY + document.body.scrollTop;
			this.dragObj.style.left = x;
			this.dragObj.style.top = y;
			//x = x + Math.floor(this.dragObj.offsetWidth / 2);
			x = x + 20;
			y = y + 20;
			for(var k = 0;k < this.dragContainers.length;k++){
				var groupPos = this.getObjPosition(this.dragContainers[k]);
				//window.status = "x = " + x + ",groupPos.x = " + groupPos.x + "," + (groupPos.x + this.dragContainers[k].offsetWidth);
				if (x >= groupPos.x && x <= groupPos.x + this.dragContainers[k].offsetWidth && y >= groupPos.y && y <= groupPos.y + this.dragContainers[k].offsetHeight){
					this.moveDBack(this.dragContainers[k],y);
					return;
				}
			}
		}
	}

	this.findDragObj = function(src){
		if(src.tagName == 'BODY') return null;
		if($(src).attr('isDragHandle') == "true") this.dragHandleOK = true;
		if($(src).attr('isDragItem') == "true") return src;
		return this.findDragObj(src.parentNode);
	}

	this.beginDrag = function(evt) {
		this.dragHandleOK = false;
		this.dragObj = this.findDragObj(window.event ? event.srcElement : evt.target);
		if (this.dragApproved == false && this.dragObj && ((this.dragHandleOK && this.needHandle) || !this.needHandle) ) {
			var w = this.dragObj.offsetWidth;
			//var h = this.dragObj.offsetHeight;
			//if (window.event) this.dragObj.parentNode.style.paddingTop = "20px";  //ie needs this line 
			this.dBack = this.dragObj.cloneNode(false);
			this.dBack.style.height = $(this.dragObj).height();
			//this.dBack.style.width = $(this.dragObj).width(); //change by duron,这里会影响到拖动
			this.dBack.style.border = "2px dashed #CCCCCC";
			this.dBack.style.background = "#ffffff";
			//this.dBack.style.height = h;
			var pos = this.getObjPosition(this.dragObj);
			//this.dragObj.className = "draging";
			this.dragObj.style.position = "absolute";
			//this.dragObj.style.zIndex = 98;
			this.dragObj.style.left = pos.x;
			this.dragObj.style.top = pos.y;
			//this.dragObj.style.width = w; //change by duron,这里会影响到拖动
			this.offX = window.event ? event.offsetX : evt.clientX - pos.x;
			this.offY = window.event ? event.offsetY : evt.clientY - pos.y;
			this.dragObj.parentNode.insertBefore(this.dBack,this.dragObj);
			this.dragApproved = true;
		}
	}

	this.moveDBack = function(obj,y){
		var length = obj.childNodes.length;
		var index = length;
		for (var i = 0;i < length;i++){
			if (obj.childNodes[i] == this.dragObj) continue;
			var childPos = this.getObjPosition(obj.childNodes[i]); 
			if (y <= childPos.y + Math.floor(obj.childNodes[i].offsetHeight / 2)) {
				index = i;
				break;
			}
		}
		if (index < length) {
			obj.insertBefore(this.dBack,obj.childNodes[index]);
		} else {
			obj.appendChild(this.dBack);
		}
	}
	
	this.getObjPosition = function(obj) {
		var pos = new Point(0,0);
		while (obj) {
			pos.x += obj.offsetLeft;
			pos.y += obj.offsetTop;
			obj = obj.offsetParent;
		}
		return pos;
	}

	this.serial = function() {
		var str = "";
		for (var i = 0;i < this.dragContainers.length;i++) {
			var group = this.dragContainers[i];
			str += group.id + "=";
			for (var j = 0;j < group.childNodes.length;j++) {
				if ($(group.childNodes[j]).attr("isDragItem") == "true") {
					str += (group.childNodes[j].id);
					if(j < group.childNodes.length - 1) str += ",";
				}
			}
			if(i < dragContainers.length - 1) str += "&";
		}
		str = str.replace(/(,&)/g,"&"); //将每个项目的最后多出的逗号去掉
		return str;
	}
	
	//此方法有点像高级语言的静态方法这个用，参数 dragSortObj 要求是一个实例化的 DragSort 对象
	this.run = function(dragSortObj){
		if(!ds.dragContainers){
			alert("可拖动对象的容器未初始化");
			return;
		}
		$(document).bind("mousedown",function(e){dragSortObj.beginDrag(e)});
		$(document).bind("mouseup",function(){dragSortObj.endDrag()});
		$(document).bind("mousemove",function(e){dragSortObj.dragDrop(e)});
	}
}

function Point(_x,_y) {
	this.x = _x;
	this.y = _y;
}
