/*
 *  Copyright (c) 2009
 *  Kieran Menor
 *
 *  Do not use without permission.
 */

function Draggable(a, b, x, y) {
	this.a = (typeof a == 'string') ? document.getElementById(a) : a;
	this.a.onmousedown = function() { return false; };
	this.a.onselectstart = function() { return false; };
	this.b = (typeof b == 'string') ? document.getElementById(b) : b;
	this.m = {
		dragElement: this.eventMethod('dragElement'),
		dragStart: this.eventMethod('dragStart'),
		dragStop: this.eventMethod('dragStop'),
		cancelSelect: this.eventMethod('cancelSelect')
	};
	if(x != 'right') {
		this.x = 'left';
		this.mx = 1;
	}
	else {
		this.x = 'right';
		this.mx = -1;
	}
	if(y != 'bottom') {
		this.y = 'top';
		this.my = 1;
	}
	else {
		this.y = 'bottom';
		this.my = -1;
	}
	this.hooked = false;
	this.drag = false;
	this.hook();
}
Draggable.prototype.eventMethod = function(name) {
	return (function(self, name) { 
		return function(e) { self[name](e); };
	})(this, name);
}
Draggable.prototype.dragElement = function(e) {
	if(!e) {
		var e = window.event;
	}
	var x = (e.pageX) ? e.pageX : e.x;
	var y = (e.pageY) ? e.pageY : e.y;
	this.b.style[this.x] = this.startX + (x - this.mouseX) * this.mx + 'px';
	this.b.style[this.y] = this.startY + (y - this.mouseY) * this.my + 'px';
}
Draggable.prototype.dragStart = function(e) {
	if(!this.drag) {
		if(!e) {
			var e = window.event;
		}
		this.startX = parseInt(this.b.style[this.x]);
		this.startY = parseInt(this.b.style[this.y]);
		this.mouseX = (e.pageX) ? e.pageX : e.x;
		this.mouseY = (e.pageY) ? e.pageY : e.y;
		this.addEvent(document, 'mousemove', this.m['dragElement']);
		this.drag = true;
	}
}
Draggable.prototype.dragStop = function() {
	if(this.drag) {
		this.removeEvent(document, 'mousemove', this.m['dragElement']);
		this.drag = false;
	}
}
Draggable.prototype.hook = function() {
	if(!this.hooked) {
		this.addEvent(this.a, 'mousedown', this.m['dragStart']);
		this.addEvent(document, 'mouseup', this.m['dragStop']);
		this.hooked = true;
	}
}
Draggable.prototype.unhook = function() {
	if(this.hooked) {
		this.removeEvent(this.a, 'mousedown', this.m['dragStart']);
		this.removeEvent(document, 'mouseup', this.m['dragStop']);
		this.dragStop();
		this.hooked = false;
	}
}
Draggable.prototype.addEvent = function(element, event, method) {
	if(element.addEventListener) {
		element.addEventListener(event, method, false);
	}
	else {
		try {
			element.attachEvent('on'+event, method);
		}
		catch(e) {}
	}
}
Draggable.prototype.removeEvent = function(element, event, method) {
	if(element.removeEventListener) {
		element.removeEventListener(event, method, false);
	}
	else {
		try {
			element.detachEvent('on'+event, method);
		}
		catch(e) {}
	}
}