﻿/**
* EasyDrag 1.4 - Drag & Drop jQuery Plug-in
*
* Thanks for the community that is helping the improvement
* of this little piece of code.
*
* For usage instructions please visit http://fromvega.com
*/

(function ($) {

	// to track if the mouse button is pressed
	var isMouseDown = false;

	// to track the current element being dragged
	var currentElement = null;

	// callback holders
	var dropCallbacks = {};
	var dragCallbacks = {};

	// global position records
	var lastMouseX;
	var lastMouseY;
	var lastElemTop;
	var lastElemLeft;

	// track element dragStatus
	var dragStatus = {};

	// returns the mouse (cursor) current position
	$.getMousePosition = function (e) {
		var posx = 0;
		var posy = 0;

		if (!e) var e = window.event;

		if (e.pageX || e.pageY) {
			posx = e.pageX;
			posy = e.pageY;
		}
		else if (e.clientX || e.clientY) {
			posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
			posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
		}

		return { 'x': posx, 'y': posy };
	};

	// updates the position of the current element being dragged
	$.updatePosition = function (e) {
		var pos = $.getMousePosition(e);

		var spanX = (pos.x - lastMouseX);
		var spanY = (pos.y - lastMouseY);

		$(currentElement).css("top", (lastElemTop + spanY));
		$(currentElement).css("left", (lastElemLeft + spanX));
	};

	// when the mouse is moved while the mouse button is pressed
	$(document).mousemove(function (e) {
		if (isMouseDown && dragStatus[currentElement.id] == 'on') {
			// update the position and call the registered function
			$.updatePosition(e);
			if (dragCallbacks[currentElement.id] != undefined) {
				dragCallbacks[currentElement.id](e, currentElement);
			}

			return false;
		}
	});

	// when the mouse button is released
	$(document).mouseup(function (e) {
		if (isMouseDown && dragStatus[currentElement.id] == 'on') {
			isMouseDown = false;
			if (dropCallbacks[currentElement.id] != undefined) {
				dropCallbacks[currentElement.id](e, currentElement);
			}

			return false;
		}
	});

	// register the function to be called while an element is being dragged
	$.fn.ondrag = function (callback) {
		return this.each(function () {
			dragCallbacks[this.id] = callback;
		});
	};

	// register the function to be called when an element is dropped
	$.fn.ondrop = function (callback) {
		return this.each(function () {
			dropCallbacks[this.id] = callback;
		});
	};

	// stop the element dragging feature
	$.fn.dragOff = function () {
		return this.each(function () {
			dragStatus[this.id] = 'off';
		});
	};


	$.fn.dragOn = function () {
		return this.each(function () {
			dragStatus[this.id] = 'on';
		});
	};

	// set an element as draggable - allowBubbling enables/disables event bubbling
	$.fn.easydrag = function (allowBubbling) {

		return this.each(function () {

			// if no id is defined assign a unique one
			if (undefined == this.id || !this.id.length) this.id = "easydrag" + (new Date().getTime());

			// set dragStatus 
			dragStatus[this.id] = "on";

			// change the mouse pointer
			$(this).css("cursor", "move");

			// when an element receives a mouse press
			$(this).mousedown(function (e) {

				// set it as absolute positioned
				$(this).css("position", "absolute");

				// set z-index
				//$(this).css("z-index", "999");

				// update track variables
				isMouseDown = true;
				currentElement = this;

				// retrieve positioning properties
				var pos = $.getMousePosition(e);
				lastMouseX = pos.x;
				lastMouseY = pos.y;

				lastElemTop = this.offsetTop;
				lastElemLeft = this.offsetLeft;

				$.updatePosition(e);

				return allowBubbling ? true : false;
			});
		});
	};

})(jQuery);
