(function($) {

	$.fn.ppdrag = function(options) {
		if (typeof options == 'string') {
			if (options == 'destroy') return this.each(function() {
				$.ppdrag.removeEvent(this, 'mousedown', $.ppdrag.start, false);
				$.data(this, 'pp-ppdrag', null);
			});
		}
		return this.each(function() {
			$.data(this, 'pp-ppdrag', { options: $.extend({}, options) });
			$.ppdrag.addEvent(this, 'mousedown', $.ppdrag.start, false);
		});
	};

	$.ppdrag = {
		start: function(event) {
			if (!$.ppdrag.current) {
				$.ppdrag.current = {
					el: this,
					oleft: parseInt( $(this).css("left") ) || 0,
					otop: parseInt( $(this).css("top") ) || 0,
					ox: event.pageX || event.screenX,
					oy: event.pageY || event.screenY
				};
				var current = $.ppdrag.current;
				var data = $.data(current.el, 'pp-ppdrag');
				if (data.options.zIndex) {
					current.zIndex = current.el.style.zIndex;
					current.el.style.zIndex = data.options.zIndex;
				}
				$.ppdrag.addEvent(document, 'mouseup', $.ppdrag.stop, true);
				$.ppdrag.addEvent(document, 'mousemove', $.ppdrag.drag, true);
			}
			if (event.stopPropagation) event.stopPropagation();
			if (event.preventDefault) event.preventDefault();
			return false;
		},

		drag: function(event) {
			if (!event) var event = window.event;
			var current = $.ppdrag.current;
			current.el.style.left = (current.oleft + (event.pageX || event.screenX) - current.ox) + 'px';
			current.el.style.top = (current.otop + (event.pageY || event.screenY) - current.oy) + 'px';
			if (event.stopPropagation) event.stopPropagation();
			if (event.preventDefault) event.preventDefault();
			return false;
		},

		stop: function(event) {
			var current = $.ppdrag.current;
			var data = $.data(current.el, 'pp-ppdrag');
			$.ppdrag.removeEvent(document, 'mousemove', $.ppdrag.drag, true);
			$.ppdrag.removeEvent(document, 'mouseup', $.ppdrag.stop, true);
			if (data.options.zIndex) {
				current.el.style.zIndex = current.zIndex;
			}
			if (data.options.stop) {
				data.options.stop.apply(current.el, [ current.el ]);
			}
			$.ppdrag.current = null;
			if (event.stopPropagation) event.stopPropagation();
			if (event.preventDefault) event.preventDefault();
			return false;
		},

		addEvent: function(obj, type, fn, mode) {
			if (obj.addEventListener)
				obj.addEventListener(type, fn, mode);
			else if (obj.attachEvent) {
				obj["e"+type+fn] = fn;
				obj[type+fn] = function() { return obj["e"+type+fn](window.event); }
				obj.attachEvent("on"+type, obj[type+fn]);
			}
		},

		removeEvent: function(obj, type, fn, mode) {
			if (obj.removeEventListener)
				obj.removeEventListener(type, fn, mode);
			else if (obj.detachEvent) {
				obj.detachEvent("on"+type, obj[type+fn]);
				obj[type+fn] = null;
				obj["e"+type+fn] = null;
			}
		}

	};

})(jQuery);

