/**
  * fix_js_SetUpQuestions
  *
  * @param xxx $str (passed by reference)
  * @param xxx $start
  * @param xxx $length
  * @return xxx
  */
 function fix_js_SetUpQuestions(&$str, $start, $length)
 {
     global $CFG;
     $substr = substr($str, $start, $length);
     parent::fix_js_SetUpQuestions($substr, 0, strlen($substr));
     $dots = 'squares';
     // default
     if ($param = clean_param($this->expand_UserDefined1(), PARAM_ALPHANUM)) {
         if (is_dir($CFG->dirroot . "/mod/hotpot/pix/autoadvance/{$param}")) {
             $dots = $param;
         }
     }
     // assume there are no jmix questions
     $jmix = true;
     $search = 'Qs.appendChild(QList[i]);';
     if ($pos = strpos($substr, $search)) {
         $insert = "\n" . "\t\tSetUpJMixQuestion(i);\n";
         $substr = substr_replace($substr, $insert, $pos + strlen($search), 0);
     }
     // add progress bar
     if ($dots) {
         $search = '/\\s*' . 'SetQNumReadout\\(\\);/';
         $replace = "\n" . "\tvar ProgressBar = document.createElement('div');\n" . "\tProgressBar.setAttribute('id', 'ProgressBar');\n" . "\tProgressBar.setAttribute(AA_className(), 'ProgressBar');\n" . "\n" . "\t// add feedback boxes and progess dots for each question\n" . "\tfor (var i=0; i<QArray.length; i++){\n" . "\n" . '		// remove bottom border (override class="QuizQuestion")' . "\n" . "\t\tif (QArray[i]) {\n" . "\t\t\tQArray[i].style.borderWidth = '0px';\n" . "\t\t}\n" . "\n" . "\t\tif (ProgressBar.childNodes.length) {\n" . "\t\t\t// add arrow between progress dots\n" . "\t\t\tProgressBar.appendChild(document.createTextNode(' '));\n" . "\t\t\tProgressBar.appendChild(AA_ProgressArrow());\n" . "\t\t\tProgressBar.appendChild(document.createTextNode(' '));\n" . "\t\t}\n" . "\t\tProgressBar.appendChild(AA_ProgressDot(i));\n" . "\n" . "\t\t// AA_Add_FeedbackBox(i);\n" . "\t}\n" . "\tvar OneByOneReadout = document.getElementById('OneByOneReadout');\n" . "\tif (OneByOneReadout) {\n" . "\t\tOneByOneReadout.parentNode.insertBefore(ProgressBar, OneByOneReadout);\n" . "\t\tOneByOneReadout.parentNode.removeChild(OneByOneReadout);\n" . "\t}\n" . "\tOneByOneReadout = null;\n" . "\t// hide the div containing ShowMethodButton, PrevQButton and NextQButton\n" . "\tvar btn = document.getElementById('ShowMethodButton');\n" . "\tif (btn) {\n" . "\t\tbtn.parentNode.style.display = 'none';\n" . "\t}\n" . "\t// activate first Progress dot\n" . "\tAA_SetProgressDot(0, 0);\n" . "\t";
         $substr = preg_replace($search, $replace, $substr, 1);
     }
     if ($jmix || $dots) {
         $substr .= "\n" . "function AA_isNonStandardIE() {\n" . "\tif (typeof(window.isNonStandardIE)=='undefined') {\n" . "\t\tif (navigator.appName=='Microsoft Internet Explorer' && (document.documentMode==null || document.documentMode<8)) {\n" . "\t\t\t// either IE8+ (in compatability mode) or IE7, IE6, IE5 ...\n" . "\t\t\twindow.isNonStandardIE = true;\n" . "\t\t} else {\n" . "\t\t\t// Firefox, Safari, Opera, IE8+\n" . "\t\t\twindow.isNonStandardIE = false;\n" . "\t\t}\n" . "\t}\n" . "\treturn window.isNonStandardIE;\n" . "}\n" . "function AA_className() {\n" . "\tif (AA_isNonStandardIE()){\n" . "\t\treturn 'className';\n" . "\t} else {\n" . "\t\treturn 'class';\n" . "\t}\n" . "}\n" . "function AA_onclickAttribute(fn) {\n" . "\tif (AA_isNonStandardIE()){\n" . "\t\treturn new Function(fn);\n" . "\t} else {\n" . "\t\treturn fn; // just return the string\n" . "\t}\n" . "}\n";
     }
     if ($dots) {
         // add functions required for progress bar
         $substr .= "\n" . "function AA_images() {\n" . "\treturn 'pix/autoadvance/{$dots}';\n" . "}\n" . "function AA_ProgressArrow() {\n" . "\tvar img = document.createElement('img');\n" . "\tvar src = 'ProgressDotArrow.gif';\n" . "\timg.setAttribute('src', AA_images() + '/' + src);\n" . "\timg.setAttribute('alt', src);\n" . "\timg.setAttribute('title', src);\n" . "\t//img.setAttribute('height', 18);\n" . "\t//img.setAttribute('width', 18);\n" . "\timg.setAttribute(AA_className(), 'ProgressDotArrow');\n" . "\treturn img;\n" . "}\n" . "function AA_ProgressDot(i) {\n" . "\t// i is either an index on QArray \n" . "\t// or a string to be used as an id for an HTML element\n" . "\tif (typeof(i)=='string') {\n" . "\t\tvar id = i;\n" . "\t\tvar add_link = false;\n" . "\t} else if (QArray[i]) {\n" . "\t\tvar id = QArray[i].id;\n" . "\t\tvar add_link = true;\n" . "\t} else {\n" . "\t\treturn false;\n" . "\t}\n" . "\t// id should now be: 'Q_' + q ...\n" . "\t// where q is an index on the State array\n" . "\tvar src = 'ProgressDotEmpty.gif';\n" . "\tvar img = document.createElement('img');\n" . "\timg.setAttribute('id', id + '_ProgressDotImg');\n" . "\timg.setAttribute('src', AA_images() + '/' + src);\n" . "\timg.setAttribute('alt', src);\n" . "\timg.setAttribute('title', src);\n" . "\t//img.setAttribute('height', 18);\n" . "\t//img.setAttribute('width', 18);\n" . "\timg.setAttribute(AA_className(), 'ProgressDotEmpty');\n" . "\tif (add_link) {\n" . "\t\tvar link = document.createElement('a');\n" . "\t\tlink.setAttribute('id', id + '_ProgressDotLink');\n" . "\t\tlink.setAttribute(AA_className(), 'ProgressDotLink');\n" . "\t\tlink.setAttribute('title', 'go to question '+(i+1));\n" . "\t\tvar fn = 'ChangeQ('+i+'-CurrQNum);return false;';\n" . "\t\tlink.setAttribute('onclick', AA_onclickAttribute(fn));\n" . "\t\tlink.appendChild(img);\n" . "\t}\n" . "\tvar span = document.createElement('span');\n" . "\tspan.setAttribute('id', id + '_ProgressDot');\n" . "\tspan.setAttribute(AA_className(), 'ProgressDot');\n" . "\tif (add_link) {\n" . "\t\tspan.appendChild(link);\n" . "\t} else {\n" . "\t\tspan.appendChild(img);\n" . "\t}\n" . "\treturn span;\n" . "}\n" . "function AA_JQuiz_GetQ(i) {\n" . "\tif (! QArray[i]) {\n" . "\t\treturn -1;\n" . "\t}\n" . "\tif (! QArray[i].id) {\n" . "\t\treturn -1;\n" . "\t}\n" . "\tvar matches = QArray[i].id.match(new RegExp('\\\\d+\$'));\n" . "\tif (! matches) {\n" . "\t\treturn -1;\n" . "\t}\n" . "\tvar q = matches[0];\n" . "\tif (! State[q]) {\n" . "\t\treturn -1;\n" . "\t}\n" . "\treturn parseInt(q);\n" . "}\n" . "function AA_SetProgressDot(q, next_q) {\n" . "\tvar img = document.getElementById('Q_'+q+'_ProgressDotImg');\n" . "\tif (! img) {\n" . "\t\treturn;\n" . "\t}\n" . "\tvar src = '';\n" . "\t// State[q][0] : the score (as a decimal fraction of 1)  for this question (initially -1)\n" . "\t// State[q][2] : no of checks for this question (initially 0)\n" . "\tif (State[q] && State[q][0]>=0) {\n" . "\t\tvar score = Math.max(0, I[q][0] * State[q][0]);\n" . "\t\t// Note that if there are only two options on a multiple-choice question, then \n" . "\t\t// even if the wrong answer is chosen, the question will be considered finished\n" . "\t\tif (neutralProgressBar) {\n" . "\t\t\tsrc = 'ProgressDotCorrect00Plus'+'.gif';\n" . "\t\t} else if (score >= 99) {\n" . "\t\t\tsrc = 'ProgressDotCorrect99Plus'+'.gif';\n" . "\t\t} else if (score >= 80) {\n" . "\t\t\tsrc = 'ProgressDotCorrect80Plus'+'.gif';\n" . "\t\t} else if (score >= 60) {\n" . "\t\t\tsrc = 'ProgressDotCorrect60Plus'+'.gif';\n" . "\t\t} else if (score >= 40) {\n" . "\t\t\tsrc = 'ProgressDotCorrect40Plus'+'.gif';\n" . "\t\t} else if (score >= 20) {\n" . "\t\t\tsrc = 'ProgressDotCorrect20Plus'+'.gif';\n" . "\t\t} else if (score >= 0) {\n" . "\t\t\tsrc = 'ProgressDotCorrect00Plus'+'.gif';\n" . "\t\t} else {\n" . "\t\t\t// this question has negative score, which means it has not yet been correctly answered\n" . "\t\t\tsrc = 'ProgressDotWrong'+'.gif';\n" . "\t\t}\n" . "\t} else {\n" . "\t\t// this question has not been completed\n" . "\t\tif (typeof(next_q)=='number' && q==next_q) {\n" . "\t\t\t// this question will be attempted next\n" . "\t\t\tsrc = 'ProgressDotCurrent'+'.gif';\n" . "\t\t} else {\n" . "\t\t\tsrc = 'ProgressDotEmpty'+'.gif';\n" . "\t\t}\n" . "\t}\n" . "\tvar full_src = AA_images() + '/' + src;\n" . "\tif (img.src != full_src) {\n" . "\t\timg.setAttribute('src', full_src);\n" . "\t}\n" . "}\n" . "function AA_SetProgressBar(next_q) {\n" . "\t// next_q is an index on State array\n" . "\t// CurrQNum is an index on QArray\n" . "\tif (typeof(next_q)=='undefined') {\n" . "\t\tnext_q = AA_JQuiz_GetQ(window.CurrQNum || 0);\n" . "\t}\n" . "\tfor (var i=0; i<QArray.length; i++) {\n" . "\t\tvar q = AA_JQuiz_GetQ(i);\n" . "\t\tif (q>=0) {\n" . "\t\t\tAA_SetProgressDot(q, next_q);\n" . "\t\t}\n" . "\t}\n" . "}\n";
     }
     // append the PlaySound() and StopSound() functions
     if ($this->expand_UserDefined2()) {
         $substr .= "\n" . "function PlaySound(i, count) {\n" . '	// li (id="Q_99") -> p (class="questionText") -> span (class="mediaplugin_mp3") -> object' . "\n" . "\tvar li = QArray[i];\n" . "\ttry {\n" . "\t\tvar SoundLoaded = li.childNodes[0].childNodes[0].childNodes[0].isSoundLoadedFromJS();\n" . "\t} catch (err) {\n" . "\t\tvar SoundLoaded = false;\n" . "\t}\n" . "\tif (SoundLoaded) {\n" . "\t\ttry {\n" . "\t\t\tli.childNodes[0].childNodes[0].childNodes[0].playSoundFromJS();\n" . "\t\t\tvar SoundPlayed = true;\n" . "\t\t} catch (err) {\n" . "\t\t\tvar SoundPlayed = false;\n" . "\t\t}\n" . "\t}\n" . "\tif (SoundLoaded && SoundPlayed) {\n" . "\t\t// sound was successfully played\n" . "\t} else {\n" . "\t\t// sound could not be loaded or played\n" . "\t\tif (count<=100) {\n" . "\t\t\t// try again in 1/10th of a second\n" . "\t\t\tsetTimeout('PlaySound('+i+','+(count+1)+')', 100);\n" . "\t\t}\n" . "\t}\n" . "}\n" . "function StopSound(i) {\n" . '	// li (id="Q_99") -> p (class="questionText") -> span (class="mediaplugin_mp3") -> object' . "\n" . "\tvar li = QArray[i];\n" . "\ttry {\n" . "\t\tvar SoundLoaded = li.childNodes[0].childNodes[0].childNodes[0].isSoundLoadedFromJS();\n" . "\t} catch (err) {\n" . "\t\tvar SoundLoaded = false;\n" . "\t}\n" . "\tif (SoundLoaded) {\n" . "\t\ttry {\n" . "\t\t\tli.childNodes[0].childNodes[0].childNodes[0].stopSoundFromJS();\n" . "\t\t\tvar SoundStopped = true;\n" . "\t\t} catch (err) {\n" . "\t\t\tvar SoundStopped = false;\n" . "\t\t}\n" . "\t}\n" . "}";
     }
     // append the SetUpJMixQuestion() and MoveJumbledItem() functions
     if ($jmix) {
         $substr .= "\n" . "function SetUpJMixQuestion(q) {\n" . "\tvar JumbledItems = document.getElementById('Q_'+q+'_JumbledItems');\n" . "\tif (JumbledItems==null) {\n" . "\t\treturn;\n" . "\t}\n" . "\tvar spans = new Array();\n" . "\tvar i_max = JumbledItems.getElementsByTagName('span').length;\n" . "\tfor (var i=i_max; i>0; i--) {\n" . "\t\tspans.push(JumbledItems.removeChild(JumbledItems.getElementsByTagName('span')[i-1]));\n" . "\t}\n" . "\tvar i_max = JumbledItems.childNodes.length;\n" . "\tfor (var i=i_max; i>0; i--) {\n" . "\t\tJumbledItems.removeChild(JumbledItems.childNodes[i-1]);\n" . "\t}\n" . "\tspans = Shuffle(spans);\n" . "\tvar i_max = spans.length\n" . "\tfor (var i=0; i<i_max; i++) {\n" . "\t\tif (i) {\n" . "\t\t\tJumbledItems.appendChild(document.createTextNode(' '));\n" . "\t\t}\n" . "\t\tJumbledItems.appendChild(spans[i]);\n" . "\t}\n" . "\tspans = null;\n" . "\tvar obj = document.getElementById('Q_'+q+'_Guess');\n" . "\tif (obj) {\n" . "\t\tobj.style.display = 'none';\n" . "\t\tvar DropArea = document.createElement('span');\n" . "\t\tDropArea.setAttribute('id', 'Q_'+q+'_DropArea');\n" . "\t\tDropArea.setAttribute(AA_className(), 'DropArea');\n" . "\t\tobj.parentNode.insertBefore(DropArea, obj);\n" . "\t}\n" . "}\n" . "function MoveJumbledItem(obj) {\n" . "\tvar m = obj.id.match(RegExp('Q_([0-9]+)_[a-zA-Z]+_[0-9]+'));\n" . "\tif (m && m[0]) {\n" . "\t\tvar JumbledItems = document.getElementById('Q_'+m[1]+'_JumbledItems');\n" . "\t\tvar DropArea = document.getElementById('Q_'+m[1]+'_DropArea');\n" . "\t\tvar Guess = document.getElementById('Q_'+m[1]+'_Guess');\n" . "\t} else {\n" . "\t\tvar JumbledItems = null;\n" . "\t\tvar DropArea = null;\n" . "\t\tvar Guess = null;\n" . "\t}\n" . "\tif (JumbledItems && DropArea && Guess) {\n" . "\t\tif (obj.parentNode == JumbledItems) {\n" . "\t\t\tif (obj.previousSibling) {\n" . "\t\t\t\tJumbledItems.removeChild(obj.previousSibling);\n" . "\t\t\t}\n" . "\t\t\tif (DropArea.childNodes.length) {\n" . "\t\t\t\tDropArea.appendChild(document.createTextNode(' '));\n" . "\t\t\t}\n" . "\t\t\tDropArea.appendChild(JumbledItems.removeChild(obj));\n" . "\t\t} else {\n" . "\t\t\tif (obj.previousSibling) {\n" . "\t\t\t\tDropArea.removeChild(obj.previousSibling);\n" . "\t\t\t}\n" . "\t\t\tif (JumbledItems.childNodes.length) {\n" . "\t\t\t\tJumbledItems.appendChild(document.createTextNode(' '));\n" . "\t\t\t}\n" . "\t\t\tJumbledItems.appendChild(DropArea.removeChild(obj));\n" . "\t\t}\n" . "\t\tGuess.value = '';\n" . "\t\tvar i_max = DropArea.getElementsByTagName('span').length;\n" . "\t\tfor (var i=0; i<i_max; i++) {\n" . "\t\t\tif (i) {\n" . "\t\t\t\tGuess.value += ' ';\n" . "\t\t\t}\n" . "\t\t\tGuess.value += DropArea.getElementsByTagName('span')[i].innerHTML;\n" . "\t\t}\n" . "\t}\n" . "}";
     }
     $str = substr_replace($str, $substr, $start, $length);
 }