/**
 * @author Administrator
 */
var Drag = Class.create();
Drag.prototype = {
	initialize:function(options){
		this.setOptions(options);//初始化参数
		this._x = this._y = 0;//鼠标距离拖动层的距离
		this.drag = _$(this.options.drag);//拖动层
		this.handle = _$(this.options.handle) || this.drag;//触发拖动的句柄
		
		this.limit = this.options.limit;
		this.mxLeft = this.options.mxLeft;
		this.mxRight = this.options.mxRight;
		this.mxTop = this.options.mxTop;
		this.mxBottom = this.options.mxBottom;
		this.mxContainer = _$(this.options.mxContainer);
		
		this.lock = this.options.lock;
		this.lockX = this.options.lockX;
		this.lockY = this.options.lockY;
		
		this.startcallback = this.options.startcallback;
		this.movecallback = this.options.movecallback;
		this.stopcallback = this.options.stopcallback;
		
		this._fm = BindAsEventListener(this,this.move);//拖动时方法
		this._fs = Bind(this,this.stop);//停止拖动方法
		
		this.drag.style.position = "absolute";//拖动层必须绝对定位，否则无效
		
		//透明（IE下如果拖动层的背景色透明，则无法触发拖动事件，这时自动填充一个透明层覆盖拖动层）
		if(isIE && !!this.options.Transparent){
			//填充拖放对象
			with(this.handle.appendChild(document.createElement("div")).style){
				width = height = "100%"; backgroundColor = "#fff"; filter = "alpha(opacity:0)"; fontSize = 0;
			}
		}
		this.repair();//参数的修正，容器的position不是relative或absolute，会自动把position设为relative来相对定位：
		addEventHandler(this.handle,'mousedown',BindAsEventListener(this,this.start));
	},
	setOptions:function(options){
		this.options={
			drag : "",//拖动层
			handle : "",//拖动句柄
			limit : false,//是否限制拖动范围，为true时mx*属性有效
			mxLeft : 0,//限制左边界
			mxRight : 9999,//限制右边界
			mxTop : 0,//限制上边界
			mxBottom : 9999,//限制下边界
			mxContainer : "",//限制拖动外容器
			lockX : false,//是否水平锁定
			lockY : false,//是否垂直锁定
			lock : false,//是否完全锁定
			startcallback : emptyFunction,//开始拖动时的回调函数
			movecallback : emptyFunction,//拖动中的回调函数
			stopcallback : emptyFunction//停止拖动的回调函数
		};
		Extend(this.options,options || {});
	},
	start:function(event){
		if(this.lock){return;}//完全锁定直接退出
		this.repair();//修订参数
		//计算鼠标距离拖动层的位置
		this._x = event.clientX - this.drag.offsetLeft;
		this._y = event.clientY - this.drag.offsetTop;
		//计算拖动层的margin属性值
		this._marginLeft = parseInt(CurrentStyle(this.drag).marginLeft) || 0;
		this._marginTop = parseInt(CurrentStyle(this.drag).marginTop) || 0;
		//mousemove时移动 mouseup时停止
		addEventHandler(document,'mousemove',this._fm);
		addEventHandler(document,'mouseup',this._fs);
		if(isIE){
			//焦点丢失
			addEventHandler(this.handle, "losecapture", this._fs);
			//设置鼠标捕获,会组织浏览器默认拖拽动作（比如图片和选中文字的拖放）
			this.handle.setCapture();
		}else{
			//焦点丢失
			addEventHandler(window, "blur", this._fs);
			//阻止默认动作
			event.preventDefault();
		};
		//执行回调
		this.startcallback();
	},
	move:function(event){
		iLeft = event.clientX - this._x;iTop = event.clientY - this._y;//移动层当前实处位置
		window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();//清除选择
		//范围限定
		if(this.limit){
			var mxLeft = this.mxLeft, mxRight = this.mxRight, mxTop = this.mxTop, mxBottom = this.mxBottom;
			//外容器限制
			if(!!this.mxContainer){
				mxLeft = Math.max(mxLeft,0);
				mxTop = Math.max(mxTop,0);
				mxRight = Math.min(mxRight,this.mxContainer.clientWidth);//外容器的右边值和限制拖动最大值之间的最小值
				mxBottom = Math.min(mxBottom,this.mxContainer.clientHeight);//同上
			}
			/*
			 *覆盖移动层当前实处坐标位置
			 *左边位置是 限制左边最小值和（右边最大值减去移动层宽度的值）之间的最小值 同 左边最小值 相比，然后取最大值
			 *上边位置是 限制上边最小值和（下边最大值减去移动层高度的值）之间的最小值 同 上边最小值 相比，然后取最大值
			 */
			iLeft = Math.max(Math.min(iLeft,mxRight-this.drag.offsetWidth),mxLeft);
			iTop = Math.max(Math.min(iTop,mxBottom-this.drag.offsetHeight),mxTop);
		}
		//在没有进行方向锁定时进行移动层的重定位（如有margin要进行相减）
		if(!this.lockX)this.drag.style.left = iLeft - this._marginLeft + "px";
		if(!this.lockY)this.drag.style.top = iTop - this._marginTop + "px";
		//执行回调
		this.movecallback();
	},
	stop:function(){
		//移除拖动事件
		removeEventHandler(document,'mousemove',this._fm);
		removeEventHandler(document,'mouseup',this._fs);
		if(isIE){
			removeEventHandler(this.handle, "losecapture", this._fs);
			this.handle.releaseCapture();
		}else{
			removeEventHandler(window, "blur", this._fs);
		};
		//执行回调
		this.stopcallback();
	},
	repair: function() {
	if(this.limit){
		//修正错误范围参数
		this.mxRight = Math.max(this.mxRight, this.mxLeft + this.drag.offsetWidth);
		this.mxBottom = Math.max(this.mxBottom, this.mxTop + this.drag.offsetHeight);
		//如果有容器必须设置position为relative或absolute来相对或绝对定位，并在获取offset之前设置
		!this.mxContainer || CurrentStyle(this.mxContainer).position == "relative" || CurrentStyle(this.mxContainer).position == "absolute" || (this.mxContainer.style.position = "relative");
	}
  }
};

