﻿jOrdering = function(id, elementsArray) {
	//initialize with the given date as the selected date
	this.initialize(id, elementsArray);
}

var jO = jOrdering.prototype;
/**************
The id is used by ordering objects to refer to html elements tied to themselves;
this was done basically to allow multiple orderings to exist within a page;
**************/
jO.id = "";
/***************
2D dimensional array with height of 3 and length n; it includes a list of n elements to be dynamically sorted by user;
the height 2 is due to the fact that element name and id is passed to the array;
***************/
jO.elementsArray = "";
/**************
Tells the event handler whether the user is currently dragging an item
***************/
jO.dragging = false;
/**************
Tells the event handler which item is currently being dragged and what are its original coordinates
***************/
jO.selectedItem = null;
jO.selectedItemIndex = null;
jO.mouseX = null;
jO.mouseY = null;
/**************
This is the css height in pixels of one element;
It needs to include the actual height, double the border width and what ever number of pixesl you want to separate consecutive elements;
For the default case I have a div of height 20px, with border width of 1px and I wanted to separate each div by 1px. Applying the formula
mentioned above it all sums up to 23
************/
jO.elemHeight = 23;

jO.initialize = function(id, elementsArray) {
	this.id = id;
	this.elementsArray = elementsArray;
	this.dragging = false;
	this.selectedItem = null;
	this.selectedItemIndex = null;
	this.mouseX = null;
	this.mouseY = null;
	this.elemHeight = 23;
}

jO.writeDynamicOrderer = function (panelNo, displayCoordinates) {
	if (this.elementsArray.length > 0) {
		document.write("<div id=\"" + this.id + "container\" class=\"ordererContainer\" style=\"height:" + (5 + (this.elemHeight*this.elementsArray.length))+ "px\" onmousemove=\"" + this.id + ".drag(event);\" onmouseup=\"" + this.id + ".deactivateDrag(event);\" onselectstart=\"return false;\">");
		for(var i = 0; i < this.elementsArray.length; i++) {
			document.write("	<input type=\"hidden\" name=\"hid" + this.id + this.elementsArray[i][1] + "\" id=\"hid" + this.id + this.elementsArray[i][1] + "\" value=\"" + i + "\">");
			document.write("	<div id=\"" + this.id + this.elementsArray[i][1] + "\" class=\"ordererElement\" onmouseover=\"this.className = 'ordererElementHover';\" onmouseout=\"this.className = 'ordererElement';\" style=\"top:" + (3+(this.elemHeight*i)) + "px;\" onmousedown=\"" + this.id + ".activateDrag(this, event, " + i + ");\" onselectstart=\"return false;\">");
			document.write("		<span style=\"float:left;\" id=\"span"+ this.id + this.elementsArray[i][1] + "\">" + (i + 1) +")</span> " + this.elementsArray[i][0]);
			document.write("	</div>");
		}
	}
	else {
		document.write("<div id=\"" + this.id + "container\" class=\"ordererContainer\">");
		document.write(" No Columns have been specified.");
	}
	document.write("</div>");
}

jO.activateDrag = function(element, ev, sIndex) {
	this.selectedItem = element;
	this.selectedItemIndex = sIndex;
	var pos = mousePosition(ev);	
	this.mouseX = pos.x;
	this.mouseY = pos.y;
	for (var i = 0; i < this.elementsArray.length; i++) {
		document.getElementById(this.id + this.elementsArray[i][1]).style.zIndex = "100";
	}
	element.style.zIndex = "1000";
	this.dragging = true;
}

jO.deactivateDrag = function() {
	// first deactivate drag
	this.dragging = false;
	
	// now reposition the selected
	this.selectedItem.style.top = (3 + (document.getElementById("hid" + this.id + this.elementsArray[this.selectedItemIndex][1]).value * this.elemHeight)) + "px";
	
	// clear out selectedIndex variables
	this.selectedItem = null;
	this.selectedItemIndex = null;
	this.mouseX = null;
	this.mouseY = null;
}

jO.drag = function(ev) {
	if (this.dragging == true) {
		// calculate the new position of the element based on how far the mouse moved
		var pos = mousePosition(ev);
		var currentTop = parseInt(this.selectedItem.style.top.replace("px", ""));
		if (currentTop + (pos.y-this.mouseY) < 3) {
			this.selectedItem.style.top = "3px";
		}
		else if (currentTop + (pos.y-this.mouseY) > 3 + (this.elemHeight * (this.elementsArray.length -1))) {
			this.selectedItem.style.top = (3 + (this.elemHeight * (this.elementsArray.length -1))) + "px";
		}
		else {
			this.selectedItem.style.top = (currentTop + (pos.y-this.mouseY)) + "px";
		}
		
		// update the other elements' positioning
		var currentOrder = parseInt(document.getElementById("hid" + this.id + this.elementsArray[this.selectedItemIndex][1]).value);
		currentTop = parseInt(this.selectedItem.style.top.replace("px", ""));
		if (currentTop < ((currentOrder * this.elemHeight) -8)) {
			// we need to move the element above underneath the one being dragged
			for(var i = 0; i < this.elementsArray.length; i++) {
				if (parseInt(document.getElementById("hid" + this.id + this.elementsArray[i][1]).value) == (currentOrder - 1)) {
					document.getElementById("hid" + this.id + this.elementsArray[i][1]).value = currentOrder;
					document.getElementById("span" + this.id + this.elementsArray[i][1]).innerHTML = (currentOrder + 1) + ")";
					document.getElementById(this.id + this.elementsArray[i][1]).style.top = (3 + (currentOrder * this.elemHeight)) + "px";
					break;
				}
			}
			document.getElementById("hid" + this.id + this.elementsArray[this.selectedItemIndex][1]).value = currentOrder - 1;
			document.getElementById("span" + this.id + this.elementsArray[this.selectedItemIndex][1]).innerHTML = currentOrder + ")";
		}
		else if (currentTop > ((currentOrder * this.elemHeight) + 14)) {
			// we need to move the element beneath above the one being dragged
			for(var i = 0; i < this.elementsArray.length; i++) {
				if (parseInt(document.getElementById("hid" + this.id + this.elementsArray[i][1]).value) == (currentOrder + 1)) {
					document.getElementById("hid" + this.id + this.elementsArray[i][1]).value = currentOrder;
					document.getElementById("span" + this.id + this.elementsArray[i][1]).innerHTML = (currentOrder + 1) + ")";
					document.getElementById(this.id + this.elementsArray[i][1]).style.top = (3 + (currentOrder * this.elemHeight)) + "px";
					break;
				}
			}
			document.getElementById("hid" + this.id + this.elementsArray[this.selectedItemIndex][1]).value = currentOrder + 1;
			document.getElementById("span" + this.id + this.elementsArray[this.selectedItemIndex][1]).innerHTML = (currentOrder + 2) + ")";
		}
		
		// update the mouse coordinates
		this.mouseY = pos.y;
	}
}

jO.reOrder = function(newOrderArray) {
	var tempElemID = 0;
	for(var i = 0; i < this.elementsArray.length; i++) {
		tempElemID = newOrderArray[i];
		document.getElementById("hid" + this.id + tempElemID).value = i;
		document.getElementById("span" + this.id + tempElemID).innerHTML = (i + 1) + ")";
		document.getElementById(this.id + tempElemID).style.top = (3 + (i * this.elemHeight)) + "px";
	}
}

function mousePosition(ev) {
	var posY = 0;
	posY=(ev||event).clientY;
	if (document.documentElement.scrollTop > 0) {
		posY = posY + document.documentElement.scrollTop;
	}	
	return {y: posY};
}
