// Saved position of a drag drop object
var saveDragDropLeft;
var saveDragDropTop;
var dropX; // used for Mac computers
var dropY;
var imgOffsetX;
var imgOffsetY;

// Global holds reference to selected element
var selectedObj;

// Constructor for single object within drag and drop activity
function DragDropObject (id, sourceType, sourceLeft, sourceTop, sourceWidth, sourceHeight, sourceImageURL, sourceText, borderColor, borderWidth, feedbackCorrect, feedbackIncorrect, targetLeft, targetTop, targetWidth, targetHeight, top, left, fontFace, fontStyle, fontSize, fontColor) {

	this.id = id;
	this.type = "drag drop";
	this.sourceType = sourceType;
	this.sourceLeft = sourceLeft;
	this.sourceTop = sourceTop;
	this.sourceWidth = sourceWidth;
	this.sourceHeight = sourceHeight;
	this.sourceZindex = 110;
	this.sourceImageURL = sourceImageURL;
	this.sourceText = sourceText;
	this.borderColor = borderColor;
	this.borderWidth = borderWidth;
	this.feedbackCorrect = feedbackCorrect;
	this.feedbackIncorrect = feedbackIncorrect;
	this.targetLeft = targetLeft;
	this.targetTop = targetTop;
	this.targetWidth = targetWidth;
	this.targetHeight = targetHeight;
	this.targetZindex = 105;
	this.height = 0;
	this.width = 0;
	this.fontFace = fontFace;
	this.fontStyle = fontStyle;
	this.fontSize = fontSize;
	this.fontColor = fontColor;
	this.top = top;
	this.left = left;
	this.distractor = false;

	if (targetLeft == "0" && targetTop == "0" && targetWidth == "0" && targetHeight == "0")
		this.distractor = true;
}


// format one drag drop item
function formatDragDropItem(itemData)
{

	var itemHTML = "";
	var dragObjectHTML = "";


	//id, sourceType, sourceLeft, sourceTop, sourceWidth, sourceHeight, sourceImageURL, sourceText, targetLeft, targetTop, targetWidth, targetHeight

	// Display source object
	var theStyle="normal",theWeight="normal";	
	
	if (itemData.fontStyle != null) {
		if(itemData.fontStyle.indexOf("Bold")!=-1)
		{
			theWeight="Bold";
		}
		if(itemData.fontStyle.indexOf("Italic")!=-1)
		{
			theStyle="Italic";
		}
	}

	var theFontColorStyle = "";
	if (itemData.fontColor)
		theFontColorStyle = "; color:" + itemData.fontColor;

	if (itemData.sourceImageURL != "")   {
		dragObjectHTML = "<IMG SRC=\"" + itemData.sourceImageURL + "\" style=\"border:solid " + itemData.borderColor + " " + itemData.borderWidth + " px\" width=" + itemData.sourceWidth + " height=" + itemData.sourceHeight + " onMouseOver=\"javascript:onDragDropMouseOver(event)\">";

	}
	else {
		dragObjectHTML = "<FONT STYLE=\"font-family:'"+ itemData.fontFace + "'; font-size:"+itemData.fontSize+"px; font-style:"+theStyle+"; font-weight:"+theWeight+ theFontColorStyle + "\" onMouseOver=\"javascript:onDragDropMouseOver(event)\">" + itemData.sourceText + "</FONT>";
	}
	
	itemHTML += "<DIV ID=dragDropSource" + itemData.id +  " STYLE=\"cursor:pointer;position:absolute; left:" + itemData.sourceLeft + "px; top:" + itemData.sourceTop + "px; width:" + itemData.sourceWidth + "px; height:" + itemData.sourceHeight + "px; visibility:show; z-index:" + itemData.sourceZindex + "\">" + 
	dragObjectHTML +
	"</DIV>" +
		// Display target object
	"<DIV ID=dragDropTarget" + itemData.id +  " STYLE=\"position:absolute; left:" + itemData.targetLeft + "px; top:" + itemData.targetTop + "px; width:" + itemData.targetWidth + "px; height:" + itemData.targetHeight + "px; visibility:show; z-index:" + itemData.targetZindex + "\">" + 
	"<IMG width=" + itemData.targetWidth + " height=" + itemData.targetHeight + " SRC=\"" + playerImagesDirectoryURL + "spacer.gif\" BORDER=0>" +
	"</DIV>";
	
	itemHTML += "<BR>";

	return itemHTML;
}

function onDragDropMouseOver(event)
{
	if (IE)
		event.srcElement.style.cursor = 'hand';
}


// Checks name of object to determine if it is a drag source
function isDragSource(testObj) {

	var isSourceObject = false;

	if (testObj.id.indexOf("dragDropSource") != -1) {
		isSourceObject = true;
	}

	return isSourceObject;
}


// Checks name of object to determine if it is a drag target
function isDragTarget(testObj) {
	var isTargetObject = false;
	if (testObj.id.indexOf("dragDropTarget") != -1) {
		isTargetObject = true;
	}
	return isTargetObject;
}
var debugCount = 0;
// selects the clicked object
function setSelectedObj(evt) {
	if (!selectedObj)
		selectedObj = getClickedObject(evt);
}

// Grab selected object
function grab(evt) {
	setSelectedObj(evt);
	var yieldMouseDown = true;

	if (selectedObj) {

		saveDragDropLeft = getLeft(selectedObj);
		saveDragDropTop = getTop(selectedObj);
		if (NN4) {
			offsetX = evt.pageX - selectedObj.left;
			offsetY = evt.pageY - selectedObj.top;
		}
		else if (NN) {
			offsetX = evt.pageX - selectedObj.offsetLeft;
			offsetY = evt.pageY - selectedObj.offsetTop;
		} else if (IE & MAC ) {

			// latest version
			offsetX = -document.body.scrollLeft;
			offsetY = -document.body.scrollTop;

			//special offset for images, since IE Mac handles them differently
			imgOffsetX = window.event.clientX - saveDragDropLeft + document.body.scrollLeft;
			imgOffsetY = window.event.clientY - saveDragDropTop + document.body.scrollTop;
		
		 } else {
			offsetX = window.event.offsetX - document.body.scrollLeft;
			offsetY = window.event.offsetY - document.body.scrollTop;
		}

		yieldMouseDown = !isDragSource(selectedObj);

	}
	// prevent further processing of mouseDown event when dragging so that
	// the Macintosh doesn't display the contextual menu and
	// lets dragging work normally.

	return yieldMouseDown;

}
// Drag an object
function drag(evt) {
	if (selectedObj) {
		if (isDragSource(selectedObj)) {
			if (NN) {
				shiftTo(selectedObj, (evt.pageX - offsetX), (evt.pageY - offsetY))
			} else {
				shiftTo(selectedObj, (window.event.clientX - offsetX), 
				(window.event.clientY - offsetY))
				
				// prevent further system response to dragging
				return false
			}
		}
	}
}

// Release object
function release(evt) {

	var correctFeedbackText = "";
	var incorrectFeedbackText = "";
	var exploreIncorrectFeedbackText = "";
	var answerIsCorrect = false;
	var itemIndex;

	if ( IE ) {
		// for some reason dropX and dropY lose their values from drag()
		dropX = (window.event.clientX - offsetX);
		dropY = (window.event.clientY - offsetY);
	}
	
	if (selectedObj) {
		var sourceIndex = selectedObj.id.substring(14,100);
		var itemIndex = sourceIndex;
		var itemData = testItemArray[itemIndex];
		
		var overObject = getClickedObject(evt);
	
		// If user releases over a dragDropTarget object
		if (overObject && (overObject.id.indexOf("dragDropTarget") != -1)) {
			var targetIndex = overObject.id.substring(14,100);
			var studentAnswer;

			// Get feedback messages, if they are not blank.
			if (itemData.feedbackCorrect != "") {
				correctFeedbackText = itemData.feedbackCorrect;
			}
				
			if (itemData.feedbackIncorrect != "") {
				incorrectFeedbackText = itemData.feedbackIncorrect;
			}
				
			if (evaluationMode == "Practice") {
				// Compare object ids to see if overObject is the target of selectedObject
				

				if (sourceIndex == targetIndex) {
					if (feedbackMode != "Cumulative") {
						showFeedback("correct", correctFeedbackText);
					}
					answerIsCorrect = true;
					studentAnswer = "correct";

					if ( IE & MAC ) {
						if (itemData.sourceImageURL == "") {
							setPos(selectedObj, dropX, dropY);
						}else {
							setPos(selectedObj, dropX - imgOffsetX, dropY - imgOffsetY);
						}
					}
				}
				else {
					if (feedbackMode != "Cumulative") {
						setPos(selectedObj, saveDragDropLeft, saveDragDropTop);
						showFeedback("incorrect", incorrectFeedbackText + exploreIncorrectFeedbackText);
					}
					studentAnswer = "incorrect";
				}
			}
			
			// Currently, evaluate is same as Practice!!
			else if (evaluationMode == "Evaluation") {
				// Compare object ids to see if overObject is the target of selectedObject
				if (sourceIndex == targetIndex) {
					//alert("target hit");
					if (feedbackMode != "Cumulative") {
						showFeedback("correct", correctFeedbackText, "DragDrop");
					}
					answerIsCorrect = true;
					studentAnswer = "correct";
					
					if ( IE & MAC ) {
						if (itemData.sourceImageURL == "") {
							setPos(selectedObj, dropX, dropY);
						}else {
							setPos(selectedObj, dropX - imgOffsetX, dropY - imgOffsetY);
						}
					}
				}
				else {
					if (feedbackMode != "Cumulative") {
						setPos(selectedObj, saveDragDropLeft, saveDragDropTop);
						showFeedback("incorrect", incorrectFeedbackText + exploreIncorrectFeedbackText, "DragDrop");
					}
					studentAnswer = "incorrect";
				}
			}

			// Always record student responses if feedback at end.
			if (feedbackMode == "Cumulative") {
				recordStudentResponse(itemIndex, studentAnswer);			
			}
			else {
				// If the question has not already been answered.
				if (studentResponseArray[itemIndex] == null) {

					recordStudentResponse(itemIndex, studentAnswer);
							
					// Update the test item HTML to give student feedback
					if ((evaluationMode == "Evaluation") || ((evaluationMode == "Practice") && (answerIsCorrect))) {
						//form.studentAnswer.value = correctAnswer;
					}
					// If the student's answer isn't correct and they are in explore mode,
					// delete their answer.
					else if ((evaluationMode == "Practice") && (!answerIsCorrect)) {
						//form.studentAnswer.value = "";
					}
					

					if (answerIsCorrect) {
						studentScore++	
					}
					
				}	
			}

		}
		
		else {
			if (itemData && itemData != null) {
				// only move the thing if it's a drag drop source
				if (selectedObj.id.indexOf("dragDropSource") != -1)
					setPos(selectedObj, itemData.sourceLeft, itemData.sourceTop);
			}
		}
		
		updateNavigationBar(itemIndex);
		selectedObj = null
	}

}

// Assign event handlers used by both Navigator and IE
function initDragDrop() {
	
	if (NN) {
		setNSEventCapture()
	}

	document.onmousedown = grab
	document.onmousemove = drag
	document.onmouseup = release
}

// returns the object user clicked on, or released mouse over.
// NB: Clone of this function in explore.js
function getClickedObject(evt) {
	var testObj;
	var foundObj = null;
		
	if (NN4) {
		var clickX = evt.pageX - xBorder;
		var clickY = evt.pageY - yBorder ;
		
		for (var i = document.bodyDiv.document.layers.length - 1; i >= 0; i--) {
			testObj = document.bodyDiv.document.layers[i];
			if ((testObj != selectedObj) && (clickX > testObj.left) && 
				(clickX < testObj.left + testObj.clip.width) && 
				(clickY > testObj.top) && 
				(clickY < testObj.top + testObj.clip.height)) {
				foundObj = testObj

				return foundObj;
			}
		}
	} 
	else if (NN) {
		var clickX = evt.pageX - xBorder;
		var clickY = evt.pageY - yBorder ;
		
		for (var i = getObj("bodyDiv").childNodes.length - 1; i >= 0; i--) {
			testObj = getObj("bodyDiv").childNodes[i];
			if (testObj)
			{
				var xInRange = (clickX > getLeft(testObj)) && (clickX < getLeft(testObj) + getWidth(testObj));
				var yInRange = (clickY > getTop(testObj)) && (clickY < getTop(testObj) + getHeight(testObj));				
				if ((testObj != selectedObj) && (testObj.id.indexOf("dragDrop") != -1) && xInRange && yInRange)
				{
					foundObj = testObj;
					//alert("foundObj =" + foundObj.id);
					if (foundObj.id != "") {
						return foundObj;
					}
					else {
						return null;
					}
				}
			}
		}
	}
	else {
		
		clickX = window.event.x - xBorder + document.body.scrollLeft;
		clickY = window.event.y - yBorder + document.body.scrollTop;

		for (var i = 0; i < document.all.bodyDiv.children.length - 1; i ++)
		{
			testObj = document.all.bodyDiv.children[i];

			if (testObj)
			{
				if ((testObj != selectedObj) && (clickX > testObj.offsetLeft) && 
					(clickX < testObj.offsetLeft + testObj.offsetWidth) && 
					(clickY > testObj.offsetTop) && 
					(clickY < testObj.offsetTop + testObj.offsetHeight))
				{
					foundObj = testObj

					//alert("foundObj =" + foundObj.id);
					if (foundObj.id != "") {
						return foundObj;
					}
					else {
						return null;
					}
				}
			}
		}
	}
	return null;
}