var ExerciseTiming=function(C,B,A){this.time=C;this.exToken=B;this.inToken=A};var Exercise=function(B,A){this.exercise=B;this.exerciseIndex=0;this.statistics=new Statistics(A);this.started=false;this.failures=new Array();this.wordcount=new Array();this.exerciseBR=new Array();this.exerciseTokens=new Array();this.inputTokens=new Array();this.timing=new Array();this.initialize=function(){this.statistics.start();this.started=true};this.reset=function(D,C){this.exercise=D;this.exerciseIndex=0;this.statistics=new Statistics(C);this.started=false;this.failures=new Array();this.wordcount=new Array();this.exerciseBR=new Array();this.inputTokens=new Array();this.exerciseTokens=new Array();this.tokenizeExercise()};this.finishEvent=function(){};this.tokenizeExercise=function(E){var G=0,D=0,J=0;var F=0,I=0,C=1;this.exercise=this.exercise.replace(/\s*\n\s*/g,"\n");this.exercise=this.exercise.replace(/ /g,"&nbsp;");while(D<this.exercise.length){var H=this._getNextHtmlToken(this.exercise,D);if(H=="&nbsp;"||H=="\n"){J++;if((E>0)&&((G-I)>=E)){this.exerciseBR[F]=true;I=F;C++}F=G}this.exerciseBR[G]=false;this.wordcount[G]=J;D+=H.length;if(H=="\n"){if((E>0)&&(I!=F)){this.exerciseBR[F]=true;I=G;F=G;C++}H="&nbsp;"}if(H=="&"){H="&amp;"}this.exerciseTokens[G]=H;G++}if((G-I)>=E){this.exerciseBR[F]=true;C++}this.wordcount[G]=J+1;this.statistics.setNumberOfLines(C)};this.getInputLength=function(){return this.inputTokens.length};this.getExerciseLength=function(){return this.exerciseTokens.length};this.isFinished=function(){return isExerciseFinished()};this.getToken=function(){var C=this.exerciseIndex;if(this.isFinished()){C--}return this._stripHtml(this.exerciseTokens[C])};this.addInputKeyCode=function(C){var D=this.keyCodeToHtml(C);this.addNormalizedCharacter(D)};this.addNormalizedCharacter=function(C){if(C==" "){C="&nbsp;"}if(C=="&"){C="&amp;"}if(!this.started){this.initialize()}if(!this.isFinished()&&!this.statistics.paused()){if(C=="delete"){if(g_backspaceAllowed){if(this.exerciseIndex>0){this.exerciseIndex--}if(this.inputTokens.length>0){this.statistics.backspacePressed();this.inputTokens.length=this.inputTokens.length-1;this.timing.length=this.timing.length-1}}else{if(typeof(showBackspaceMessage)!="undefined"){showBackspaceMessage()}}}else{this.timing[this.timing.length]=new ExerciseTiming(this.statistics.time(),this.exerciseTokens[this.exerciseIndex],C);if(g_soundEnabled&&(C!=this.exerciseTokens[this.inputTokens.length])){soundManager.play("keyerror")}this.inputTokens[this.inputTokens.length]=C;if(this.exerciseIndex<this.exerciseTokens.length){this.exerciseIndex++}}}this.statistics.setNumberOfCharacters(this.inputTokens.length);this.statistics.saveStatus(C);if(this.isFinished()){this.statistics.update(this.timing);this.statistics.finish()}};this.keyCodeToHtml=function(D){var C="";switch(D){case 9:C="&nbsp;";break;case 8:C="delete";break;case 10:C="\n";break;case 13:C="\n";break;case 32:C="&nbsp;";break;case 34:C="&quot;";break;case 38:C="&amp;";break;case 39:C="&apos;";break;case 60:C="&lt;";break;case 62:C="&gt;";break;case 161:C="&iexcl;";break;case 199:C="&Ccedil;";break;case 209:C="&Ntilde;";break;case 231:C="&ccedil;";break;case 241:C="&ntilde;";break;case 8364:C="&euro;";break;default:C=String.fromCharCode(D)}return C};this.getStatistics=function(){return this.statistics};this._formatTime_MMSS=function(C){var E=(C%60);var D=(C-E)/60;if(E<10){E="0"+E}return D+":"+E};this.drawStatistics=function(C){if(C.cpm){$(C.cpm).html(this.statistics.getCPM())}if(C.wpm){$(C.wpm).html(this.statistics.getWPM())}if(C.net_wpm){$(C.net_wpm).html(this.statistics.getNetWPM())}if(C.time){$(C.time).html(this.statistics.getTime()+" s")}if(C.rtime){$(C.rtime).html(this._formatTime_MMSS(this.statistics.getRemainingTime()))}if(C.score){$(C.score).html(""+this.statistics.getScore())}if(C.errors){$(C.errors).html(""+this.statistics.getNumberOfErrors())}if(C.accuracy){$(C.accuracy).html(this.statistics.getAccuracy()+" %")}if(C.total_score){$(C.total_score).html(""+g_totalScore+this.statistics.getScore())}};this.getUserInput=function(){var D="";for(var C=0;C<this.inputTokens.length;C++){D+=this.inputTokens[C]}return D};this.findAndFixGapsAndMissedKeys=function(){var F=0;for(var C=0;(C<this.inputTokens.length)&&(C<this.exerciseTokens.length);C++){exToken=this.exerciseTokens[C];inToken=this.inputTokens[C];if(inToken!=exToken){F++}else{F=0}if(F>=3){var G=C-F+1;var E=true;for(var H=G;H<(C-1);H++){if(this.inputTokens[H]!=this.exerciseTokens[H+1]){E=false}}if(E){for(var D=this.inputTokens.length;D>=G;D--){this.inputTokens[D]=this.inputTokens[D-1]}this.inputTokens[G]="^";this.failures[G]="missed"}else{var E=true;for(var H=G;H<(C-1);H++){if(this.inputTokens[H+1]!=this.exerciseTokens[H]){E=false}}if(E){for(var D=G;D<this.inputTokens.length-1;D++){this.inputTokens[D]=this.inputTokens[D+1]}this.inputTokens.pop();this.failures[G]="extra"}}}}};this.drawAdvancedExercise=function(K,S,Q){if(this.exerciseTokens.length==0){this.tokenizeExercise(Q)}var I='<div class="ExerciseCompleted">';var V='<div class="ExerciseCompleted">';var L=0;this.findAndFixGapsAndMissedKeys();var R=0;var F=0;var M=0;var E=0,J=0;for(var H=0;H<this.exerciseTokens.length;H++){var T=this.exerciseTokens[H];var U=(H<this.inputTokens.length)?this.inputTokens[H]:"";if(H<this.inputTokens.length){if(this.exerciseBR[H]){E++;F=0;M=0}else{M++}if(typeof(this.failures[H])!="undefined"){T="<div class='WrongCharacter'>"+T+"</div>";U="<div class='WrongCharacter'>"+U+"</div>";L++}else{if(T!=U){if((U=="\n")&&this.exerciseBR[H]){}else{T="<div class='WrongCharacter'>"+T+"</div>";U="<div class='WrongCharacter'>"+U+"</div>";L++}}}}else{if(H==this.inputTokens.length){T="</div><div id='ExerciseNextKey'>"+T+"</div>";U+="</div>_"}else{}}I+=T;V+=U;if(this.exerciseBR[H]){I+="<br/>";if(H<this.inputTokens.length){V+="<br/>"}J++}if(J==E){F++}}this.statistics.setNumberOfErrors(L);if(this.isFinished()){I+="<div id='ExerciseNextKey' style='border-color: transparent;'>&nbsp;</div>"}var N=16;var D=4;var P=parseInt((N/D)/2)-1;var O=parseInt(N/D);var C=0;if(E>=P&&(J>=O)){var G=(M/F);C=-D*((E-P)+G);$(K).css("margin-top",C+"em");if(S){$(S).css("margin-top",(1.75+C)+"em")}}$(K).html(I);if(S){$(S).html(V)}};this.drawAnimatedExercise=function(I,K,R){var M=1.8;var F=1;var D=8;if(this.exerciseTokens.length==0){this.tokenizeExercise(0)}var J="";var Q="";var P="";var G=this.statistics.update(this.timing);var H=0;while((H<this.exerciseTokens.length)&&(H<R)){var E=F;if((R-H)<D){E=F+(D-(R-H))*((M-F)/D)}if(H<this.inputTokens.length){var L="",C="";switch(G[H].type){case TYPING_OK:break;case TYPING_WRONG_CHAR_ERROR:L="<div class='WrongCharacter'>";C="</div>";break;case TYPING_LOWER_ERROR:L="<div class='WrongCharLower'>";C="</div>";break;case TYPING_UPPER_ERROR:L="<div class='WrongCharUpper'>";C="</div>";break;case TYPING_SWAP_ERROR:L="<div class='WrongSwap'>";C="</div>";break;case TYPING_SKIP_ERROR:L="<div class='WrongSkip'>";C="</div>";break}if(E!=F){J+='<div style="font-size: '+E+'em; display: inline;">'+L+G[H].exToken+C+"</div>"}else{J+=L+G[H].exToken+C}P+=L+G[H].inToken+C;H+=G[H].size}else{if(H==this.inputTokens.length){var N=this.exerciseTokens[H];if(E!=F){Q+='<div id="ExerciseNextKey" style="font-size: '+E+'em;">'+N+"</div>"}else{Q+="<div id='ExerciseNextKey'>"+N+"</div>"}H++}else{var O=this.exerciseTokens[H];if(E!=F){Q+='<div style="font-size: '+E+'em; display: inline;">'+O+"</div>"}else{Q+=O}H++}}}if(this.isFinished()){Q+="<div id='ExerciseNextKey' style='border-color: transparent;'>&nbsp;</div>"}$(K).html(P);$(I).html('<div class="ExerciseCompleted">'+J+"</div>"+Q);return(R<=(this.exerciseTokens.length+D))};this._getNextHtmlToken=function(F,D){var E="";if(F.length==0||D>=F.length){E=""}else{if(F.charAt(D)=="&"){var C=F.indexOf(";",D+1);E=F.substring(D,C+1);if(!E.match(/^&[^\s&]+;$/g)){E="&"}}else{E=F.charAt(D)}}return E};this._stripHtml=function(E){var D=E;if(E.length>0&&E.charAt(0)=="&"){var C=E.indexOf(";",1);D=E.substring(1,C)}return D};this._getWrongTokenId=function(D,C){var E="WrongCharacter";if(D==C.toLowerCase()){E="WrongCharLower"}else{if(D==C.toUpperCase()){E="WrongCharUpper"}}return E}};