function DDO(){
	this.items=new Array;//масств элементов класса DDOitem
	this.draggingItem=false;//перетаскиваемый в данный момент объект
	this.mouseY;//координата Y предыдущего положения курсора на экране
	this.mouseX;//координата X предыдущего положения курсора на экране
	this.maxZindex=159;//максимальное значение свойства z-index, всякий раз увеличивается на 1 и присваивается перетаскиваемому объекту

	// private methods
	this.mousedown=DDOmousedown;
	this.mousemove=DDOmousemove;
	this.mouseup=DDOmouseup;
	this.selectstart=DDOselectstart;
}

function DDOmousedown(mozillaEVENT){
	if(ddo.draggingItem)
		return false;
	var e=(document.all)?event:mozillaEVENT;
	var mouseBtn=(e.button)?e.button:e.which;
	if(mouseBtn==1){
		var target=(document.all)?e.srcElement:e.target; 
		for(var i in ddo.items){
			if(ddo.items[i].id==target.id){
				ddo.draggingItem=ddo.items[i];
				ddo.draggingItem.top=parseInt(ddo.draggingItem.getDOMobj().offsetTop);
				ddo.draggingItem.left=parseInt(ddo.draggingItem.getDOMobj().offsetLeft);
				ddo.maxZindex++;
				ddo.draggingItem.redraw(ddo.maxZindex);
				break;
			}
		}
	}
}

function DDOmousemove(mozillaEVENT){
	var e=(document.all)?event:mozillaEVENT;
	if(ddo.draggingItem){
		if(ddo.mouseX || ddo.mouseY){
			var dx=e.clientX-ddo.mouseX; var dy=e.clientY-ddo.mouseY; 
			ddo.draggingItem.top+=dy; ddo.draggingItem.left+=dx;
			ddo.draggingItem.redraw(ddo.maxZindex);
		}
		ddo.mouseX=e.clientX; ddo.mouseY=e.clientY;
	}
	e.cancelBubble=true;
}

function DDOmouseup(){
	if(ddo.draggingItem){
		if(ddo.draggingItem.userReleaseFunction) ddo.draggingItem.userReleaseFunction();
		ddo.draggingItem=false;
		ddo.mouseX=null; ddo.mouseY=null;
	}
}

function DDOselectstart(){
	if(ddo.draggingItem)
		return false;
}
var ddo=new DDO();


if(document.all){
	document.onmousedown=ddo.mousedown;
	document.onmousemove=ddo.mousemove;
	document.onmouseup=ddo.mouseup;
	document.onselectstart=ddo.selectstart;
}else{
	window.captureEvents(Event.MOUSEDOWN|Event.MOUSEMOVE|Event.MOUSEUP|Event.SELECTSTART)
	window.onmousedown=ddo.mousedown;
	window.onmousemove=ddo.mousemove;
	window.onmouseup=ddo.mouseup;
	window.onselectstart=ddo.selectstart;
}

//========================

function DDOitem(id,range,zindex,funcmov,funcrls){
	this.id=id;
	this.zIndex=(zindex)?zindex:null;//первоначальное значение свойства z-index перетаскиваемого объекта
	this.top;//текущая координата top перетаскиваемого объекта
	this.left;//текущая координата left перетаскиваемого объекта
	this.userRange=range;//"0,0, 500,500; 400,500, 500,800" координаты пределов области видимости, заданные пользователем
	this.range;//"0,0, 500,500; 400,500, 500,800" координаты пределов области видимости (окончательные)
	this.userMoveFunction=(funcmov)?funcmov:null;
	this.userReleaseFunction=(funcrls)?funcrls:null;

	//private methods
	this.getRange=DDOitemGetRange;
	this.redraw=DDOitemRedraw;
	this.getDOMobj=new Function('return document.getElementById(this.id)');

	//setup
	ddo.items.push(this);
	this.getDOMobj().ondragstart=new Function('return false');
}

function DDOitemGetRange(){
	if(!this.range){
		if(this.userRange){
			this.range=this.userRange;
		}else{
			this.range='0,0, '+ parseInt( (window.innerWidth>0)?window.innerWidth:document.body.clientWidth )+ ','+ parseInt( (window.innerHeight>0)?window.innerHeight:document.body.clientHeight );
		}
		this.range=this.range.replace(/\s/,'');
	}
	return this.range;
}

function DDOitemRedraw(zIndex){
	// проверяем, не выходит ли объект за пределы области видимости
	try{
		var tmpRangesArr=this.getRange().split(';');
		var outOfXRange=true;
		var outOfYRange=true;
		var itemWidth=parseInt(this.getDOMobj().offsetWidth);
		var itemHeight=parseInt(this.getDOMobj().offsetHeight);
		for(var i in tmpRangesArr){
			if(tmpRangesArr[i]!=''){
				var tmpCoordsArr=tmpRangesArr[i].split(',');
				outOfXRange=!(this.left >= tmpCoordsArr[0] && this.left+itemWidth <= tmpCoordsArr[2]);
				outOfYRange=!(this.top >= tmpCoordsArr[1] && this.top+itemHeight <= tmpCoordsArr[3]);
				if(outOfXRange && outOfYRange) break;
			}
		}
		if(!outOfXRange) this.getDOMobj().style.left=this.left+'px';
		if(!outOfYRange) this.getDOMobj().style.top=this.top+'px';
		if(!this.zIndex) this.getDOMobj().style.zIndex=zIndex;//изменяем свойство только в том случае, если он не было задано пользователем
		if(this.userMoveFunction) this.userMoveFunction();
	}
	catch(e){
		window.status='вероятно, область видимости задана неправильно';
	}
}


