text: /**
   * draggable - jQuery EasyUI
   * 
   * Copyright (c) 2009-2013 www.jeasyui.com. All rights reserved.
   *
   * Licensed under the GPL or commercial licenses
   * To use it on other terms please contact us: info@jeasyui.com
   * http://www.gnu.org/licenses/gpl.txt
   * http://www.jeasyui.com/license_commercial.php
   */
  (function($){
  //	var isDragging = false;
  	function drag(e){
  		var state = $.data(e.data.target, 'draggable');
  		var opts = state.options;
  		var proxy = state.proxy;
  		
  		var dragData = e.data;
  		var left = dragData.startLeft + e.pageX - dragData.startX;
  		var top = dragData.startTop + e.pageY - dragData.startY;
  		
  		if (proxy){
  			if (proxy.parent()[0] == document.body){
  				if (opts.deltaX != null && opts.deltaX != undefined){
  					left = e.pageX + opts.deltaX;
  				} else {
  					left = e.pageX - e.data.offsetWidth;
  				}
  				if (opts.deltaY != null && opts.deltaY != undefined){
  					top = e.pageY + opts.deltaY;
  				} else {
  					top = e.pageY - e.data.offsetHeight;
  				}
  			} else {
  				if (opts.deltaX != null && opts.deltaX != undefined){
  					left += e.data.offsetWidth + opts.deltaX;
  				}
  				if (opts.deltaY != null && opts.deltaY != undefined){
  					top += e.data.offsetHeight + opts.deltaY;
  				}
  			}
  		}
  		
  //		if (opts.deltaX != null && opts.deltaX != undefined){
  //			left = e.pageX + opts.deltaX;
  //		}
  //		if (opts.deltaY != null && opts.deltaY != undefined){
  //			top = e.pageY + opts.deltaY;
  //		}
  		
  		if (e.data.parent != document.body) {
  			left += $(e.data.parent).scrollLeft();
  			top += $(e.data.parent).scrollTop();
  		}
  		
  		if (opts.axis == 'h') {
  			dragData.left = left;
  		} else if (opts.axis == 'v') {
  			dragData.top = top;
  		} else {
  			dragData.left = left;
  			dragData.top = top;
  		}
  	}
  	
  	function applyDrag(e){
  		var state = $.data(e.data.target, 'draggable');
  		var opts = state.options;
  		var proxy = state.proxy;
  		if (!proxy){
  			proxy = $(e.data.target);
  		}
  //		if (proxy){
  //			proxy.css('cursor', opts.cursor);
  //		} else {
  //			proxy = $(e.data.target);
  //			$.data(e.data.target, 'draggable').handle.css('cursor', opts.cursor);
  //		}
  		proxy.css({
  			left:e.data.left,
  			top:e.data.top
  		});
  		$('body').css('cursor', opts.cursor);
  	}
  	
  	function doDown(e){
  //		isDragging = true;
  		$.fn.draggable.isDragging = true;
  		var state = $.data(e.data.target, 'draggable');
  		var opts = state.options;
  		
  		var droppables = $('.droppable').filter(function(){
  			return e.data.target != this;
  		}).filter(function(){
  			var accept = $.data(this, 'droppable').options.accept;
  			if (accept){
  				return $(accept).filter(function(){
  					return this == e.data.target;
  				}).length > 0;
  			} else {
  				return true;
  			}
  		});
  		state.droppables = droppables;
  		
  		var proxy = state.proxy;
  		if (!proxy){
  			if (opts.proxy){
  				if (opts.proxy == 'clone'){
  					proxy = $(e.data.target).clone().insertAfter(e.data.target);
  				} else {
  					proxy = opts.proxy.call(e.data.target, e.data.target);
  				}
  				state.proxy = proxy;
  			} else {
  				proxy = $(e.data.target);
  			}
  		}
  		
  		proxy.css('position', 'absolute');
  		drag(e);
  		applyDrag(e);
  		
  		opts.onStartDrag.call(e.data.target, e);
  		return false;
  	}
  	
  	function doMove(e){
  		var state = $.data(e.data.target, 'draggable');
  		drag(e);
  		if (state.options.onDrag.call(e.data.target, e) != false){
  			applyDrag(e);
  		}
  		
  		var source = e.data.target;
  		state.droppables.each(function(){
  			var dropObj = $(this);
  			if (dropObj.droppable('options').disabled){return;}
  			
  			var p2 = dropObj.offset();
  			if (e.pageX > p2.left && e.pageX < p2.left + dropObj.outerWidth()
  					&& e.pageY > p2.top && e.pageY < p2.top + dropObj.outerHeight()){
  				if (!this.entered){
  					$(this).trigger('_dragenter', [source]);
  					this.entered = true;
  				}
  				$(this).trigger('_dragover', [source]);
  			} else {
  				if (this.entered){
  					$(this).trigger('_dragleave', [source]);
  					this.entered = false;
  				}
  			}
  		});
  		
  		return false;
  	}
  	
  	function doUp(e){
  //		isDragging = false;
  		$.fn.draggable.isDragging = false;
  //		drag(e);
  		doMove(e);
  		
  		var state = $.data(e.data.target, 'draggable');
  		var proxy = state.proxy;
  		var opts = state.options;
  		if (opts.revert){
  			if (checkDrop() == true){
  				$(e.data.target).css({
  					position:e.data.startPosition,
  					left:e.data.startLeft,
  					top:e.data.startTop
  				});
  			} else {
  				if (proxy){
  					var left, top;
  					if (proxy.parent()[0] == document.body){
  						left = e.data.startX - e.data.offsetWidth;
  						top = e.data.startY - e.data.offsetHeight;
  					} else {
  						left = e.data.startLeft;
  						top = e.data.startTop;
  					}
  					proxy.animate({
  						left: left,
  						top: top
  					}, function(){
  						removeProxy();
  					});
  				} else {
  					$(e.data.target).animate({
  						left:e.data.startLeft,
  						top:e.data.startTop
  					}, function(){
  						$(e.data.target).css('position', e.data.startPosition);
  					});
  				}
  			}
  		} else {
  			$(e.data.target).css({
  				position:'absolute',
  				left:e.data.left,
  				top:e.data.top
  			});
  			checkDrop();
  		}
  		
  		opts.onStopDrag.call(e.data.target, e);
  		
  		$(document).unbind('.draggable');
  		setTimeout(function(){
  			$('body').css('cursor','');
  		},100);
  		
  		function removeProxy(){
  			if (proxy){
  				proxy.remove();
  			}
  			state.proxy = null;
  		}
  		
  		function checkDrop(){
  			var dropped = false;
  			state.droppables.each(function(){
  				var dropObj = $(this);
  				if (dropObj.droppable('options').disabled){return;}
  				
  				var p2 = dropObj.offset();
  				if (e.pageX > p2.left && e.pageX < p2.left + dropObj.outerWidth()
  						&& e.pageY > p2.top && e.pageY < p2.top + dropObj.outerHeight()){
  					if (opts.revert){
  						$(e.data.target).css({
  							position:e.data.startPosition,
  							left:e.data.startLeft,
  							top:e.data.startTop
  						});
  					}
  					$(this).trigger('_drop', [e.data.target]);
  					removeProxy();
  					dropped = true;
  					this.entered = false;
  					return false;
  				}
  			});
  			if (!dropped && !opts.revert){
  				removeProxy();
  			}
  			return dropped;
  		}
  		
  		return false;
  	}
  	
  	$.fn.draggable = function(options, param){
  		if (typeof options == 'string'){
  			return $.fn.draggable.methods[options](this, param);
  		}
  		
  		return this.each(function(){
  			var opts;
  			var state = $.data(this, 'draggable');
  			if (state) {
  				state.handle.unbind('.draggable');
  				opts = $.extend(state.options, options);
  			} else {
  				opts = $.extend({}, $.fn.draggable.defaults, $.fn.draggable.parseOptions(this), options || {});
  			}
  			var handle = opts.handle ? (typeof opts.handle=='string' ? $(opts.handle, this) : opts.handle) : $(this);
  			
  			$.data(this, 'draggable', {
  				options: opts,
  				handle: handle
  			});
  			
  			if (opts.disabled) {
  				$(this).css('cursor', '');
  				return;
  			}
  			
  			handle.unbind('.draggable').bind('mousemove.draggable', {target:this}, function(e){
  //				if (isDragging) return;
  				if ($.fn.draggable.isDragging){return}
  				var opts = $.data(e.data.target, 'draggable').options;
  				if (checkArea(e)){
  					$(this).css('cursor', opts.cursor);
  				} else {
  					$(this).css('cursor', '');
  				}
  			}).bind('mouseleave.draggable', {target:this}, function(e){
  				$(this).css('cursor', '');
  			}).bind('mousedown.draggable', {target:this}, function(e){
  				if (checkArea(e) == false) return;
  				$(this).css('cursor', '');
  
  				var position = $(e.data.target).position();
  				var offset = $(e.data.target).offset();
  				var data = {
  					startPosition: $(e.data.target).css('position'),
  					startLeft: position.left,
  					startTop: position.top,
  					left: position.left,
  					top: position.top,
  					startX: e.pageX,
  					startY: e.pageY,
  					offsetWidth: (e.pageX - offset.left),
  					offsetHeight: (e.pageY - offset.top),
  					target: e.data.target,
  					parent: $(e.data.target).parent()[0]
  				};
  				
  				$.extend(e.data, data);
  				var opts = $.data(e.data.target, 'draggable').options;
  				if (opts.onBeforeDrag.call(e.data.target, e) == false) return;
  				
  				$(document).bind('mousedown.draggable', e.data, doDown);
  				$(document).bind('mousemove.draggable', e.data, doMove);
  				$(document).bind('mouseup.draggable', e.data, doUp);
  //				$('body').css('cursor', opts.cursor);
  			});
  			
  			// check if the handle can be dragged
  			function checkArea(e) {
  				var state = $.data(e.data.target, 'draggable');
  				var handle = state.handle;
  				var offset = $(handle).offset();
  				var width = $(handle).outerWidth();
  				var height = $(handle).outerHeight();
  				var t = e.pageY - offset.top;
  				var r = offset.left + width - e.pageX;
  				var b = offset.top + height - e.pageY;
  				var l = e.pageX - offset.left;
  				
  				return Math.min(t,r,b,l) > state.options.edge;
  			}
  			
  		});
  	};
  	
  	$.fn.draggable.methods = {
  		options: function(jq){
  			return $.data(jq[0], 'draggable').options;
  		},
  		proxy: function(jq){
  			return $.data(jq[0], 'draggable').proxy;
  		},
  		enable: function(jq){
  			return jq.each(function(){
  				$(this).draggable({disabled:false});
  			});
  		},
  		disable: function(jq){
  			return jq.each(function(){
  				$(this).draggable({disabled:true});
  			});
  		}
  	};
  	
  	$.fn.draggable.parseOptions = function(target){
  		var t = $(target);
  		return $.extend({}, 
  				$.parser.parseOptions(target, ['cursor','handle','axis',
  				       {'revert':'boolean','deltaX':'number','deltaY':'number','edge':'number'}]), {
  			disabled: (t.attr('disabled') ? true : undefined)
  		});
  	};
  	
  	$.fn.draggable.defaults = {
  		proxy:null,	// 'clone' or a function that will create the proxy object, 
  					// the function has the source parameter that indicate the source object dragged.
  		revert:false,
  		cursor:'move',
  		deltaX:null,
  		deltaY:null,
  		handle: null,
  		disabled: false,
  		edge:0,
  		axis:null,	// v or h
  		
  		onBeforeDrag: function(e){},
  		onStartDrag: function(e){},
  		onDrag: function(e){},
  		onStopDrag: function(e){}
  	};
  	
  	$.fn.draggable.isDragging = false;
  	
  //	$(function(){
  //		function touchHandler(e) {
  //			var touches = e.changedTouches, first = touches[0], type = "";
  //
  //			switch(e.type) {
  //				case "touchstart": type = "mousedown"; break;
  //				case "touchmove":  type = "mousemove"; break;        
  //				case "touchend":   type = "mouseup";   break;
  //				default: return;
  //			}
  //			var simulatedEvent = document.createEvent("MouseEvent");
  //			simulatedEvent.initMouseEvent(type, true, true, window, 1,
  //									  first.screenX, first.screenY,
  //									  first.clientX, first.clientY, false,
  //									  false, false, false, 0/*left*/, null);
  //
  //			first.target.dispatchEvent(simulatedEvent);
  //			if (isDragging){
  //				e.preventDefault();
  //			}
  //		}
  //		
  //		if (document.addEventListener){
  //			document.addEventListener("touchstart", touchHandler, true);
  //			document.addEventListener("touchmove", touchHandler, true);
  //			document.addEventListener("touchend", touchHandler, true);
  //			document.addEventListener("touchcancel", touchHandler, true); 
  //		}
  //	});
  })(jQuery);
  