function Draggable(){
	this._init.apply(this, arguments);
}

Draggable.prototype = {
	/* Methods for re-init in child class */
	oninit: function(){},
	events: function(){},
	onmousedown: function(){
		this.ptr.css({ position: "absolute" });
	},
	onmousemove: function(evt, x, y){
		this.ptr.css({ left: x, top: y });
	},
	onmouseup: function(){},

	isDefault: {
		drag: false,
		clicked: false,
		toclick: true,
		mouseup: false
	},

	_init: function(){
		if(arguments.length > 0){
			this.ptr = jQuery(arguments[0]);
			this.outer = jQuery(".draggable-outer");

			this.is = new Object();
			jQuery.extend(this.is, this.isDefault);

			var _offset = this.ptr.offset();
			this.d = {
				left: _offset.left,
				top: _offset.top,
				width: this.ptr.width(),
				height: this.ptr.height()
			}
			
			this.oninit.apply(this, arguments);

			this._events();
		}
	},
	_events: function(){
		var oThis = this;

		jQuery(document)
			.mousemove(function(evt){
				if(oThis.is.drag){
					oThis._mousemove(evt);
					return false;
				}
			})
			.mouseup(function(evt){
				oThis._mouseup(evt);
			})
			.bind("dragstart", function(){
				return false;
			});

		this.ptr
			.mousedown(function(evt){
				oThis._mousedown(evt);
				return false;
			})
			.mouseup(function(evt){
				oThis._mouseup(evt);
			});
		
		this.ptr.find("a")
			.click(function(){
				oThis.is.clicked = true;
				if(!oThis.is.toclick){
					oThis.is.toclick = true;
					return false;
				}
			})
			.mousedown(function(oEvt){
				oThis._mousedown(oEvt);
				return false;
			})
			.bind("dragstart", function(){
				return false;
			});

		
		this.events();
	},
	_mousedown: function(evt){
		this.is.drag = true;
		this.is.clicked = false;
		this.is.mouseup = false;
		
		var _offset = this.ptr.offset();
		this.cx = evt.pageX - _offset.left;
		this.cy = evt.pageY - _offset.top;

		jQuery.extend(this.d, {
			left: _offset.left,
			top: _offset.top,
			width: this.ptr.width(),
			height: this.ptr.height()
		});
		
		if(this.outer && this.outer.get(0)){
			this.outer.css({ height: Math.max(this.outer.height(), jQuery(document.body).height()), overflow: "hidden" });
		}
		
		this.onmousedown(evt);
	},
	_mousemove: function(evt){
		this.is.toclick = false;
		this.onmousemove(evt, evt.pageX - this.cx, evt.pageY - this.cy);
	},
	_mouseup: function(evt){
		var oThis = this;
		if(this.is.drag){
			this.is.drag = false;

			if(this.outer && this.outer.get(0)){

				if(jQuery.browser.mozilla)
					this.outer.css({ overflow: "hidden" });
				else
					this.outer.css({ overflow: "visible" });
				
				if(jQuery.browser.msie && jQuery.browser.version == '6.0')
					this.outer.css({ height: "100%" });
				else
					this.outer.css({ height: "auto" });
					
			}

			this.onmouseup(evt);
		}
	}
	
}