/*
 * jQuery Draggable 0.1- A simple jQuery plugin for draggin' stuff
 *
 * Copyright (c) 2008 Rogie King (komodomedia.com)
*
 * $Date: 2008-07-22 $
 * $Rev: 1 $
 */
(function ($) {
    $.fn.draggable = function ( opts ) {
	
	var opts = $.extend(
		{
			lockX:false,
			lockY:false,
			constrainTo:null,
			onDrag: function(){},
			onRelease: function(){}
		},opts);
	var jqObjects 	= $(this);
	var jqDragging 	= null;
	var jqClone		= null;
	var jqConstrainTo = opts.constrainTo? $(opts.constrainTo) : null;
	var lastOffset = null;
	
	//first, add a mouseup and down function to the document
	$(document)
    	.mouseup( 
    		function( e ){ 
    			//only run the mouseup function if this is dragging
    			if( jqDragging && jqClone){
    			
    				var x = jqClone.offset().left;
    				var y = jqClone.offset().top;
    				var delta = {};
    				
    				if( jqConstrainTo ){
    					x = x - jqConstrainTo.offset().left;
    					y = y - jqConstrainTo.offset().top;
    					delta.percentLeft = x/(jqConstrainTo.width() - jqClone.width());
    					delta.percentTop = (y/(jqConstrainTo.height() - jqClone.height())) || 0;
    				}
    				delta.left 	= x;
    				delta.top 	= y;
    				
    				//dispatch the on release event handler
    				opts.onRelease.call( jqClone.get(0), delta);
    				    				
    				//lastly, when dragging stops, restore the old dragged item
    				//and remove the clone
    				jqClone.remove();    				
    				
    				//and now show the original item and translate it's new 
    				jqDragging.removeClass('dragging').show();
    				
    			}
    			if( jqDragging ) jqDragging.removeClass('dragging');
    			$('body').css({cursor:''});
    			jqClone = null;
    			jqDragging = null;
    			
    		} 
    	)
    	.mousemove( function(e){	    				
    		
    		if( jqDragging && !jqClone){
    			
    			if( jqClone )	jqClone.remove();
    			
    			jqClone = jqDragging
    						.clone(true)
    						.css(
    							{
    								position:'absolute', 
    								zIndex: parseInt( new Date().getTime()/1000) 
    							})
    						.appendTo('body');
    			
    			//make a dragging cursor
    			$('body').css({cursor: 'grabbing'}).css({cursor: '-moz-grabbing'});
    						
    			//hide the other one
    			jqDragging.hide();
    			    						
    		}
    		
    		if( jqDragging ){
    			
    			var x = e.pageX - jqClone.width()/2;
    			var y = e.pageY - jqClone.height()/2;
    			
    			
    			if( jqConstrainTo ){
    				
    				ctOffset = jqConstrainTo.offset();
    				
    				if( x < parseInt(ctOffset.left) ){
    					x = ctOffset.left;
    				}else if( x + jqClone.width() > parseInt(ctOffset.left) + jqConstrainTo.width() ){
    					x = parseInt(ctOffset.left) + jqConstrainTo.width() - jqClone.width();
    				}
    				
    				if( y < parseInt(ctOffset.top) ){
    					y = ctOffset.top;
    				}else if( y + jqClone.height() > parseInt(ctOffset.top) + jqConstrainTo.height() ){
    					y = parseInt(ctOffset.top) + jqConstrainTo.height() - jqClone.height();
    				}
    			
    			}
    			if( opts && !opts.lockX ){
    				jqClone.css( {left: x} );
    			}
    			if( opts && !opts.lockY ){
    				jqClone.css( {top:y} );
    			}
    			
    			//calculate the change in position
    			var xDelta = jqClone.offset().left - lastOffset.left;
    			var yDelta = jqClone.offset().top - lastOffset.top;
    			
    			//reset the new offset
    			lastOffset = jqClone.offset();
    			
    			//now, set the change
    			jqDragging.css( {left: parseInt(jqDragging.css('left')) + xDelta,
    							top:parseInt(jqDragging.css('top')) + yDelta});
    			
    		}
    	} );
    	
    //create a mouse down function for initiating drag
    jqObjects
		.mousedown( 
			function( e ){ 
				e.stopPropagation();
				e.preventDefault();
				
				jqDragging = $(this);
				
				//set this to either absolute or relative
				if( jqDragging.css('position') != 'absolute' ){
					jqDragging.css({position:'relative'});
				}
				
				//log the last coordinates
				lastOffset = jqDragging.offset();
											
				//dispatch the ondrag event
				opts.onDrag.call( jqDragging.get(0), e);
			} 
		);

  };
})(jQuery);