Source: jsoclo/spectroAnalyzer.js

/**
 * Contsructor for spectroAnalyzer
 * @class
 * 
 * @classdesc Inherits from analyzerBase and provides Spectroscopy specific 
 * feedback, scoring and syntax checking. <p> 
 * 
 * @extends analyzerBase
 * 
 * @tutorial SpectroscopyQuestionFileFormat
 * 
 * @see {@link searcher}
 * @see {@link chargeSearcher}  
 * @see {@link functionalGroupsSearcher} 
 * @see {@link molecularFormulaSearcher} 
 * @see {@link molecularWeightSearcher} 
 * @see {@link numHydrogenSearcher} 
 * @see {@link numCarbonSearcher} 
 * @see {@link numTypesHydrogenSearcher} 
 * @see {@link numTypesCarbonSearcher} 
 * @see {@link ringsSearcher} 
 * 
 * @tutorial ArchitectureOverview
 */
function spectroAnalyzer(){
	//========================= Constructor =====================
	//super constructor
	
	analyzerBase.call(this);
	var that = this;
	// public instance variables
	/**
	 * The question score for this question only
	 */
	this.questionScore = config.SPEC_MAX_QUESTION_SCORE; 
	
	var tokens = null; 
	
	
	//Load the question display and feedback information
	this.getQuestionFile();
	
	// the question file has been loaded by the parent
	// now we need to call the smidge Parser on the 
	// SMILE string from the question file. 
	tokens = Parser.parse(that.getCorrectAnswer()); 
	
	//=========================privileged methods =====================
	
	/**
	 * returns the tokens as parsed by Smidge.js 
	 */
	this.getTokens = function(){
		return tokens; 
	};
	
	/**
	 * Overrides  analyzerBase checkSyntax
	 * 
	 * @returns the empty String as syntax validation is not done
	 * for spectroscopy
	 * 
	 * This method is called in getFeedback(String). 
	 * 
	 */
	this.checkSyntax = function(answer){
		
		return ""; 
		
	};
	
	
	/**
	 * Overrides analyzerBase getFeedback
	 * to provide feedback for Spectroscopy
	 * answers.  
	 * @param {String} answer 
	 * @returns a string of feedback based on the answer content.
	 * 
	 * This method should be called from the presentation layer. 
	 * 
	 */
	this.getFeedback = function(answer){
		var response = "";
		
		if(this.isCorrect(answer)){
			if(config.DONT_SHOW_FEEDBACK_ON_CORRECT) {
			    return response + this.getCorrectMsg() + "<br>";
			} else {response += this.getCorrectMsg() + "<br>";} 
		}
		//if its not correct then...
	try {
		  
		response +=  this.checkSyntax(answer);
		
		// there may be more than one common section
		// in spectro
		var tmp = this.getCommonSearchers(); 
		if (tmp != null) {
		    var res = ""; 
		    for (var i = 0; i < tmp.length; i++) {
			var cSearch = tmp[i];
			//alert(cSearch.getRegExpString());
			res = cSearch.search(answer); 
			if(res.length != 0){
			    response += res + "<br>"; 
			    res = ""; 
			}
		    }
		}
		response +=  this.getMolecularWeightSearcher().search(answer) + "<br>";
		response += this.getNumCargonSearcher().search(answer) + "<br>";
		response += this.getNumHydrogenSearcher().search(answer) + "<br>";
		response += this.getMolecularFormulaSearcher().search(answer) + "<br>"; 
		
		//these can return empty strings
		tmp = this.getRingsSearcher().search(answer); 	
		if(tmp.length != 0){
			response += tmp + "<br>"; 
		}
		
		tmp = this.getStereoSearcher().search(answer); 
		if(tmp.length != 0){
			response += tmp  + "<br>"; 
		}
	
		tmp = this.getChargeSearcher().search(answer); 	
		if(tmp.length != 0){
			response += tmp  + "<br>"; 
		}
		
		tmp = this.getFunctionalGroupsSearcher().search(answer);
		if(tmp.length != 0){
			response += tmp  + "<br>"; 
		}

		
	} catch (e) {
			alert(config.AF_LOAD_ERROR  +  "\n\nspectroAnalyzer.getFeedback: Question: " + 
				$.cookie("question")  + ", " + e); 
	}
		
		return response; 
		
	};
	
	
}

//inherit from the analyzerParent
spectroAnalyzer.prototype = new analyzerBase();
spectroAnalyzer.prototype.constructor = spectroAnalyzer; 


//=========================Public methods =====================

	/**
	 * 
	 * getCorrect() deals with all scoring.  getCorrect must be 
	 * called for any scoring to be be dealt with. 
	 * 
	 * Side affect:  will calculate the score on the first 
	 * and only the first correct answer. 
	 */
	spectroAnalyzer.prototype.getCorrect = function (answer){
	
		if(!this.isCompleted() && this.isCorrect(answer) ){
			this.calcScore();
			this.setComplete(); 			
			return true;
					
		}else if(this.questionScore > 0){
			this.questionScore--;
		}
		return false;
			
	};
	

	/**
	 * Gives the question a zero and calculates the new average 
	 * for the category. 
	 */
	spectroAnalyzer.prototype.forfeitQuestion = function (){
		
		this.questionScore = 0; 
		this.setComplete(); 
		this.calcScore();
			
	};
		
	/**
	 * 
	 *	This method should be called by either spectroAnalyzer.getCorrect(), 
	 *  or by spectroAnalyzer.forfeitQuestion() only.  
	 *  
	 *  It uses the cookie values to calculate the average score for 
	 *  the section.  It keeps, in cookies, the total score and the number 
	 *  of questions tried and simply calculates the average.  
	 *  
	 *  It sets the resultant average by calling analyzerBase.setScore.  
	 * 
	 */
	
	spectroAnalyzer.prototype.calcScore = function(){
		
		var theQScore = this.questionScore/config.SPEC_MAX_QUESTION_SCORE*100; 
		var theRunningScore = new Number($.cookie("score"));
		var theNumberOfQuestions = new Number($.cookie("numQuestionsTried")) + 1; //number of questions
		var theNewRunningScore = theRunningScore + theQScore; 
			
		$.cookie("score",theNewRunningScore, {path: '/'});
		$.cookie("numQuestionsTried",theNumberOfQuestions, {path: '/'});
		
		
		this.setScore(theNewRunningScore/theNumberOfQuestions); // The new score

		
	};