var Dragger = new function()
{
	var me_ = this;
	var map_ = {};

	var cursor_x_ = 0;
	var cursor_y_ = 0;
	var start_x_ = 0;
	var start_y_ = 0;

	this.register = function( id, obj )
	{
		map_[ id ] = obj;
		addEvent( obj.dragHandle(), 'mousedown', me_.drag_start, false, false );
		addEvent( obj.dragHandle(), 'dragstart', function() { return false }, false, false );
	}

	this.drag_start = function( e )
	{
		e = standard_event( e, this );
		var obj = map_[ e.currentTarget.id ];
		if ( obj )
		{
			cursor_x_ = e.pageX;
			cursor_y_ = e.pageY;
			start_y_ = obj.dragElement().offsetTop;
			start_x_ = obj.dragElement().offsetLeft;
			obj.dragHandle().style.cursor = 'move';
			addEvent( obj.dragHandle(), 'mousemove', me_.drag_go, false, false );
			addEvent( obj.dragHandle(), 'mouseup', me_.drag_stop, false, false );
			if ( obj.dragStopOnOut && obj.dragStopOnOut() )
				addEvent( obj.dragHandle(), 'mouseout', me_.drag_stop, false, false );
			if ( obj.dragOnParent && obj.dragOnParent() )
				map_[ e.target.parentNode.id ] = obj;
			e.stopPropagation();
			e.preventDefault();
		}
	}

	this.drag_go = function( e )
	{
		e = standard_event( e, this );
		var obj = map_[ e.currentTarget.id ];
		if ( obj )
		{
			var x = start_x_ + e.pageX - cursor_x_;
			var y = start_y_ + e.pageY - cursor_y_;
			if ( obj.minX && x < obj.minX() )
				x = obj.minX();
			if ( obj.minY && y < obj.minY() )
				y = obj.minY();
			if ( obj.maxX && x + obj.dragElement().offsetWidth > obj.maxX() )
				x = obj.maxX() - obj.dragElement().offsetWidth;
			if ( obj.maxY && y + obj.dragElement().offsetHeight > obj.maxY() )
				y = obj.maxY() - obj.dragElement().offsetHeight;
			obj.dragElement().style.left = x + 'px';
			obj.dragElement().style.top = y + 'px';
			if ( obj.on_drag )
				obj.on_drag( e );
			e.stopPropagation();
			e.preventDefault();
		}
	}

	this.drag_stop = function( e )
	{
		e = standard_event( e, this );
		var obj = map_[ e.currentTarget.id ];
		if ( obj )
		{
			removeEvent( obj.dragHandle(), 'mousemove', me_.drag_go, false, false );
			removeEvent( obj.dragHandle(), 'mouseup', me_.drag_stop, false, false );
			removeEvent( obj.dragHandle(), 'mouseout', me_.drag_stop, false, false );
			obj.dragHandle().style.cursor = 'default';
			if ( obj.on_drag_end )
				obj.on_drag_end( e );
			e.stopPropagation();
			e.preventDefault();
		}
	}
}();
