/*************
dragdrop.js
This drag & drop script is used for dragging a word into a sentence.
*************/
/** correct and incorrect is added in global.js also **/
var correct=new Image(25,25);
correct.src="/lls/llonline/assets/images/correct.gif";
var incorrect=new Image(25,25);
incorrect.src="/lls/llonline/assets/images/incorrect.gif";

var evt=new universalEvent();
if (typeof(lls) == "undefined") var lls = new Object();
if (typeof(lls.dhtml) == "undefined") lls.dhtml = new Object();

lls.dhtml.dragObject = function(oid) {
	if (te=document.getElementById(oid)) {
		this.type=1;
		this.id=oid;
		this.ref=te;
		this.x=null;
		this.y=null;
		this.org_x=null;
		this.org_y=null;
		this.org_m_x=null;
		this.org_m_y=null;
		this.moveSpan=null;
		this.feedbackTick=null;
		this.dropped=false;		//dropped is true if dnd object was placed ok.
		this.dragState=false;	// false=dropped, true=dragging
		this.ident=parseInt(this.id.substr(this.id.lastIndexOf("-")+1));
		this.correctPos=parseInt(document.getElementById("dnd-pos-"+this.ident).firstChild.nodeValue);

		//setup look & feel of object
		this.ref.style.cursor="crosshair";
		this.ref.onmousedown=this.pick;
		this.ref.onmouseup=this.drop;
		this.ref.onclick=this.cancelEvent;
		this.ref.ondblclick=this.cancelEvent;

		//get coords of target sentence for comparison when dragging over.
		this.dndSen = document.getElementById(this.id.substr(0,4) + this.id.substr(this.id.lastIndexOf("-")+1));
		if (this.dndSen) {
			this.dndSen_tl_x = getTotalOffset(this.dndSen,"left");
			this.dndSen_tl_y = getTotalOffset(this.dndSen,"top");
			this.dndSen_br_x = this.dndSen_tl_x + this.dndSen.offsetWidth;
			this.dndSen_br_y = this.dndSen_tl_y + this.dndSen.offsetHeight + 10;
			this.setupSentence();
		}
		setupPointer();
		this.resetBut = isIE?document.createElement("<input onclick=\"findDNDById('"+this.id+"').reset()\"'>"):document.createElement("input");
		this.resetBut.setAttribute("type","button");
		this.resetBut.setAttribute("value","Reset");
		insertAfter(this.resetBut,this.dndSen.nextSibling.nextSibling);
		if (isGecko) this.resetBut.setAttribute("onclick","findDNDById('"+this.id+"').reset()");
		this.ansBut = isIE?document.createElement("<input onclick=\"findDNDById('"+this.id+"').answer()\"'>"):document.createElement("input");
		this.ansBut.setAttribute("type","button");
		this.ansBut.setAttribute("value","Show answer");
		insertAfter(this.ansBut,this.resetBut);
		if (isGecko) this.ansBut.setAttribute("onclick","findDNDById('"+this.id+"').answer()");

		this.ref.style.left=getTotalOffset(this.ref,"left")+"px";
		this.ref.style.top=getTotalOffset(this.ref,"top")+"px";
		this.centreX = getTotalOffset(this.ref,"left") + (this.ref.offsetWidth/2);
		this.centreY = getTotalOffset(this.ref,"top") + (this.ref.offsetHeight/2);

		//create space on page where Div was when in static position.
		var temp;
		temp = this.ref.cloneNode(true);
		this.ref.parentNode.insertBefore(temp,this.ref);
		temp.style.visibility="hidden";
		temp.style.position="static";
		this.startPos = temp;
		this.ref.style.position="absolute";

	}
	else alert("LLS dhtml: Drag object '" + oid + "' not found. Drag and Drop creation failed");

}

lls.dhtml.dragObject.prototype.reset = function() {
	if (this.moveSpan.parentNode) this.moveSpan.parentNode.removeChild(this.moveSpan);
	this.feedbackTick.src = "/lls/llonline/assets/images/spacer.gif";
	this.ref.style.left=getTotalOffset(this.startPos,"left")+"px";
	this.ref.style.top=getTotalOffset(this.startPos,"top")+"px";
	this.centreX = getTotalOffset(this.ref,"left") + (this.ref.offsetWidth/2);
	this.centreY = getTotalOffset(this.ref,"top") + (this.ref.offsetHeight/2);
	this.ref.style.display="block";
	this.dropped=false;
}

lls.dhtml.dragObject.prototype.answer = function() {
	this.ref.style.display="none";
	var spans = this.dndSen.getElementsByTagName("span");
	for (var i=0;i<spans.length;i++) {
		if (i==this.correctPos) {
			spans[i].parentNode.insertBefore(this.moveSpan,spans[i]);
			this.moveSpan.style.display="inline";
			this.feedbackTick.src=correct.src;
			return true;
		}
	}
	return false;
}

lls.dhtml.dragObject.prototype.pick = function(e) {
	evt.refresh(e);
	evt.cancel();
	var dnd = findDNDById(evt.evtSrcId);
	dnd.org_m_x = evt.mouseX;
	dnd.org_m_y = evt.mouseY;
	dnd.org_x = parseInt(dnd.ref.style.left);
	dnd.org_y = parseInt(dnd.ref.style.top);
	dnd.dragState=true;
	currentDragged = dnd;
}

var drag = function(e) {
	if (!currentDragged) return false;
	evt.cancel();
	evt.refresh(e);
	var dnd = currentDragged,hs;
	if (!dnd.dragState) return false;	//cancel if not dragging
	//alert(dnd.ref.style.left);
	dnd.ref.style.left = (dnd.org_x + (evt.mouseX-dnd.org_m_x)) + "px";
	dnd.ref.style.top = (dnd.org_y + (evt.mouseY-dnd.org_m_y)) + "px";
	dnd.centreX = getTotalOffset(dnd.ref,"left") + (dnd.ref.offsetWidth/2);
	dnd.centreY = getTotalOffset(dnd.ref,"top") + (dnd.ref.offsetHeight/2);
	if (dnd.type == 1) {
		if (checkOverlap(dnd)) {
			if (hs=findHoverSpan(dnd)) {
				pointer.style.display="block";
				pointer.style.top = (getTotalOffset(hs,"top") + hs.offsetHeight) + "px";
				pointer.style.left = (getTotalOffset(hs,"left") + (hs.offsetWidth-7)) + "px";
			}
			else pointer.style.display="none";
		}
		else pointer.style.display="none";
	}
	else if (dnd.type == 2) {
		if (checkOverlap2(dnd)) {
			dnd.bin.style.border="solid 1px red";
		}
		else dnd.bin.style.border="solid 1px white";
	}
}

lls.dhtml.dragObject.prototype.drop = function(e) {
	evt.refresh(e);
	var dnd = findDNDById(evt.evtSrcId),hs;
	if (!dnd) dnd = currentDragged;
	if (!dnd.dragState) return false;	//cancel if not dragging
	evt.cancel();
	dnd.ref.style.color="#000";
	if (checkOverlap(dnd)) {
		if (hs=findHoverSpan(dnd)) {		//found a drop position
			insertAfter(dnd.moveSpan,hs);
			dnd.moveSpan.style.display="inline";
			dnd.ref.style.display="none";
			pointer.style.display="none";
			//evaluate correctness
			hsnum = parseInt(hs.id.substr(hs.id.lastIndexOf("-")+1));
			if (hsnum+1 == dnd.correctPos) dnd.feedbackTick.src = correct.src;
			else dnd.feedbackTick.src = incorrect.src;
			dnd.dropped=true;
		}
		else dnd.returnDrag();
	}
	else dnd.returnDrag();
	dnd.dragState=false;
	currentDragged = null;
}

lls.dhtml.dragObject.prototype.returnDrag = function() {
	this.ref.style.left = this.org_x + "px";
	this.ref.style.top = this.org_y + "px";
}

lls.dhtml.dragObject.prototype.cancelEvent = function(e) {
	evt.cancel();
	// now unselect text if anything has been selected by (double)clicking.
	if (isIE) document.selection.empty();
	else if (isGecko) window.getSelection().removeAllRanges();
}

lls.dhtml.dragObject.prototype.setupSentence = function() {
	var words = this.dndSen.firstChild.nodeValue.split(" "),i,sp;
	removeChildElements(this.dndSen);
	for(i=0;i<words.length; i++) {
		sp = document.createElement("span");
		sp.appendChild(document.createTextNode(words[i] + " "));
		sp.id="dnd-" + this.ident + "-sp-" + i;
		this.dndSen.appendChild(sp);
	}
	sp=document.createElement("sp");
	sp.appendChild(document.createTextNode(this.ref.firstChild.nodeValue + " "));
	sp=this.dndSen.appendChild(sp);
	sp.style.display="none";
	sp.id="moveSpan-"+this.ident;
	this.moveSpan=sp;

	var img = document.createElement("img");
	img.setAttribute("src","/lls/llonline/assets/images/spacer.gif");
	img.width=25;
	img.height=25;
	this.feedbackTick = img;
	this.dndSen.appendChild(img);
}

var dobjs=new Array();
var dragObject = lls.dhtml.dragObject;
var currentDragged = null;

var rePositionDrags = function() {
	return false;
	var darray;
	
	if (dints) darray = dints;
	else if (dobjs) darray = dobjs;
	
	var i;
	for(i=0;i<darray.length;i++) {
		if (dobjs) {
			if (!dobjs[i].dropped) dobjs[i].reset();
		}
		else if (dints) {
			for(j=0;j<dints[i].dobjs.length;j++) {
				if (!dints[i].dobjs[j].dropped) dints[i].dobjs[j].reset();
			}
		}
	}
}

var createDNDs = function() {
	var i;
	for(i=0; i<arguments.length; i++) {
		dobjs[i] = new dragObject(arguments[i]);
	}
	
	// New code to fix the error dints begins here..this needs more testing on all areas
	if (!dints)
	{
		var dints	=	new Array();
		dints		=	dobjs;
	}
	// New code to fix the error dints ends here
	
	document.onmouseup=cancelDrags;
	document.onmousemove=drag;
	window.onresize=rePositionDrags;
}

var findDNDById = function(oid) {
	var i;
	for(i=0;i<dobjs.length;i++) {
		if (dobjs[i].id == oid) return dobjs[i];
	}
	return null;
}

var cancelDrags = function() {
	var darray;
	// New code to fix the error dints begins here
	if (!dints)
	{
		var dints	=	new Array();
		dints		=	dobjs;
	}
	// New code to fix the error dints ends here
	if (dints) darray = dints;
	else if (dobjs) darray = dobjs;
	var i;
	for(i=0;i<darray.length;i++) {
		darray[i].dragState=false;
	}
}

function getTotalOffset(htmlElement,dir) {
	var tot=0,prop="offset"+dir.substr(0,1).toUpperCase()+dir.substr(1).toLowerCase();
	if (typeof(eval("htmlElement." + prop)) == "number") {
		while (htmlElement.offsetParent) {
			tot += eval("htmlElement." + prop);
			htmlElement = htmlElement.offsetParent;
		}
		return tot;
	}
	else return null;
}

function checkOverlap(dnd) {
	var dndSen;
	if (!dnd.dndSen) return false;
	if ((dnd.centreX < dnd.dndSen_br_x && dnd.centreX > dnd.dndSen_tl_x) && (dnd.centreY > dnd.dndSen_tl_y && dnd.centreY < dnd.dndSen_br_y)) {
		return true;
	}
	else return false;
}

function findHoverSpan(dnd) {
	var spans = dnd.dndSen.getElementsByTagName("span"),i,spanX,spanY,spanWidth;
	for (i=0;i<spans.length;i++) {
		spanX = getTotalOffset(spans[i],"left") + (parseInt(spans[i].offsetWidth/2));
		spanY = getTotalOffset(spans[i],"top");
		if (i < (spans.length-1)) {
			spanWidth = spans[i].offsetWidth/2 + spans[i+1].offsetWidth/2;
		}
		if ((dnd.centreX < (spanX + spanWidth) && dnd.centreX > spanX) && (dnd.centreY > (spanY-10) && dnd.centreY < (spanY + spans[i].offsetHeight+10))) {
			return spans[i];
		}
	}
	return null;
}

var pointer;
function setupPointer() {
	pointer = document.createElement("img");
	pointer.setAttribute("src","/lls/llonline/assets/images/dnd-pointer.gif");
	pointer.width=13;
	pointer.height=14;
	document.body.appendChild(pointer);
	pointer.style.display="none";
	pointer.style.position="absolute";
}