$.drug = null;
$.dragHelper = null;

$.dragstart = function(e)
{
	if (window.event) {
		window.event.cancelBubble = true;
		window.event.returnValue = false;
		sx = window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
		sy = window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop;
	} else {
		e.preventDefault();
		e.stopPropagation();
		sx = e.clientX
		sy = e.clientY
	}
	this.dE.oC = $.getPos(this.dE);
    this.dE.dX = sx - this.dE.oC.x;
    this.dE.dY = sy - this.dE.oC.y;
    this.dE.oD = $.css(this.dE, 'display');
    this.dE.oP = $.css(this.dE, 'position');
    this.dE.oW = $.css(this.dE, 'width');
    this.dE.oH = $.css(this.dE, 'height');
    this.dE.oF = $.css(this.dE, 'float');
	$.dragHelper.html('');
	c = this.dE.cloneNode(true);
	if (this.dE.opacity) {
		$(c).css('opacity', this.dE.opacity);
		if (window.ActiveXObject)
			$(c).css('filter', 'alpha(opacity=' + this.dE.opacity * 100 + ')');
	}
	$(c).css(
		{
			display:	'block',
			width:		this.dE.oC.w + 'px',
			height:		this.dE.oC.h + 'px'
		}
	);
	$(c).css(
		{
			left:		'0px',
			top: 		'0px'
		}
	);
	$.dragHelper.append(c).css(
		{
			display:	'block',
			left:		this.dE.oC.x + 'px',
			top: 		this.dE.oC.y + 'px',
			width:		this.dE.oC.w + 'px',
			height:		this.dE.oC.h + 'px',
			overflow:	'hidden'
		}
	);
	if (this.dE.ghosting == false) {
		$(this.dE).css('display', 'none');
	}
	if ($.droppables && $.droppables.length > 0 ){
		$.drophighlight(this.dE);
	}
	if (this.dE.zIndex != false) {
		$.dragHelper.css('zIndex', this.dE.zIndex);
	}
    $.drug = this.dE;
	$.drug.prot = false;
	$.drag(e);
};

$.dragstop = function(e)
{
    if ($.drug == null || $.drug.prot == true) {
		return;
    }
	hx = $.intval($.dragHelper.css('left'))
	hy = $.intval($.dragHelper.css('top'));
	if ($.drug.revert == false) {
		if ($.drug.fx > 0 && hx != $.drug.oC.x && hy != $.drug.oC.y) {
			$.dragHelper.css('display','none');
			x = new fx.Left($.drug,$.drug.fx);
			y = new fx.Top($.drug,$.drug.fx);
			x.custom($.drug.oC.x,hx);
			y.custom($.drug.oC.y,hy);
			x.show();
			y.show();
		} else {
			$($.drug).css(
				{
					left: $.dragHelper.css('left'),
					top: $.dragHelper.css('top')
				}
			);
			$.dragHelper.css('display','none');
		}
	} else {
		if ($.drug.fx > 0 && hx != $.drug.oC.x && hy != $.drug.oC.y) {
			$.drug.prot = true;
			x = new fx.Left(
				$.dragHelper.cur[0],
				{
					duration : $.drug.fx,
					onComplete : function()
					{
						$(this).css('display','none');
						if ($.drug.ghosting == false) {
							$($.drug).css('display', $.drug.oD);
						}
						$.drug = null;
					}
				}
			);
			if($.overzone && $.sortables) {
				dh = $.getPos($.sortHelper.cur[0]);
			} else {
				dh = false;
			}
			y = new fx.Top($.dragHelper.cur[0],$.drug.fx);
			x.custom(hx,dh ? dh.x : $.drug.oC.x);
			y.custom(hy,dh ? dh.y : $.drug.oC.y);
			x.show();
			y.show();
		} else {
			$.dragHelper.css('display','none');
		}
	}
	
	if ($.droppables && $.droppables.length > 0 ){
		$.dropcheck($.drug.dE);
	}
	if ($.sortables ) {
		$.sortcheck($.drug.dE);
	}
	
	if ($.drug.prot == false) {
		if ($.drug.ghosting == false) {
			$($.drug).css('display', $.drug.oD);
		}
	    $.drug = null;
	}
}

$.drag = function(e)
{
    if ($.drug == null || $.drug.prot == true) {
		return;
    }
	if (window.event) {
		sx = window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
		sy = window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop;
	} else {
		sx = e.clientX
		sy = e.clientY
	}
    var nx = (sx- $.drug.dX);
    var ny = (sy - $.drug.dY);
    nx = (nx < 0) ? 0 : nx;
    nx = (nx + $.drug.offsetWidth) > document.width ? document.width - $.drug.offsetWidth : nx;
    ny = (ny < window.scrollY) ? window.scrollY : ny;
    ny = (ny + $.drug.offsetHeight) > window.innerHeight + window.scrollY ? window.innerHeight + window.scrollY - $.drug.offsetHeight: ny;

	if ($.drug.gx) {
		nx = parseInt(nx/$.drug.gx) * $.drug.gx;
		ny = parseInt(ny/$.drug.gy) * $.drug.gy;
	}

	$.dragHelper.css('left', nx + 'px').css('top', ny + 'px');
	if ($.droppables && $.droppables.length > 0 ){
		mx = e.clientX + (window.scrollX ? window.scrollX : 0);
		my = e.clientY + (window.scrollY ? window.scrollY : 0);
		$.dropcheckhover(mx, my, nx, ny, $.drug.oW , $.drug.oH);
	}
};
$.draginit = false;

$.fn.Draggable = function(o)
{
    if (!$.draginit) {
		$('body').bind('mousemove', $.drag).bind('mouseup', $.dragstop);
		$.draginit = true;
    }
    if (!$.dragHelper) {
		$('body',document).append('<div id="dragHelper"></div>');
		$.dragHelper = $('#dragHelper');
		$.dragHelper.css(
			{
				position:	'absolute',
				display:	'none',
				cursor:		'move'
			}
		);
    }
    if (!o) {
		o = {};
	}
    return this.each(
		function()
		{
			if (this.isDraggable)
				return;
			var dhe = o.handle ? $(this).find(o.handle) : $(this);
			this.revert = o.revert ? true : false;
			this.ghosting = o.ghosting ? true : false;
			if(o.grid){
				if(typeof o.grid == 'number'){
					this.gx = this.gy = $.intval(o.grid);
				} else if (o.grid.length == 2) {
					this.gx = $.intval(o.grid[0]);
					this.gy = $.intval(o.grid[1]);
				}
			}
			this.zIndex = o.zIndex ? $.intval(o.zIndex) : false;
			this.opacity = o.opacity ? parseFloat(o.opacity) : false;
			this.fx = $.intval(o.fx);
			this.hpc = o.hpc ? o.hpc : false,
			this.isDraggable = true;
			if (window.ActiveXObject && this.tagName.toLowerCase() == 'img') {
				this.onselectstart = function(){return false;};
				this.ondragstart = function(){return false;};
			}
			dhe.get(0).dE = this;
			dhe.bind('mousedown', $.dragstart);
		}
	);
};
