/*
 * Name:
 *	content_rater.js
 *
 * Description:
 *	Defines functions for making AJAX queries via the HTTP protocol's GET method.
 *
 * Pre-conditions:
 *	'q'			   : Content Rating
 *	'contentId'    : contentId
 *  'contentTypeId : contentTypeId
 *
 * Post-conditions:
 * - Calls the upd_content_rater.php which updates/inserts
 *   content rating and displays RatingAvg
 * - Updates the hit counts, miss counts, and calculated ratings of all instances of a piece of content onscreen.
 *
 * Log:
 *	Kripa Shenai		08/15/2006
 *		- Creation
 *	Randall Betta		11/13/2006
 *		- Altered to update raw hit counts and raw miss counts.
 *		- Altered to update all instances of the content's rating values onscreen automagically.
 *
 */


var xmlHttp

function rate_content(rating, contentTypeId, contentId) {
	var url;
	
	// Cast rating as a string.
	rating = '' + rating;
	// Ensure the rating string is a valid integer representation.
	if (rating.match(/([-])?[0-9]+/)) {
		url  = document.domain +"/upd_content_rater.php";
		url += "?q=" + rating;
		url += "&contentTypeId=" + contentTypeId;
		url += "&contentId=" + contentId;
		url += "&sid=" + Math.random();
		
		xmlHttp=GetXmlHttpObject(function () { stateChanged(contentTypeId, contentId); })
		xmlHttp.open("GET", url , true)
		xmlHttp.send(null)
	} // End if: rating is a valid integer.
} // End function: rate_content.




function stateChanged(contentTypeId, contentId) {
	var responseText;
	var propObj;
	var pairsArray;
	var pairIndex;
	var keyValueArray;
	var pairKey;
	var pairValue;
	var messageElts;
	var eltIndex;
	
	// Returned AJAX values.
	var hits;
	var misses;
	var rating;
	var debugMsg;
	var userMsg;
	var success;
	
	if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete") { // If: the HTTP response is valid.
		responseText = xmlHttp.responseText;
		
		// Initialize an object whose properties will be set via the AJAX response's key-value pairs.
		propObj = new Object();
		
		// Parse the AJAX response for key-value pairs. Keys and values are URL-encoded, in the
		// form: key=value,key=value,key=value,...,key=value
		pairsArray = responseText.split(',');
		for (pairIndex = pairsArray.length - 1; pairIndex >= 0; pairIndex--) { // For: iterate through pairs.
			keyValueArray = (pairsArray[pairIndex]).split('=');
			pairKey = '' + unescape(keyValueArray[0]);
			pairValue = '' + unescape(keyValueArray[1]);
			propObj[pairKey] = pairValue;
		} // End for: iterate through pairs.
		
		// Store known key-value pairs as local variables.
		hits		= propObj['hits'];
		misses		= propObj['misses'];
		rating		= propObj['rating'];
		success		= propObj['success'];	// Set to 1 if rating was successful.
		userMsg		= propObj['userMsg'];	// For display to the user.
		debugMsg	= propObj['debugMsg'];	// For AJAX debugging.
		
		if ('1' == ('' + success)) { // If: Rating was successful.
			// Update the front-end displays of this content's rating.
			updateHitOrMissDisplays(contentTypeId, contentId, hits, misses, rating, userMsg);
		} else { // Else: the content could not be rated.
			// Display any necessary  message.
			if (userMsg) { // If: a message is defined.
				displayRatingMessages(contentTypeId, contentId, userMsg);
			} // End if: a message is defined.
		} // End if: the content could not be rated.
    } // End if: the HTTP response is valid.
} // End function: stateChanged.






/*
function rate_content(str1,str2,str3,str4)
{
 var str = str1;

	if (str1.length==0)
	{
		var obj = document.getElementById(str4);
        if (obj) obj.innerHTML = '';
	}
	else {
		var url="/upd_content_rater.php";
		url=url+"?q="+str1;
		url=url+"&contentTypeId="+str2;
		url=url+"&contentId="+str3;
		url=url+"&sid="+Math.random();
		var txtLink = "txtLink"+str4;
		xmlHttp=GetXmlHttpObject(function () { stateChanged(txtLink); })
		xmlHttp.open("GET", url , true)
		xmlHttp.send(null)
    }

}
*/

/*
function stateChanged(txtLink)
{
     if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
     {
     var obj = document.getElementById(txtLink);
     if (obj) obj.innerHTML =xmlHttp.responseText;
    	 document.getElementById(txtLink).innerHTML=xmlHttp.responseText
    }

}
*/

function GetXmlHttpObject(handler)
{
	var objXmlHttp=null

	if (navigator.userAgent.indexOf("Opera")>=0)
	{
		alert("This doesn't work in Opera")
		return
	}
	if (navigator.userAgent.indexOf("MSIE")>=0)
	{
		var strName="Msxml2.XMLHTTP"
		if (navigator.appVersion.indexOf("MSIE 5.5")>=0)
		{
			strName="Microsoft.XMLHTTP"
		}
		try
		{
			objXmlHttp=new ActiveXObject(strName)
			objXmlHttp.onreadystatechange=handler
			return objXmlHttp
		}
		catch(e)
		{
			alert("Error. Scripting for ActiveX might be disabled")
			return
		}
	}
	if (navigator.userAgent.indexOf("Mozilla")>=0)
	{
		objXmlHttp=new XMLHttpRequest()
		objXmlHttp.onload=handler
		objXmlHttp.onerror=handler
		return objXmlHttp
	}
}


/*
 * Name:
 *	updateContentRatingDisplays
 *
 * Description:
 *	Given the contentTypeId and contentId of some content, and its hit and miss count, update any
 *  onscreen <div> elements containing that content's hit-or-miss status to reflect the new numbers.
 *	
 * Pre-conditions:
 *	The following arguments are expected:
 *		contentTypeId		REQUIRED	The numeric content type of the content.
 *		contentId			REQUIRED	The Id of the content.
 *		hits				REQUIRED	The number of positive ratings earned.
 *		misses				REQUIRED	The number of negative ratings earned.
 *		rating				REQUIRED	The overall derived (i.e. calculated) rating earned.
 *		message				REQUIRED	A message to display to the user. If empty, none is displayed.
 *	Additionally, the HTML id properties of the <div> tags holding the ratings must be as follows:
 *		The id must consist of a set of key-value pairs, with each key separated from its value
 *		by a colon (":"). The pairs are separated from each other by a hyphen ("-"). The pairs
 *		should be as follows:
 *		1: rating:hitOrMiss
 *		2: type:hit or type:miss or type:rating or type:message
 *		3: contentTypeId:43		(value for example only)
 *		4: contentId:23862		(value for example only)
 *		5: hash:1				(value for example only)
 *		The "hash" key is an alphanumeric suffix to allow for uniqueness, since HTML does not
 *		allow identical ID properties on different elements in the same document.
 *		Example HTML snippet for content with 34 misses:
 *		Misses: <div id="rating:hitOrMiss-type:miss-contentTypeId:32-contentId:4376-hash:IamUnique379">34</div>
 *
 * Post-conditions:
 *	Updates any onscreen displays of the given content's numeric hit-or-miss status.
 *
 *	Libraries:
 *		html_element_search.js
 *
 * Log:
 *	Randall Betta		11/07/2006
 *		- Creation
 *
 */
function updateHitOrMissDisplays(contentTypeId, contentId, hits, misses, rating, message) {
	
	// HTML elements with nodeValues of numeric hit or miss counts, or rating totals.
	var hitElts;
	var missElts;
	var ratingElts;
	
	// Regexes that describe the IDs of HTML elements to change.
	var hitEltRegex = 'rating\:hitOrMiss\-type\:hit\-contentTypeId\:' + contentTypeId + '\-contentId\:' + contentId + '\-hash\:([A-Za-z0-9])*';
	var missEltRegex = 'rating\:hitOrMiss\-type\:miss\-contentTypeId\:' + contentTypeId + '\-contentId\:' + contentId + '\-hash\:([A-Za-z0-9])*';
	var ratingEltRegex = 'rating\:hitOrMiss\-type\:rating\-contentTypeId\:' + contentTypeId + '\-contentId\:' + contentId + '\-hash\:([A-Za-z0-9])*';
	
	// Counters and temporary variables.
	var eltIndex;
	var elt;
	
	// Obtain separate arrays of all <div> elements containing hit, miss,
	// and rating numbers, as well as messages to be displayed.
	hitElts = getRelatedElements('div', hitEltRegex, true, true);
	missElts = getRelatedElements('div', missEltRegex, true, true);
	ratingElts = getRelatedElements('div', ratingEltRegex, true, true);
	
	// Update the numeric hit displays.
	for (eltIndex = hitElts.length - 1; eltIndex >= 0; eltIndex--) { // For: HTML hit elements.

		// Store current hit element.
		elt = hitElts[eltIndex];
		// Update its contents.
		try {
			if (elt.firstChild) {
				elt.firstChild.nodeValue = hits;
			}
			else {
				elt.appendChild(document.createTextNode(hits));
			}
		}
		catch (exc) { ; } // Silently fail on a JavaScript permissions error.

	} // End for: iteration through HTML hit elements.
	
	// Update the numeric miss displays.
	for (eltIndex = missElts.length - 1; eltIndex >= 0; eltIndex--) { // For: HTML miss elements.

		// Store current miss element.
		elt = missElts[eltIndex];
		// Update its contents.
		try {
			if (elt.firstChild) {
				elt.firstChild.nodeValue = misses;
			}
			else {
				elt.appendChild(document.createTextNode(misses));
			}
		}
		catch (exc) { ; } // Silently fail on a JavaScript permissions error.

	} // End for: iteration through HTML miss elements.
	
	// Update the numeric rating displays.
	for (eltIndex = ratingElts.length - 1; eltIndex >= 0; eltIndex--) { // For: HTML rating elements.
		
		// Store current rating element.
		elt = ratingElts[eltIndex];
	
		// Update its contents.
		try {
			if (elt.firstChild) {
				elt.firstChild.nodeValue = rating;
			}
			else {
				elt.appendChild(document.createTextNode(rating));
			}
		}
		catch (exc) { ; } // Silently fail on a JavaScript permissions error.

	} // End for: iteration through HTML miss elements.
	
	// Update the message displays.
	message = (message) ? message : '';
	displayRatingMessages(contentTypeId, contentId, message);

	return;
	
} // End function: updateHitOrMissDisplays




/*
 * Name:
 *	displayRatingMessages
 *
 * Description:
 *	Displays a message to the user regarding rating a given piece of content.
 *	
 * Pre-conditions:
 *	The following arguments are expected:
 *		contentTypeId		REQUIRED	The numeric content type of the content.
 *		contentId			REQUIRED	The Id of the content.
 *		message				REQUIRED	A message to display to the user. Can be empty.
 *
 * Post-conditions:
 *	Updates any onscreen displays of the given content's rating messages.
 *
 *	Libraries:
 *		html_element_search.js
 *
 * Log:
 *	Randall Betta		11/14/2006
 *		- Creation
 *
 */
function displayRatingMessages(contentTypeId, contentId, message) {

	// HTML elements with text nodes to store the message.
	var messageElts;
	
	// Regexes that describe the IDs of HTML elements to change.
	var messageEltRegex = 'rating\:hitOrMiss\-type\:message\-contentTypeId\:' + contentTypeId + '\-contentId\:' + contentId + '\-hash\:([A-Za-z0-9])*';

	// Counters and temporary variables.
	var eltIndex;
	var elt;
	
	// Obtain separate arrays of all <div> elements containing messages to be displayed.
	messageElts = getRelatedElements('div', messageEltRegex, true, true);

	// Update the message displays.
	message = (message) ? message : '';
	for (eltIndex = messageElts.length - 1; eltIndex >= 0; eltIndex--) { // For: HTML message elements.
		// Store current rating element.
		elt = messageElts[eltIndex];
		// Update its contents.
		try {
			if (elt.firstChild) {
				elt.firstChild.nodeValue = message;
			}
			else {
				elt.appendChild(document.createTextNode(message));
			}
			messageEltId = elt.id;
			document.getElementById(messageEltId).style.display = 'block';
			window.setTimeout("document.getElementById('" + messageEltId + "').style.display = 'none';", 3000);
		}
		catch (exc) { ; } // Silently fail on a JavaScript permissions error.

	} // End for: iteration through HTML message elements.
	return messageElts;

} // End function: displayRatingMessages
