﻿// The Rater class
function Rater(rater, options)
{
	constructor();
	
	var IMAGE_WIDTH = 20; // Constant for the width of the rater image (in pixels)
	
	var firstRatingElement;
	var originalFirstElementWidth;
	var ajaxRequest;
	var savingTextTimeout;
	var errorTimeout;
	
	function constructor()
	{
		addJavaScriptToRaterElements(rater);
	}
	
	// Adds JavaScript functionality to each rater element that needs it
	function addJavaScriptToRaterElements(rater)
	{
		$A(rater.getElementsByTagName("li")).each
		(
			function(element)
			{
				if (element.className == "current-rating")
				{
					firstRatingElement = element;
					originalFirstElementWidth = parseFloat(firstRatingElement.style.width);
				}
				else
				{
					Event.observe(element, "click", function (event) { ratingClick(element); Event.stop(event); });
				}
			}
	    )
	}
	
	// Handles clicks on the rater elements
	function ratingClick(element)
	{
		setCurrentRating(parseFloat(element.className));
		makeRequest(options.remoteFunction, handleResponse, handleError, getParameters(element.className));
		element.blur();
	}
	
	// Returns the orginal rating that the rater was set at
	function getOriginalRating()
	{
		return originalFirstElementWidth / IMAGE_WIDTH;
	}
	
	// Set the current rating of the rater element
	function setCurrentRating(ratingNumber)
	{
		firstRatingElement.style.width = (IMAGE_WIDTH * ratingNumber) + "px";
	}

	// Set the rater to the average rating display
	function setToAverage(averageRating)
	{
		setCurrentRating(averageRating);
		options.statusArea.innerHTML = "";
	}
	
	// Sets the rater back to the original rating
	function setToOriginalRating()
	{
		setCurrentRating(getOriginalRating());
		options.statusArea.innerHTML = "";
	}
	
	// Gets the parameters to send to the database
	function getParameters(ratingScore)
	{
		var parameters = new Object();
		parameters.uniqueId = options.uniqueId;
		parameters.ratingScore = ratingScore;
		parameters.userId = options.userId;
		return parameters;
	}
	
	// Makes an Ajax request to the web request
	function makeRequest(remoteFunctionName, responseHandler, errorHandler, parameters)
	{	
		// Build a post body based on all of the parameters in the list
		var postBody;
		for (var parameter in parameters)
		{
			if (!postBody)
				postBody = parameter + "=" + parameters[parameter];
			else
				postBody += "&" + parameter + "=" + parameters[parameter];
		}
		
		var url = "/AJAX/AjaxHandler.asmx/" + remoteFunctionName;		
		var ajaxOptions =
		{
			method : "post",
			postBody : postBody,
			onSuccess : responseHandler,
			onFailure : errorHandler,
			on404 : errorHandler
		}

		ajaxRequest = new Ajax.Request(url, ajaxOptions);
		
		// Show some status text if request takes longer than 1 second, cancel the request after 10 seconds 
		savingTextTimeout = setTimeout(function () { options.statusArea.innerHTML = options.savingText; }, 1000);
		errorTimeout = setTimeout(function () { handleError(); ajaxRequest.transport.abort(); }, 10000); 
	}
	
	// Handles the response from the database
	function handleResponse(response)
	{
		var returnValues = response.responseXML;
		var averageRating = returnValues.getElementsByTagName("AverageRating")[0].firstChild.nodeValue;
		var numberOfRatings = returnValues.getElementsByTagName("NumberOfRatings")[0].firstChild.nodeValue;
		var isRatingUpdate = returnValues.getElementsByTagName("IsRatingUpdate")[0].firstChild.nodeValue == "true" ? true : false;
		
		clearTimeout(savingTextTimeout);
		clearTimeout(errorTimeout);
		
		options.statusArea.innerHTML = isRatingUpdate ? options.resavedText : options.savedText;
		options.numberRatingsArea.innerHTML = numberOfRatings;
		
		setTimeout(function () { setToAverage(averageRating); }, 2000);
	}
	
	// Handles errors from the AJAX call
	function handleError()
	{
		clearTimeout(savingTextTimeout);
		options.statusArea.innerHTML = options.errorText;
		setTimeout(function () { setToOriginalRating(); }, 3000);
	}
}


