/*
 *  Calculates the credits and GPA needed to reach a desired GPA 
 *  
 *  @package GPA_Estimator
 *  @category Registrar
 *  @author Paul Gilzow, Web Communications, University of Missouri
 *  @copyright 2008
 *  @uses prototype.js
 *  @uses scriptaculous.js  
 */

/******************************************************************
 *  CONFIGURABLE VARIABLES
 ******************************************************************/
/**
 * ID of the element to display errors
 */
var errContainerID 		= 'error-container';
/**
 * ID of the element to display GPA results
 */
var resultsContainerID 	= 'results-container'
/**
 * The color for the background of the alternating row
 */
var colorRow 			= '#EEEEEE';
/**
 * The color of the flash highlight
 */
var colorHighlight 		= '#FFCD55';
/**
 * The color of the warning highlight
 */
var colorWarn			= '#FF0000';


/**
 * The main function. Creates our XHR object, queries and displays results
 * 
 * If, for some reason, the 	XHR object isnt able to contact the server-side script, or receives an improper response, then it 
 * responds with boolean true so that the form will be submitted to the server-side script.  Otherwise responds with boolean false  
 * 
 *   @return boolean boolContinue
 */
function estimateGPA(){
	var current_hours 	= $('CR_completed').getValue();			
	var current_gpa		= $('curr_GPA').getValue();
	var desired_gpa		= $('desired_GPA').getValue();
	var boolContinue	= false;
	var resultsContainer= $(resultsContainerID);
	
	//hide the containers if they are currently visible
	toggleContainer(false,errContainerID);
	toggleContainer(false,resultsContainerID);
	
	new Ajax.Request('gpa-estimate.php', 
		{ 
			method:'get',
			parameters: $('frm_gpa_estimate').serialize(true),
			onSuccess: function(transport){
						 var response = transport.responseText.evalJSON(true) || "no response text"; 
						 handleSuccess(response);
						}, 
			onFailure: function(){ 
							boolContinue = true; 
						} 
		}
	);	
	
	return boolContinue;	
}

/**
 * Displays the results (both errors and success) of the estimation query
 * 
 * @param {Object} response
 * @return void
 * @TODO The messages could be moved to the server-side and then sent back with everything pre-formatted.  That way you dont have to
 * worry about the messages being in synch on both the server and the client.
 */
function handleSuccess(response){
	if(response.error){
		var errContainer	= $(errContainerID);
		var errIntro 		= new Element('p',{id:'errors-intro'}).update('The following errors were encountered:');
		var errList 		= new Element('ul',{id:'errors-list'});
		var i				= 1;
		
		errContainer.update('');//empty the container from any previous errors
		toggleContainer(true,errContainerID) ; // display the error container
		errContainer.appendChild(errIntro);
		errContainer.appendChild(errList);
		
		response.messages.each(function(strError){
				var errID = 'error-' + i;
				var errItem = new Element('li',{id:errID}).update(strError);
				errList.appendChild(errItem);
				new Effect.Highlight(errID,{startcolor:colorWarn,queue:'end'});
				++i;
			}
		);
	} else {
		// Message Templates
		var msgGraduateNotPossible 	= new Template('You will not be able to reach the desired GPA of #{desiredGPA} when you graduate at 120 hours.');
		var msgGPANotPossible		= new Template('It is not possible to reach your desired GPA of #{desiredGPA} in one semester.');
		var msgToAchieve			= new Template('To achieve a #{desiredGPA} GPA , with a current GPA of #{currentGPA} and #{hoursCompleted} hours completed, you need:');
		var msgResultLine			= new Template('#{creditHours} credits of at least a #{fltGPA} average');
		var msgToGraduate			= new Template('To graduate with 120 credits, you need #{creditsRemaining} credits of at least a #{fltGPA} average');
	
		// form values
		var current_hours 			= $('CR_completed').getValue();			
		var current_gpa				= $('curr_GPA').getValue();
		var desired_gpa				= $('desired_GPA').getValue();		
		
		//hash of our credits=>gpa's
		var hashEstimates 			= $H(response.estimates);
		
		var resultsContainer 		= $(resultsContainerID);
		var boolRow 				= true; //whether the row should end in a highlight or not

		var j						= 1;
		var boolGrad				= true;
		var resultsEndMsg 			= '';
		
		resultsContainer.update(''); // empty out the results container
		toggleContainer(true,resultsContainerID);//show the container
		
		resultsContainer.update('<legend>Results</legend>');
		var resultHeader = new Element('div',{id:'results-header'}).update(msgToAchieve.evaluate({desiredGPA:desired_gpa,currentGPA:current_gpa,hoursCompleted:current_hours}));
		resultsContainer.appendChild(resultHeader);
		new Effect.Highlight('results-header',{startcolor:colorHighlight,queue:'end'});		
		

		if(response.estimates.length == 0){ //no results at all.  
			boolGrad = false; //definitely no 120 index
			var notPossible = new Element('div',{id:'gpa-not-possible'}).update(msgGPANotPossible.evaluate({desiredGPA:desired_gpa}));
			resultsContainer.appendChild(notPossible);
			new Effect.Highlight('gpa-not-possible',{startcolor:colorWarn,queue:'end'});			
		} else {
			var resultsList = new Element('ul',{id:'results-list'});
			resultsContainer.appendChild(resultsList);
			hashEstimates.each(function(item){
					if(item.key != '120'){
						var listID 		= 'result-list-item-' + j;
						var listItem = new Element('li',{id:listID}).update(msgResultLine.evaluate({creditHours:item.key,fltGPA:item.value}));
						resultsList.appendChild(listItem);
						if(boolRow){
							var listOptions = {startcolor:colorHighlight,endcolor:colorRow,restorecolor:colorRow,queue:'end'};
						} else {
							var listOptions = {startcolor:colorHighlight,queue:'end'};	
						}
						new Effect.Highlight(listID,listOptions);
						++j;
						boolRow = !boolRow;
					} else {
						var credits_remaining = 120 - current_hours;
						resultsEndMsg = msgToGraduate.evaluate({creditsRemaining:credits_remaining,fltGPA:hashEstimates.get(120)});						
					}
				}
			);
			
			if(resultsList.childElements().length == 0){
				// looks like their goal isnt possible in one semester
				var notPossible = new Element('div',{id:'gpa-not-possible'}).update(msgGPANotPossible.evaluate({desiredGPA:desired_gpa}));
				resultsList.appendChild(notPossible);
				new Effect.Highlight('gpa-not-possible',{startcolor:colorWarn,queue:'end'});
			}
				
		}
		

		
		if(!boolGrad || resultsEndMsg == ''){
			resultsEndMsg = msgGraduateNotPossible.evaluate({desiredGPA:desired_gpa});
		} 

		var resultsEnd = new Element('div',{id:'results-graduate'}).update(resultsEndMsg);
		resultsContainer.appendChild(resultsEnd);
		new Effect.Highlight('results-graduate',{startcolor:colorHighlight,queue:'end'});
	}		
}
/**
 * Blinds down or Blinds up a container element
 * 
 * @param {boolean} boolShow
 * @param {string} elementID
 * @return void
 */
function toggleContainer(boolShow,elementID){
	if(boolShow){
		new Effect.BlindDown(elementID,{queue:'end'});
	} else {
		new Effect.BlindUp(elementID,{
			queue:'front',
			duration:0.5,
			beforeStart:function(){
				$(elementID).setStyle({backgroundColor:'#000000'});
			},
			afterFinish:function(){
				$(elementID).setStyle({backgroundColor:'#FFFFFF'});
			}
		  }
		);		
	}
}
