/** Keep hold of the current table being dragged */
var currenttable = null;

/** Capture the onmousemove so that we can see if a row from the current
 *  table if any is being dragged.
 * @param ev the event (for Firefox and Safari, otherwise we use window.event for IE)
 */

document.onmousemove = function(ev){
    getMouseXY(ev);
	if (currenttable && currenttable.dragObject) {
        ev   = ev || window.event;
        var mousePos = currenttable.mouseCoords(ev);
        var y = mousePos.y - currenttable.mouseOffset.y;
        if (y != currenttable.oldY) {
            // work out if we're going up or down...
            var movingDown = y > currenttable.oldY;
            // update the old value
            currenttable.oldY = y;
            // update the style to show we're dragging
            currenttable.dragObject.style.backgroundColor = "#eee";
            // If we're over a row then move the dragged row to there so that the user sees the
            // effect dynamically
            var currentRow = currenttable.findDropTargetRow(y);
			var Elem;
			if (table.getAttribute("page")=="left")
			{
				if (currentRow) {
					if (movingDown && currenttable.dragObject != currentRow) {
						if (
							// Pas sur les entêtes
							currentRow.getAttribute("id")>1 
							// Pas droppable sur une sous cat sauf si on drag une autre sous cat
							&& (currentRow.getAttribute("Typec") != "sscat" || currenttable.dragObject.getAttribute("Typec") == "sscat")
							// Pas droppable sur une catégorie qui a des childs (Catégorie qui se glisse entre elle et ses childs) SAUF si on drop un de ses childs
							&& (
								currentRow.getAttribute("childs") == ""	
								|| 
								currenttable.dragObject.getAttribute("parent")==currentRow.getAttribute("id")
								|| 
								currenttable.dragObject.getAttribute("Typec") == "sscat"
								)
							// Si la dernière ligne est une sous cat et que la selection est une cat, on la passe
							|| (currenttable.dragObject.getAttribute("Typec") == "cat" 
								&&
								currentRow.getAttribute("Typec") == "sscat" 
								&&
								currentRow.nextSibling.nodeName != "TR"
								
								)
							
							)
							
						{
							//document.getElementById("debug").innerHTML = currentRow.nextSibling.nodeName + "<br>" + document.getElementById("debug").innerHTML;
							Elem = currenttable.dragObject.parentNode.insertBefore(currenttable.dragObject, currentRow.nextSibling);
							// Bouge les childs
							if (currenttable.dragObject.getAttribute("childs") != "")
							{
								var reg=new RegExp("[;]+", "g");
								var tableau=currenttable.dragObject.getAttribute("childs").split(reg);
								for (var i=0; i<tableau.length; i++)
								{
									Elem = Elem.parentNode.insertBefore(document.getElementById(tableau[i]), Elem.nextSibling);
								}
							}
							// Bouge une sous Catégorie dans une autre catégorie

						}
					} else if (! movingDown && currenttable.dragObject != currentRow) {
						 if (
							// Pas sur les entêtes
							currentRow.getAttribute("id")>1 
							// Pas droppable sur une sous cat sauf si on drag une autre sous cat
							&& (currentRow.getAttribute("Typec") != "sscat" || currenttable.dragObject.getAttribute("Typec") == "sscat")
							// Bloquage en montant une sous cat sur Acceuil
							&& (currenttable.dragObject.getAttribute("Typec") == "cat"
								|| 
									(currenttable.dragObject.getAttribute("Typec") == "sscat" 
									&& 
									currentRow.previousSibling.getAttribute("canchild")))
							)
						{
							Elem = currenttable.dragObject.parentNode.insertBefore(currenttable.dragObject, currentRow);
							// Bouge les childs
							if (currenttable.dragObject.getAttribute("childs") != "")
							{
								var reg=new RegExp("[;]+", "g");
								var tableau=currenttable.dragObject.getAttribute("childs").split(reg);
								for (var i=0; i<tableau.length; i++)
								{
									Elem = Elem.parentNode.insertBefore(document.getElementById(tableau[i]), Elem.nextSibling);
								}
							}
						}
					}
				}
			}
			else if (table.getAttribute("page")=="article")
			{
				if (currentRow) 
				{
					if (movingDown && currenttable.dragObject != currentRow) 
					{
						if (
						currenttable.dragObject.getAttribute("parent") == currentRow.getAttribute("parent")
						&& 
						currenttable.dragObject.getAttribute("typec") == currentRow.getAttribute("typec")
						)
						{
							Elem = currenttable.dragObject.parentNode.insertBefore(currenttable.dragObject, currentRow.nextSibling);
						}
					} 
					else if (! movingDown && currenttable.dragObject != currentRow) 
					{
						if (
						currenttable.dragObject.getAttribute("parent") == currentRow.getAttribute("parent")
						&& 
						currenttable.dragObject.getAttribute("typec") == currentRow.getAttribute("typec")
						)
						{
						Elem = currenttable.dragObject.parentNode.insertBefore(currenttable.dragObject, currentRow);
						}
					}
				}
			}
			else
			{
				if (currentRow) {
					if (currentRow.getAttribute("id")>0) {
						if (movingDown && currenttable.dragObject != currentRow) {
						Elem = currenttable.dragObject.parentNode.insertBefore(currenttable.dragObject, currentRow.nextSibling);
						} else if (! movingDown && currenttable.dragObject != currentRow) {
						Elem = currenttable.dragObject.parentNode.insertBefore(currenttable.dragObject, currentRow);}
						}
					}
			}
		}
        return false;
    }
}

// Similarly for the mouseup
document.onmouseup   = function(ev){
    if (currenttable && currenttable.dragObject) {
        var droppedRow = currenttable.dragObject;
        // If we have a dragObject, then we need to release it,
        // The row will already have been moved to the right place so we just reset stuff
        droppedRow.style.backgroundColor = 'transparent';
        currenttable.dragObject   = null;
        // And then call the onDrop method in case anyone wants to do any post processing
        currenttable.onDrop(currenttable.table, droppedRow);
		doUpdate(currenttable.table);
        currenttable = null; // let go of the table too
    }
}


/** get the source element from an event in a way that works for IE and Firefox and Safari
 * @param evt the source event for Firefox (but not IE--IE uses window.event) */
function getEventSource(evt) {
    if (window.event) {
        evt = window.event; // For IE
        return evt.srcElement;
    } else {
        return evt.target; // For Firefox
    }
}

/**
 * Encapsulate table Drag and Drop in a class. We'll have this as a Singleton
 * so we don't get scoping problems.
 */
function TableDnD() {
    /** Keep hold of the current drag object if any */
    this.dragObject = null;
    /** The current mouse offset */
    this.mouseOffset = null;
    /** The current table */
    this.table = null;
    /** Remember the old value of Y so that we don't do too much processing */
    this.oldY = 0;

    /** Initialise the drag and drop by capturing mouse move events */
    this.init = function(table) {
        this.table = table;
        var rows = table.tBodies[0].rows; //getElementsByTagName("tr")
        for (var i=0; i<rows.length; i++) {
			// John Tarr: added to ignore rows that I've added the NoDnD attribute to (Category and Header rows)
			var nodrag = rows[i].getAttribute("NoDrag")
			if (nodrag == null || nodrag == "undefined") { //There is no NoDnD attribute on rows I want to drag
				this.makeDraggable(rows[i]);
			}
        }
    }

    /** This function is called when you drop a row, so redefine it in your code
        to do whatever you want, for example use Ajax to update the server */
    this.onDrop = function(table, droppedRow) {
		if (table.getAttribute("page")=="actu")
		{
			// Do update in Database (Ajax)
			// Make the whole table
			var rows = table.tBodies[0].rows; //getElementsByTagName("tr")
			First = true;
			for (var i=1; i<rows.length; i++)
			{
				if (First)
				{
					AjaxTable = rows[i].getAttribute("id") + ":" + i;
					First = false;
				}
				else
				{
					AjaxTable += ";" + rows[i].getAttribute("id") + ":" + i;
					First = false;
				}
			}
			doUpdate(AjaxTable, table.getAttribute("page"));
		}
		else if (table.getAttribute("page")=="article")
		{
			var rows = table.tBodies[0].rows; //getElementsByTagName("tr")
			First = true;
			var CurrentCat = "";
			for (var i=1; i<rows.length; i++)
			{
				if (First)
				{
					if (rows[i].getAttribute("Typec")=="sscat0" || rows[i].getAttribute("Typec")=="sscat1" || rows[i].getAttribute("Typec")=="sscat2" || rows[i].getAttribute("Typec")=="sscat3")
					{
						AjaxTable = rows[i].getAttribute("id") + ":" + i;
						First = false;
					}
					
				}
				else
				{
					if (rows[i].getAttribute("Typec")=="sscat0" || rows[i].getAttribute("Typec")=="sscat1" || rows[i].getAttribute("Typec")=="sscat2" || rows[i].getAttribute("Typec")=="sscat3")
					{
						AjaxTable += ";"+ rows[i].getAttribute("id") + ":" + i;
						First = false;
					}
				}
			}
			doUpdate(AjaxTable, table.getAttribute("page"));
		}
		else if(table.getAttribute("page") == "left")
		{
			var rows = table.tBodies[0].rows; //getElementsByTagName("tr")
			First = true;
			var CurrentCat = "";
			for (var i=1; i<rows.length; i++)
			{
				if (rows[i].getAttribute("Typec")=="cat")
				{
					CurrentCat = rows[i].getAttribute("id");
					rows[i].setAttribute("childs", "");
				}
				if (First)
				{
					AjaxTable = rows[i].getAttribute("id") + ":" + i;
					if (rows[i].getAttribute("Typec")=="sscat")
					{
						rows[i].setAttribute("parent",CurrentCat);
						if (document.getElementById(CurrentCat).getAttribute("childs") == "")
						{
							document.getElementById(CurrentCat).setAttribute("childs", rows[i].getAttribute("id"));
						}
						else
						{
							document.getElementById(CurrentCat).setAttribute("childs", document.getElementById(CurrentCat).getAttribute("childs")+ ";"+rows[i].getAttribute("id"));
						}
						
						AjaxTable += ":" + CurrentCat;
					}
					else
					{
						AjaxTable += ":" + 1;
					}
					First = false;
				}
				else
				{
					AjaxTable += ";"+ rows[i].getAttribute("id") + ":" + i;
					if (rows[i].getAttribute("Typec")=="sscat")
					{
						rows[i].setAttribute("parent",CurrentCat);
						if (document.getElementById(CurrentCat).getAttribute("childs") == "")
						{
							document.getElementById(CurrentCat).setAttribute("childs", rows[i].getAttribute("id"));
						}
						else
						{
							document.getElementById(CurrentCat).setAttribute("childs", document.getElementById(CurrentCat).getAttribute("childs")+ ";"+rows[i].getAttribute("id"));
						}
						
						AjaxTable += ":" + CurrentCat;
					}
					else
					{
						AjaxTable += ":" + 1;
					}
					First = false;
				}
			}
			doUpdate(AjaxTable, table.getAttribute("page"));
		}
		else if (table.getAttribute("page")=="top")
		{
			// Do update in Database (Ajax)
			// Make the whole table
			var rows = table.tBodies[0].rows; //getElementsByTagName("tr")
			First = true;
			for (var i=1; i<rows.length; i++)
			{
				if (First)
				{
					AjaxTable = rows[i].getAttribute("id") + ":" + i;
					First = false;
				}
				else
				{
					AjaxTable += ";" + rows[i].getAttribute("id") + ":" + i;
					First = false;
				}
			}
			doUpdate(AjaxTable, table.getAttribute("page"));
		}
		else if (table.getAttribute("page")=="bottom")
		{
			// Do update in Database (Ajax)
			// Make the whole table
			var rows = table.tBodies[0].rows; //getElementsByTagName("tr")
			First = true;
			for (var i=1; i<rows.length; i++)
			{
				if (First)
				{
					AjaxTable = rows[i].getAttribute("id") + ":" + i;
					First = false;
				}
				else
				{
					AjaxTable += ";" + rows[i].getAttribute("id") + ":" + i;
					First = false;
				}
			}
			doUpdate(AjaxTable, table.getAttribute("page"));
		}
		return false;
    }

	/** Get the position of an element by going up the DOM tree and adding up all the offsets */
    this.getPosition = function(e){
        var left = 0;
        var top  = 0;
		/** Safari fix -- thanks to Luis Chato for this! */
		if (e.offsetHeight == 0) {
			/** Safari 2 doesn't correctly grab the offsetTop of a table row
			    this is detailed here:
			    http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/
			    the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild.
			    note that firefox will return a text node as a first child, so designing a more thorough
			    solution may need to take that into account, for now this seems to work in firefox, safari, ie */
			e = e.firstChild; // a table cell
		}

        while (e.offsetParent){
            left += e.offsetLeft;
            top  += e.offsetTop;
            e     = e.offsetParent;
        }

        left += e.offsetLeft;
        top  += e.offsetTop;

        return {x:left, y:top};
    }

	/** Get the mouse coordinates from the event (allowing for browser differences) */
    this.mouseCoords = function(ev){
        if(ev.pageX || ev.pageY){
            return {x:ev.pageX, y:ev.pageY};
        }
        return {
            x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
            y:ev.clientY + document.body.scrollTop  - document.body.clientTop
        };
    }

	/** Given a target element and a mouse event, get the mouse offset from that element.
		To do this we need the element's position and the mouse position */
    this.getMouseOffset = function(target, ev){
        ev = ev || window.event;

        var docPos    = this.getPosition(target);
        var mousePos  = this.mouseCoords(ev);
        return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
		
		item.style.cursor = "url(images/cursor_hand.cur), move";
    }

	/** Take an item and add an onmousedown method so that we can make it draggable */
    this.makeDraggable = function(item) {
        if(!item) return;
        var self = this; // Keep the context of the TableDnd inside the function
        item.onmousedown = function(ev) {
            // Need to check to see if we are an input or not, if we are an input, then
            // return true to allow normal processing
            var target = getEventSource(ev);
            if (target.tagName == 'INPUT' || target.tagName == 'SELECT') return true;
            currenttable = self;
            self.dragObject  = this;
            self.mouseOffset = self.getMouseOffset(this, ev);
            return false;
        }
		
        item.style.cursor = "move";
    }

    /** We're only worried about the y position really, because we can only move rows up and down */
    this.findDropTargetRow = function(y) {
        var rows = this.table.tBodies[0].rows;
		for (var i=0; i<rows.length; i++) {
			var row = rows[i];
			// John Tarr added to ignore rows that I've added the NoDnD attribute to (Header rows)
			var nodrop = row.getAttribute("NoDrop");
			if (nodrop == null || nodrop == "undefined") {  //There is no NoDnD attribute on rows I want to drag
				var rowY    = this.getPosition(row).y;
				var rowHeight = parseInt(row.offsetHeight)/2;
				if (row.offsetHeight == 0) {
					rowY = this.getPosition(row.firstChild).y;
					rowHeight = parseInt(row.firstChild.offsetHeight)/2;
				}
				// Because we always have to insert before, we need to offset the height a bit
				if ((y > rowY - rowHeight) && (y < (rowY + rowHeight))) {
					// that's the row we're over
					return row;
				}
			}
		}
		return null;
	}
}
/** For Ajax purpose **/
function doUpdate(AjaxTable, Page)
{
	// alert('scripts/AjaxActualites.php?table='+ (AjaxTable));
	if (Page == "actu")
	{
		file('scripts/AjaxActualites.php?table='+ escape(AjaxTable));
	}
	else if (Page == "article")
	{
		file('scripts/AjaxArticles.php?table='+ escape(AjaxTable));
	}
	else if (Page == "left")
	{
		file('scripts/AjaxCategoriesLeft.php?table=' + escape(AjaxTable));
	}
	else if (Page == "top")
	{
		file('scripts/AjaxCategoriesTop.php?table='+ escape(AjaxTable));
	}
	else if (Page == "bottom")
	{
		file('scripts/AjaxCategoriesBottom.php?table='+ escape(AjaxTable));
	}
}

function file(fichier)
 {
 if(window.XMLHttpRequest) // FIREFOX
	  xhr_object = new XMLHttpRequest();
 else if(window.ActiveXObject) // IE
	  xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
 else
	  return(false);
 xhr_object.open("GET", fichier, false);
 xhr_object.send(null);
 if(xhr_object.readyState == 4) return(xhr_object.responseText);
 else return(false);
 }


