// DRAGNDROP.JS
// Motore di drag'n'drop. Bisogna settare esternamente la seguenti variabili-parametro:
// var floatingElements = [nomi dei layer da trascinare]
// var blackHoles = [nomi dei layer "attiranti"]
// var ray = tolleranza per porre un layer su un "blackhole"
// ------------------------------------------------------------------------------------
// dipende da: crossbrowser.js, pokerengine.js(per la funzione holeHandler richiamata in releaseElement)

// global variables

var selectedElement
var returnedElement		// riferimento all'elemento "catturato" che viene restituito alla funzione "holeHandler"
var selectedHole=""             //nome del "black hole" che ha appena "catturato" un elemento (stringa vuota altrimenti)
var offsetX, offsetY
var old_X, old_Y, old_Z		//coordinate iniziali del layer trascinato

document.onmousedown = grabElement
document.onmousemove = dragElement
document.onmouseup = releaseElement

//controllo di appartenenza ad un insieme
function belong(element, vector)
{
	numElem = vector.length;
	trovato = false;
	while (!trovato && numElem>0)
	{
		if (obj(vector[numElem-1]) == element)
                	trovato = true;
		numElem = numElem-1;
	}
	return trovato;
}

// Imposta l'elemento "selectedElement" (da trascinare)
function setSelectedElement(evt)
{
	selectedElement = null;
	if ( isN4 )
	{
		clickX = evt.pageX;
		clickY = evt.pageY;
		currentZ = 0;

		for ( i = floatingElements.length - 1; i >= 0 ; i--)
		{
			testObj = obj(floatingElements[i]);
			if ( testObj && (clickX > testObj.left) && (clickX < testObj.left + testObj.clip.width) && 
				(clickY > testObj.top) && (clickY < testObj.top+testObj.clip.height) &&
                                (testObj.zIndex > currentZ) )
				{	
					selectedElement = testObj;
                                        currentZ = testObj.zIndex; // per prendere il layer con zIndex piu' alto
				}
		}
	}
	else if (isIE)
	{
		imgObj = window.event.srcElement;
		if (imgObj.parentElement) selectedElement = imgObj.parentElement.style;
	}
	else // (isN6)
	{
		clickX = evt.pageX;
		clickY = evt.pageY;
		currentZ = 0;

		for ( i = floatingElements.length - 1; i >= 0 ; i--)
		{
			testObj = obj(floatingElements[i]);
			if ( testObj && (clickX > parseInt(testObj.left)) && (clickX < (parseInt(testObj.left) + 71)) && 
				(clickY > parseInt(testObj.top)) && (clickY < (parseInt(testObj.top) + 96)) &&
                                (parseInt(testObj.zIndex) > parseInt(currentZ)) )
				{	
					selectedElement = testObj;
                                        currentZ = testObj.zIndex; // per prendere il layer con zIndex piu' alto
				}
		}
	}
	if (selectedElement)
	{
		if (!belong(selectedElement,floatingElements))   // in realta' questo controllo non serve con netscape
			{                                          // perche' il controllo l'ho fatto su floatingElements
				selectedElement = null;
				return false;
			}
		else
			{
			  old_X=selectedElement.top;
			  old_Y=selectedElement.left;
			  old_Z=selectedElement.zIndex;
			  selectedElement.zIndex = 100;
			}
	}
	return;
}

// Imposta l'elemento da trascinare
function grabElement(evt)
{
	setSelectedElement(evt)
	if (selectedElement)
	{	
		if (isN4 || isN6)
		{
			offsetX = evt.pageX - parseInt(selectedElement.left);
			offsetY = evt.pageY - parseInt(selectedElement.top);
		}
		else
		{
			offsetX = window.event.offsetX;
			offsetY = window.event.offsetY;
		}
		return false; // se devo trascinare
	}
	else
		return true;  // se non devo trascinare
}

// Trascina l'elemento
function dragElement(evt)
{	
	if(selectedElement)
	{	
		if (isN4 || isN6)
		{	moveTo( selectedElement, (evt.pageX - offsetX), (evt.pageY - offsetY) );
		        
	 	}
		else
		{
			moveTo( selectedElement, (window.event.clientX - offsetX), (window.event.clientY - offsetY));
			return false;
		}
	}
	else
		return true;
}


// Rilascia l'elemento
function releaseElement(evt)
{
	if (selectedElement)
		if (isElementCaptured())
		{
			selectedElement.zIndex = old_Z;
			// holeHandler(): funzione che l'utente deve definire (non e' qui definita)
			// serve per gestire l'evento del "rilascio" di un layer
			returnedElement = selectedElement;
			selectedElement = null;
			holeHandler();
		}
	selectedElement = null;
}


//funzione di controllo sulla cattura dei layer
function isElementCaptured()
{
	lunVect=blackHoles.length;
        captured=false;
	sE_top=parseInt(selectedElement.top);	 //sE= selectedElement 
  	sE_left=parseInt(selectedElement.left);
        while (lunVect > 0 && captured == false )
        {       
		testObj = obj(blackHoles[lunVect-1])
		if (testObj) bH_top=parseInt(testObj.top);		 //bH= blackHole attuale
		if (testObj) bH_left=parseInt(testObj.left);																
		if (testObj && (sE_top >= bH_top - ray) &&	 	 //condizione di cattura 
                   (sE_top <= bH_top + ray) &&
                   (sE_left >= bH_left - ray) &&
                   (sE_left <= bH_left + ray) )
		{				
			selectedHole = blackHoles[lunVect-1];
			captured = true;
                        selectedElement.top = testObj.top;
                        selectedElement.left = testObj.left;
                        selectedElement.zIndex = parseInt(testObj.zIndex) + 1;
		}
		else
			lunVect--;
	}
        if( !captured)
	{
		selectedElement.top  = old_X;
		selectedElement.left = old_Y;
                selectedElement.zIndex = old_Z;
	}
        return captured;
}				 

// Recommendation:
// Before using a numeric property value, change it to numeric with "parseInt" function.
