/*
 * DragLite 1.0 for jQuery
 *
 * Copyright (c) 2009 Aner Levi
 */
(function($){
	$.fn.draglite = function(options){
		var defaults = {
			cursor: "auto",
			bounds: "false",
			handle: null,
			onDrag: function(){},
			onDrop: function(){}
		};
		
		var options = $.extend(defaults, options);
		var bounds = parseBounds(options.bounds);
		
		function numeralVal(str){
			str = parseInt(str);
			return isNaN(str) ? 0 : str;
		}
		function clamp(val, min, max){
			return Math.max(min, Math.min(val, max));
		}
		function parseBounds(value){
			var b = {const0: false, const1: false, min0: false, max0: 0, min1: false, max1: 0};
			value = value.replace(/^\s+|\s+$/g, "");
			var parts = value.split(/\s+/, 4);
			for (var i=0,j=0; i<parts.length && j<2;){
				if ( parts[i]=="true" ){
					b["const"+j] = true;
					j++;
					i++;
				} else {
					b["const"+j] = false;
					if ( isNaN(parseInt(parts[i])) ){
						b["min"+j] = false;
						j++;
						i++;
					} else {
						b["min"+j] = parseInt(parts[i]);
						if ( parts[i+1] && !isNaN(parseInt(parts[i+1])) ){
							b["max"+j] = ( parseInt(parts[i])<=parseInt(parts[i+1]) ) ? parseInt(parts[i+1]) : parseInt(parts[i]);
							i+=2;
						} else {
							b["max"+j] = parseInt(parts[i]);
							i++;
						}
						j++;
					}
				}
			}
			if ( j==1 ){
				b.const1 = b.const0;
				b.min1 = b.min0;
				b.max1 = b.max0;
			}
			return b;
		}
		
		function _drag(e){
			var prev = e.data.prev;
			if ( !bounds.const0 ){
				var left = prev.left + e.pageX - prev.pageX;
				left = (bounds.min0===false) ? left : clamp(left, bounds.min0, bounds.max0);
				prev.source.css("left", left);
			}
			if ( !bounds.const1 ){
				var top = prev.top + e.pageY - prev.pageY;
				top = (bounds.min1===false) ? top : clamp(top, bounds.min1, bounds.max1);
				prev.source.css("top", top);
			}
			prev.onDrag(e);
		}
		function _drop(e){
			var prev = e.data.prev;
			$().unbind('mousemove', _drag)
				.unbind('mouseup', _drop);
			prev.onDrop(e);
		}
		
		return this.each(function(){
			var self = this;
			var handle = !options.handle ? $(this) : $(options.handle, this);
			$(this).css({
				position: "absolute",
				top: $(this).position().top,
				left: $(this).position().left
			}).find("img").attr("unselectable", "on");
			handle.css({
				cursor: options.cursor,
				MozUserSelect: "none",
				WebkitUserSelect: "none"
			}).attr("unselectable", "on");
			handle.bind("mousedown", {el: self}, function(e){
				e.preventDefault();
				var source = $(e.data.el);
				var prev = {
					top: numeralVal(source.css('top')),
					left: numeralVal(source.css('left')),
					pageX: e.pageX,
					pageY: e.pageY,
					handle: handle,
					source: source,
					onDrag: options.onDrag,
					onDrop: options.onDrop
				}
				$().bind("mousemove", {prev: prev}, _drag)
					.bind("mouseup", {prev: prev}, _drop);
			});
		});
	}
})(jQuery);
