/**
* 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
};