TestBlocksCount=0;

BlocksTitles = new Array();
BlocksAdaptiveModes = new Array();
BlocksQuestionsNumbers = new Array();
BlocksQuestionsCounts = new Array();
BlocksQuestionTypes = new Array();
BlocksBlockTimeLimits = new Array();
BlocksQuestionTimeLimits = new Array();
BlocksInstrucTexts = new Array();
BlocksInstrucEnabled = new Array();
BlocksInstrucVisible = new Array();

BlocksRandomQuestions = new Array();
BlocksRandomAnswers = new Array();

CurrentBlockNumber=0;
CurrentQuestionNumber=0;
CurrentBlockQuestionNumber=0;

CurrentBlockBackwardLevel = 0;

BlocksQuestionsNeutralAnswers = new Array();

ProgressBarsWidth = 200;



// Block Control Methods


function startTestBlock(bnumber)
{
  var bcount=getTestBlocksCount();
  if ((bnumber<1) || (bnumber>bcount)) return false;
  setCurrentBlockNumber(bnumber);
  onBlockNumberChanged();
  setCurrentBlockQuestionNumber(1);
  onBlockQuestionNumberChanged();
  if (!isDebugDisableInstrucs()) showBlockInstruc();
  return true;
}


function startTestNextBlock()
{
  var bcount=getTestBlocksCount();
  var bnumber=getCurrentBlockNumber();
  if (bnumber<bcount) {
    startTestBlock(bnumber+1);
  } else {
    showTestingCompleteInstruct();
  }
}




// Blocks Get Properties Methods


function getTestBlocksCount()
{
  var bcount=BlocksTitles.length-1;
  return bcount;
}


function getBlockTitle(bnumber)
{
  var bindex = bnumber;
  var title = BlocksTitles[bindex];
  return title;
}


function getBlockAdaptiveMode(bnumber)
{
  var bindex = bnumber;
  var mode = BlocksAdaptiveModes[bindex];
  return mode;
}


function getBlockMinQuestionNumber(bnumber)
{
  var bindex=bnumber;
  var qmin=BlocksQuestionsNumbers[bindex][0];
  return qmin;
}


function getBlockMaxQuestionNumber(bnumber)
{
  var bindex=bnumber;
  var qmax=BlocksQuestionsNumbers[bindex][1];
  return qmax;
}


function getBlockQuestionsCount(bnumber)
{
  var bindex=bnumber;
  var count=BlocksQuestionsCounts[bindex];
  return count;
}


function getBlockQuestionsTotal(bnumber)
{
  var qmin=getBlockMinQuestionNumber(bnumber);
  var qmax=getBlockMaxQuestionNumber(bnumber);
  var qtotal=qmax-qmin+1;
  return qtotal;
}


function getBlockQuestionTypeCode(bnumber)
{
  var bindex=bnumber;
  var qtnumber=BlocksQuestionTypeNumbers[bindex];
  var qtcode=QuestionTypesCodes[qtnumber];
  return qtcode;
}


function getBlockBlockTimeLimit(bnumber)
{
  var bindex=bnumber;
  var limit=BlocksBlockTimeLimits[bindex];
  return limit;
}


function getBlockQuestionTimeLimit(bnumber)
{
  var bindex = bnumber;
  var limit = BlocksQuestionTimeLimits[bindex];
  return limit;
}


function getBlockInstrucText(bnumber)
{
  var bindex=bnumber;
  var itext=BlocksInstrucTexts[bindex];
  return itext;
}


function getBlockInstrucEnabled(bnumber)
{
  var bindex=bnumber;
  var ienabled=BlocksInstrucEnabled[bindex];
  return ienabled;
}


function getBlockInstrucVisible(bnumber)
{
  var bindex=bnumber;
  var ivisible=BlocksInstrucVisible[bindex];
  return ivisible;
}


function getBlockRandomQuestions(bnumber)
{
  var bindex=bnumber;
  var qrandom=BlocksRandomQuestions[bindex];
  return qrandom;
}


function getBlockRandomAnswers(bnumber)
{
  var bindex=bnumber;
  var arandom=BlocksRandomAnswers[bindex];
  return arandom;
}




// Blocks Get Answer Control Properties Methods


function getBlockNeutralAnswersControl(bnumber)
{
  var bindex=bnumber;
  var bneutral=BlocksNeutralAnswersControls[bindex];
  return bneutral;
}


function getBlockNeutralAnswersPercentMin(bnumber)
{
  var bindex=bnumber;
  var bneutmin=BlocksNeutralAnswersPercentMins[bindex];
  return bneutmin;
}


function getBlockNeutralAnswersPercentMax(bnumber)
{
  var bindex=bnumber;
  var bneutmax=BlocksNeutralAnswersPercentMaxs[bindex];
  return bneutmax;
}


function getBlockCaseNeutralAnswersControl(bnumber)
{
  var bindex=bnumber;
  var bcneutral=BlocksCaseNeutralAnswersControls[bindex];
  return bcneutral;
}

function getBlockCaseNeutralAnswersMin(bnumber)
{
  var bindex=bnumber;
  var bcneutmin=BlocksCaseNeutralAnswersMins[bindex];
  return bcneutmin;
}


function getBlockCaseNeutralAnswersMax(bnumber)
{
  var bindex=bnumber;
  var bcneutmax=BlocksCaseNeutralAnswersMaxs[bindex];
  return bcneutmax;
}


function getBlockCaseNegativeAnswersControl(bnumber)
{
  var bindex=bnumber;
  var bcnegative=BlocksCaseNegativeAnswersControls[bindex];
  return bcnegative;
}


function getBlockCaseNegativeAnswersMin(bnumber)
{
  var bindex=bnumber;
  var bcnegmin=BlocksCaseNegativeAnswersMins[bindex];
  return bcnegmin;
}


function getBlockCaseNegativeAnswersMax(bnumber)
{
  var bindex=bnumber;
  var bcnegmax=BlocksCaseNegativeAnswersMaxs[bindex];
  return bcnegmax;
}


function getBlockCasePositiveAnswersControl(bnumber)
{
  var bindex=bnumber;
  var bcpositive=BlocksCasePositiveAnswersControls[bindex];
  return bcpositive;
}


function getBlockCasePositiveAnswersMin(bnumber)
{
  var bindex=bnumber;
  var bcposmin=BlocksCasePositiveAnswersMins[bindex];
  return bcposmin;
}


function getBlockCasePositiveAnswersMax(bnumber)
{
  var bindex=bnumber;
  var bcposmax=BlocksCasePositiveAnswersMaxs[bindex];
  return bcposmax;
}


function getBlockCaseNegativeAnswerWidth(bnumber)
{
  var bindex=bnumber;
  var bcnegwidth=BlocksCaseNegativeAnswerWidths[bindex];
  return bcnegwidth;
}


function getBlockCasePositiveAnswerWidth(bnumber)
{
  var bindex=bnumber;
  var bcposwidth=BlocksCasePositiveAnswerWidths[bindex];
  return bcposwidth;
}


function getBlockBackwardAllowed(bnumber)
{
  var bindex = bnumber;
  var allowed = BlocksBackwardAllowed[bindex];
  return allowed;
}


function getBlockBackwardLimit(bnumber)
{
  var bindex = bnumber;
  var limit = BlocksBackwardLimits[bindex];
  return limit;
}


// Block Calculate Methods 


function getBlockQuestionAbsoluteNumber(bnumber,bqnumber)
{
  var base=getBlockMinQuestionNumber(bnumber);
  var qnumber=base+bqnumber-1;
  return qnumber;
}


function getBlockQuestionSequenceNumber(bnumber,bqnumber)
{
  var base=0;
  for (var b=1;b<bnumber;b++) {
    var bcount=getBlockQuestionsCount(b);
    base+=bcount;
  }
  var qsnumber=base+bqnumber;
  return qsnumber;
}



// Current Block Methods


function getCurrentBlockNumber()
{
  return CurrentBlockNumber;
}


function getCurrentBlockTitle()
{
  var bnumber=getCurrentBlockNumber();
  var btitle=getBlockTitle(bnumber);
  return btitle;
}


function getCurrentBlockAdaptiveMode()
{
  var bnumber = getCurrentBlockNumber();
  var bmode = getBlockAdaptiveMode(bnumber);
  return bmode;
}


function isCurrentBlockAdaptiveIrt()
{
  var mode = getCurrentBlockAdaptiveMode();
  var adaptive = (mode=="irt");
  return adaptive;
}


function getCurrentBlockQuestionNumber()
{
  return CurrentBlockQuestionNumber;
}


function getCurrentQuestionSequenceNumber()
{
  var bnumber=getCurrentBlockNumber();
  var bqnumber=getCurrentBlockQuestionNumber();
  var qnumber=getBlockQuestionSequenceNumber(bnumber,bqnumber);
  return qnumber;
}


function getCurrentQuestionAbsoluteNumber()
{
  var bnumber=getCurrentBlockNumber();
  var bqnumber=getCurrentBlockQuestionNumber();
  var qnumber=getBlockQuestionAbsoluteNumber(bnumber,bqnumber);
  qnumber = getQuestionAbsoluteNumberBySerial(qnumber);
  return qnumber;
}


function getCurrentBlockQuestionsCount()
{
  var bnumber=getCurrentBlockNumber();
  var bqcount=getBlockQuestionsCount(bnumber);
  return bqcount;
}


function getCurrentBlockTimeLimit()
{
  var bnumber=getCurrentBlockNumber();
  var btlimit=getBlockBlockTimeLimit(bnumber)
  return btlimit;
}


function getCurrentBlockTimeValue()
{
  var bnumber=getCurrentBlockNumber();
  var btime=getProtocolBlockTimeValue(bnumber);
  return btime;
}


function setCurrentBlockTimeValue(btime)
{
  var bnumber=getCurrentBlockNumber();
  setProtocolBlockTimeValue(bnumber,btime);
  return btime;
}


function getCurrentQuestionTimeLimit()
{
  var bnumber=getCurrentBlockNumber();
  var qtlimit=getBlockQuestionTimeLimit(bnumber)
  return qtlimit;
}


function getCurrentQuestionTimeValue()
{
  var qnumber=getCurrentQuestionAbsoluteNumber();
  var qtime=getProtocolQuestionTimeValue(qnumber);
  return qtime;
}


function setCurrentQuestionTimeValue(qtime)
{
  var qnumber=getCurrentQuestionAbsoluteNumber();
  return setProtocolQuestionTimeValue(qnumber,qtime);
}


function getCurrentQuestionTimeIsOut()
{
  var qnumber=getCurrentQuestionAbsoluteNumber();
  var timeout=getProtocolQuestionTimeIsOut(qnumber);
  return timeout;
}


function getCurrentQuestionViewCount()
{
  var qnumber=getCurrentQuestionAbsoluteNumber();
  var count=getProtocolQuestionViewCount(qnumber)
  return count;
}


function setCurrentQuestionViewCount(count)
{
  var qnumber=getCurrentQuestionAbsoluteNumber();
  return setProtocolQuestionViewCount(qnumber,count);
}


function getCurrentBlockInstrucText()
{
  var bnumber=getCurrentBlockNumber();
  var itext=getBlockInstrucText(bnumber);
  return itext;
}


function getCurrentBlockInstrucEnabled()
{
  var bnumber=getCurrentBlockNumber();
  var ienabled=getBlockInstrucEnabled(bnumber);
  return ienabled;
}


function getCurrentBlockInstrucVisible()
{
  var bnumber=getCurrentBlockNumber();
  var ivisible=getBlockInstrucVisible(bnumber);
  return ivisible;
}


function getCurrentBlockRandomQuestions()
{
  var bnumber=getCurrentBlockNumber();
  var qrandom=getBlockRandomQuestions(bnumber);
  return qrandom;
}


function getCurrentBlockRandomAnswers()
{
  var bnumber=getCurrentBlockNumber();
  var arandom=getBlockRandomAnswers(bnumber);
  return arandom;
}


// Current Block Answer Control Methods


function getCurrentBlockNeutralAnswersControl()
{
  var bnumber=getCurrentBlockNumber();
  var bneutral=getBlockNeutralAnswersControl(bnumber);
  return bneutral;
}

function getCurrentBlockNeutralAnswersPercentMin()
{
  var bnumber=getCurrentBlockNumber();
  var bneutmin=getBlockNeutralAnswersPercentMin(bnumber);
  return bneutmin;
}

function getCurrentBlockNeutralAnswersPercentMax()
{
  var bnumber=getCurrentBlockNumber();
  var bneutmax=getBlockNeutralAnswersPercentMax(bnumber);
  return bneutmax;
}

function getCurrentBlockCaseNeutralAnswersControl()
{
  var bnumber=getCurrentBlockNumber();
  var bcneutral=getBlockCaseNeutralAnswersControl(bnumber);
  return bcneutral;
}

function getCurrentBlockCaseNeutralAnswersMin()
{
  var bnumber=getCurrentBlockNumber();
  var bcneutmin=getBlockCaseNeutralAnswersMin(bnumber);
  return bcneutmin;
}

function getCurrentBlockCaseNeutralAnswersMax()
{
  var bnumber=getCurrentBlockNumber();
  var bcneutmax=getBlockCaseNeutralAnswersMax(bnumber);
  return bcneutmax;
}

function getCurrentBlockCaseNegativeAnswersControl()
{
  var bnumber=getCurrentBlockNumber();
  var bcnegative=getBlockCaseNegativeAnswersControl(bnumber);
  return bcnegative;
}

function getCurrentBlockCaseNegativeAnswersMin()
{
  var bnumber=getCurrentBlockNumber();
  var bcnegmin=getBlockCaseNegativeAnswersMin(bnumber);
  return bcnegmin;
}

function getCurrentBlockCaseNegativeAnswersMax()
{
  var bnumber=getCurrentBlockNumber();
  var bcnegmax=getBlockCaseNegativeAnswersMax(bnumber);
  return bcnegmax;
}

function getCurrentBlockCasePositiveAnswersControl()
{
  var bnumber=getCurrentBlockNumber();
  var bcpositive=getBlockCasePositiveAnswersControl(bnumber);
  return bcpositive;
}

function getCurrentBlockCasePositiveAnswersMin()
{
  var bnumber=getCurrentBlockNumber();
  var bcposmin=getBlockCasePositiveAnswersMin(bnumber);
  return bcposmin;
}

function getCurrentBlockCasePositiveAnswersMax()
{
  var bnumber=getCurrentBlockNumber();
  var bcposmax=getBlockCasePositiveAnswersMax(bnumber);
  return bcposmax;
}

function getCurrentBlockCaseNegativeAnswerWidth()
{
  var bnumber = getCurrentBlockNumber();
  var bcnegwidth = getBlockCaseNegativeAnswerWidth(bnumber);
  return bcnegwidth;
}

function getCurrentBlockCasePositiveAnswerWidth()
{
  var bnumber = getCurrentBlockNumber();
  var bcposwidth = getBlockCasePositiveAnswerWidth(bnumber);
  return bcposwidth;
}

function getCurrentBlockBackwardAllowed()
{
  var bnumber = getCurrentBlockNumber();
  var allowed = getBlockBackwardAllowed(bnumber);
  return allowed;
}

function getCurrentBlockBackwardLimit()
{
  var bnumber = getCurrentBlockNumber();
  var limit = getBlockBackwardLimit(bnumber);
  return limit;
}



// Block Show Methods


function showBlockCurrentQuestion()
{
  CurrentQuestionNumber=getCurrentQuestionAbsoluteNumber();
  if (CurrentQuestionNumber>0) {
    var html=htmlQuestion(CurrentQuestionNumber);
    setTestingContent(html);
  //showDebugString("document.all.length = "+document.all.length);
  }
}


function showCurrentBlockInfo()
{
  var bnumber=getCurrentBlockNumber();
  var bcount=getTestBlocksCount();
  var btitle=getCurrentBlockTitle();
  var string="Блок";
  if (bcount>1) string+=" "+bnumber+" из "+bcount;
  if (btitle!="") string+=":  "+btitle;
  if ((bcount==1) && (btitle=="")) string=" ";
  setBlockTitleContent(string);
}


function showBlockInstruc(runtime)
{
  runtime = (runtime==true);
  var ienabled = getCurrentBlockInstrucEnabled();
  var ivisible = getCurrentBlockInstrucVisible();
  if (!ienabled || !ivisible) return false;
  if (runtime) saveCurrentQuestionAnswers();
  if (!runtime) {
    pauseBlockTimer(true);
    pauseQuestionTimer(true);
  }
  var qviews = getCurrentQuestionViewCount();
  setCurrentQuestionViewCount(qviews-1);
  var itext = getCurrentBlockInstrucText();
  var html = htmlBlockInstruc(itext,runtime);
  setTestingContent(html);
  if (!runtime) {
    setProgressBarsHidden(true);
    setQuestionNumberHidden(true);
  }
  return true;
}


function hideBlockInstruc(runtime)
{
  runtime = (runtime==true);
  onBlockQuestionNumberChanged();
  if (!runtime) {
    setProgressBarsHidden(false);
    setQuestionNumberHidden(false);
    pauseBlockTimer(false);
    pauseQuestionTimer(false);
  }
}


function showBlockTimeoutInstruct()
{
  pauseBlockTimer(true);
  pauseQuestionTimer(true);
  var html=htmlInstructBlockTimeout();
  setTestingContent(html);
}


function hideBlockTimeoutInstruct()
{
  startTestNextBlock();
}


function showTestingCompleteInstruct()
{
  pauseBlockTimer(true);
  pauseQuestionTimer(true);
  var html=htmlInstructTestingComplete();
  setTestingContent(html);
  setProgressBarsHidden(true);
  setQuestionNumberHidden(true);
  return true;
}





// Blocks Set Methods


function setCurrentBlockNumber(bnumber)
{
  CurrentBlockNumber = bnumber;
  var initialized = (BlocksQuestionsNeutralAnswers.length>bnumber);
  if (!initialized) {
    BlocksQuestionsNeutralAnswers[bnumber] = new Array();
    var bqcount = getBlockQuestionsCount(bnumber);
    for (var bq=0; bq<bqcount; bq++) {
      BlocksQuestionsNeutralAnswers[bnumber][bq] = false;
    }
  }
}


function setCurrentBlockQuestionNumber(bqnumber)
{
  CurrentBlockQuestionNumber=bqnumber;
}


function setCurrentQuestionSequenceNumber(qsnumber)
{
  var base=0;
  var bnumber=0;
  var bqnumber=0;
  var bcount=getTestBlocksCount();
  for (var b=1;b<=bcount;b++) {
    var bqcount=getBlockQuestionsCount(b);
    base+=bqcount;
    if (base>=qsnumber) {
      bnumber=b;
      bqnumber=qsnumber-(base-bqcount);
      break;
    }
  }
//alert("setCurrentQuestionSequenceNumber\nqsnumber: "+qsnumber+"\nbnumber: "+bnumber+"\nbqnumber: "+bqnumber);
  setCurrentBlockNumber(bnumber);
  setCurrentBlockQuestionNumber(bqnumber);
}




// Block Progress Methods


function initBlockItemsProgress(bnumber)
{
  var bqcount=getCurrentBlockQuestionsCount();
  var progress=htmlProgressBar("BlockItemsProgressBar",bqcount,0,ProgressBarsWidth);
  setBlockItemsProgressBarContent(progress);
}


function initBlockTimeProgress()
{
  var blimit=getCurrentBlockTimeLimit();
  var string="";
  var progress="";
  if (blimit>0) {
    string="&nbsp;"
    progress=htmlProgressBar("BlockTimeProgressBar",blimit,0,ProgressBarsWidth);
  } else {
    string="Время на блок:";
    progress="не ограничено";
  }
  setBlockTimeProgressTextContent(string);
  setBlockTimeProgressBarContent(progress);
}


function initQuestionTimeProgress()
{
  var qlimit=getCurrentQuestionTimeLimit();
  var string="";
  var progress="";
  if (qlimit>0) {
    string="&nbsp;";
    progress=htmlProgressBar("QuestionTimeProgressBar",qlimit,0,ProgressBarsWidth);
  } else {
    string="Время на задание:";
    progress="не ограничено";
  }
  setQuestionTimeProgressTextContent(string);
  setQuestionTimeProgressBarContent(progress);
}


function showBlockItemsProgress()
{
  var bqnumber=getCurrentBlockQuestionNumber();
  var bqcount=getCurrentBlockQuestionsCount();
  var string="Задание блока: "+bqnumber+" из "+bqcount;
  setBlockItemsProgressTextContent(string);
  setProgresPosition("BlockItemsProgressBar",bqnumber-1);
  setBlockQuestionNumberContent(bqnumber);
}


function showBlockTimeProgress()
{
  var blimit=getCurrentBlockTimeLimit();
  if (blimit>0) {
    var btime=getCurrentBlockTimeValue();
    var string="Время на блок: "+getLimitTimeString(btime,blimit)+" из "+getLimitTimeString(blimit,blimit);
    setBlockTimeProgressTextContent(string);
    setProgresPosition("BlockTimeProgressBar",btime);
  }
}


function showQuestionTimeProgress()
{
  var qlimit=getCurrentQuestionTimeLimit();
  if (qlimit>0) {
    var qtime=getCurrentQuestionTimeValue();
    var string="Время на задание: "+getLimitTimeString(qtime,qlimit)+" из "+getLimitTimeString(qlimit,qlimit);
    setQuestionTimeProgressTextContent(string);
    setProgresPosition("QuestionTimeProgressBar",qtime);
  }
}


function getLimitTimeString(time,maxtime)
{
  var mins=(maxtime>=60);
  var timeval = mins? (Math.round(10*time/60)/10):time;
  if (time<maxtime) timeval=Math.floor(timeval);
  var string = timeval+" "+(mins? "мин":"сек");
  return string;
}




// Block Event Handlers


function onBlockNumberChanged()
{
  initBlockItemsProgress();
  initBlockTimeProgress();
  showBlockItemsProgress();
  showBlockTimeProgress();
  showCurrentBlockInfo();
  startBlockTimer();
}


function onBlockQuestionNumberChanged()
{
  showBlockCurrentQuestion();
  showBlockItemsProgress();
  initQuestionTimeProgress();
  showQuestionTimeProgress();
  startQuestionTimer();
  var views=getCurrentQuestionViewCount();
  setCurrentQuestionViewCount(views+1);
  var prev = isPrevQuestionAvailable();
  var adaptive = isCurrentBlockAdaptiveIrt();
  setPrevButtonEnabled(prev && !adaptive);
  queueCurrentTestPosition();
  tryDebugAutoRespondMode(0);
}



function onTestingNextStep()
{
  if (isCurrentAnswerComplete() && isCurrentAnswerCorrect()) {
    saveCurrentQuestionAnswers();
    saveCurrentQuestionNeutralAnswers();

//var restart = isRestartNeutralAnswersOverride();
//alert("restart="+restart);

    var absqnumber = getCurrentQuestionAbsoluteNumber();
    var adaptive = isCurrentBlockAdaptiveIrt();
    if (adaptive) {
      var processed = processCurrentAdaptiveQuestion();
      if (!processed) return false;
      var pointer = getCurrentQuestionAdaptiveActualPointer();
      var terminated = (!pointer);
    }
    var bcount = getTestBlocksCount();
    var bnumber = getCurrentBlockNumber();
    var bqcount = getCurrentBlockQuestionsCount();
    var bqnumber = getCurrentBlockQuestionNumber();
    var nextblock = (bqnumber>=bqcount) || (adaptive && terminated);
    if (!nextblock) {
      if (CurrentBlockBackwardLevel>0) CurrentBlockBackwardLevel--;
      setCurrentBlockQuestionNumber(bqnumber+1);
      onBlockQuestionNumberChanged();
    } else {
      CurrentBlockBackwardLevel=0;
      startTestNextBlock();
    }
  }
  window.scrollTo(0,0);
}


function onTestingPrevStep()
{
  var bcount = getTestBlocksCount();
  var bnumber = getCurrentBlockNumber();
  var bqcount = getCurrentBlockQuestionsCount();
  var bqnumber = getCurrentBlockQuestionNumber();
  saveCurrentQuestionAnswers();
  if (bqnumber>1) {
    CurrentBlockBackwardLevel++;
    setCurrentBlockQuestionNumber(bqnumber-1);
    onBlockQuestionNumberChanged();
  } else 
  if ((bqnumber==1) && (bnumber>1)) {
    setCurrentBlockNumber(bnumber-1);
    bqcount = getCurrentBlockQuestionsCount();
    setCurrentBlockQuestionNumber(bqcount);
    onBlockNumberChanged();
  }
  window.scrollTo(0,0);
}




// Block Timer Methods


function startBlockTimer()
{
  var btime=getCurrentBlockTimeValue();
  var blimit=getCurrentBlockTimeLimit();
  var onout='onTestBlockTimeOut();';
  startTimer("TestBlockTimer",1000*btime,1000*blimit,0,"onTestBlockTimerTick();",onout);
}


function pauseBlockTimer(pause)
{
  pauseTimer("TestBlockTimer",pause);
}


function onTestBlockTimerTick()
{
  var value=getTimerValue("TestBlockTimer");
  var btime=Math.round(value/1000);
  setCurrentBlockTimeValue(btime);
  showBlockTimeProgress();
}


function onTestBlockTimeOut()
{
  showBlockTimeoutInstruct();
}


function startQuestionTimer()
{
  var qtime=getCurrentQuestionTimeValue();
  var qlimit=getCurrentQuestionTimeLimit();
  var onout='onTestQuestionTimeOut();';
  startTimer("TestQuestionTimer",1000*qtime,1000*qlimit,0,"onTestQuestionTimerTick();",onout);
}


function pauseQuestionTimer(pause)
{
  pauseTimer("TestQuestionTimer",pause);
}


function onTestQuestionTimerTick()
{
  var value=getTimerValue("TestQuestionTimer");
  var qtime=Math.round(value/1000);
  setCurrentQuestionTimeValue(qtime);
  showQuestionTimeProgress();
}


function onTestQuestionTimeOut()
{
  pauseQuestionTimer(true);
  var qnumber=getCurrentQuestionAbsoluteNumber();
  setQuestionEnabled(qnumber,false);
  setObjectHidden("idQuestionTable",true);
  setObjectHidden("idQuestionTimeoutTable",false);
  var message="Время, отведенное на текущее задание, истекло.";
  showQuestionMessageAlert(message);
}


function pauseTestingTimers(pause)
{
  pauseBlockTimer(pause);
  pauseQuestionTimer(pause);
}


// Others Methods


function isCurrentAnswerComplete()
{
  var qnumber = getCurrentQuestionAbsoluteNumber();
  var sacount = getScreenCheckedAnswersCount(qnumber);
  var qacount = getTestQuestionAnswersCount(qnumber);
  var message = "";
  var complete=true;
  var code = getTestQuestionTypeCode(qnumber);
  switch (code) {
    case "single":
      complete = (sacount>0) || (qacount<1);
      message="Не задан ответ для тестового задания.\nПожалуйста, задайте свой вариант ответа.";
      break;
    case "multiple-slider":
    case "multiple-radios":
      complete=(sacount==qacount);
      message="Ответы для тестового задания заданы не полностью.\nПожалуйста, задайте свои варианты ответов.";
      break;
  }
  var timeout = getCurrentQuestionTimeIsOut();
  if (timeout) complete=true;
  if (!complete) alert(message);
  var expertise=isTestExpertiseMode();
  if (complete && expertise) complete=isCurrentExpertiseComplete();
  return complete;
}


function isCurrentExpertiseComplete()
{
  var complete=true;
  var message = "";
  var fcount=getExpertiseFactorsCount();
  var vcount=getScreenQuestionFactorsValuesCount();
  if (vcount<fcount) {
    complete=false;
    var message1="Не задана экспертная оценка для текущего задания.\nПожалуйста, задайте оценку для тестового задания.";
    var message2="Экспертная оценка для текущего задания задана не полностью.\nПожалуйста, задайте оценку задания по всем критериям.";
    message = (vcount>0)? message2:message1;
  }
  if (!complete) alert(message);
  return complete;
}



function isCurrentAnswerCorrect()
{
  var correct = true;
  var qnumber = getCurrentQuestionAbsoluteNumber();
  var qcode = getTestQuestionTypeCode(qnumber);
  switch (qcode) {
    case "single":
    case "single-text":
      correct = true;
      break;
    case "multiple":
      correct = isMultipleAnswerCorrect(qnumber);
      break;
    case "multiple-slider":
    case "multiple-radios":
      correct = isMultipleSliderAnswerCorrect(qnumber);
      break;
    case "multiple-select":
    case "multiple-text":
      correct = true;
      break;
  }
  return correct;
}


function isMultipleAnswerCorrect(qnumber)
{
  var error="";
  var bcpositive = getCurrentBlockCasePositiveAnswersControl();
  if (bcpositive && !error) {
    var positives = getScreenQuestionCheckedAnswersCount(qnumber);
    var bcposmin = getCurrentBlockCasePositiveAnswersMin();
    var bcposmax = getCurrentBlockCasePositiveAnswersMax();
    if ((bcposmin>0) && (positives<bcposmin)) error="Внимание!\nЧисло выбранных ответов должно быть не меньше "+bcposmin+".\nПожалуйста, задайте приемлемые варианты ответов."; else
    if ((bcposmax>0) && (positives>bcposmax)) error="Внимание!\nЧисло выбранных ответов должно быть не больше "+bcposmax+".\nПожалуйста, задайте приемлемые варианты ответов."; 
  }
  var correct=(error=="");
  if (!correct) alert(error);
  return correct;
}


function isMultipleSliderAnswerCorrect(qnumber)
{
  var error="";
  var bcpositive = getCurrentBlockCasePositiveAnswersControl();
  var bcnegative = getCurrentBlockCaseNegativeAnswersControl();
  var bcneutral = getCurrentBlockCaseNeutralAnswersControl();
  if (bcpositive && !error) {
    var positives = getScreenQuestionPositiveAnswersCount(qnumber);
    var bcposmin = getCurrentBlockCasePositiveAnswersMin();
    var bcposmax = getCurrentBlockCasePositiveAnswersMax();
    if ((bcposmin>0) && (positives<bcposmin)) error="Внимание!\nЧисло положительных ответов должно быть не меньше "+bcposmin+".\nПожалуйста, задайте приемлемые варианты ответов."; else
    if ((bcposmax>0) && (positives>bcposmax)) error="Внимание!\nЧисло положительных ответов должно быть не больше "+bcposmax+".\nПожалуйста, задайте приемлемые варианты ответов."; 
  }
  if (bcnegative && !error) {
    var negatives = getScreenQuestionNegativeAnswersCount(qnumber);
    var bcnegmin = getCurrentBlockCaseNegativeAnswersMin();
    var bcnegmax = getCurrentBlockCaseNegativeAnswersMax();
    if ((bcnegmin>0) && (negatives<bcnegmin)) error="Внимание!\nЧисло отрицательных ответов должно быть не меньше "+bcnegmin+".\nПожалуйста, задайте приемлемые варианты ответов."; else
    if ((bcnegmax>0) && (negatives>bcnegmax)) error="Внимание!\nЧисло отрицательных ответов должно быть не больше "+bcnegmax+".\nПожалуйста, задайте приемлемые варианты ответов."; 
  } 
  if (bcneutral && !error) {
    var neutrals=getScreenQuestionNeutralAnswersCount(qnumber);
    var bcneutmin=getCurrentBlockCaseNeutralAnswersMin();
    var bcneutmax=getCurrentBlockCaseNeutralAnswersMax();
    if ((bcneutmin>0) && (neutrals<bcneutmin)) error="Внимание!\nЧисло нейтральных ответов должно быть не меньше "+bcneutmin+".\nПожалуйста, задайте приемлемые варианты ответов."; else
    if ((bcneutmax>0) && (neutrals>bcneutmax)) error="Внимание!\nЧисло нейтральных ответов должно быть не больше "+bcneutmax+".\nПожалуйста, задайте приемлемые варианты ответов."; 
  } 
  var correct=(error=="");
  if (!correct) alert(error);
  return correct;
}


function saveCurrentQuestionAnswers()
{
  var qnumber = getCurrentQuestionAbsoluteNumber();
  if (qnumber>0) {
    var answers = getScreenQuestionAnswers(qnumber);
    setProtocolQuestionAnswers(qnumber,answers);
    queueCurrentQuestionAnswers(qnumber,answers);
    var expertise = isTestExpertiseMode();
    if (expertise) {
      var values = getScreenQuestionFactorsValues();
      setExpertiseQuestionFactorsValues(qnumber,values);
      queueCurrentExpertiseFactorsValues(qnumber,values);
      var enabled = getExpertiseCommentsEnabled();
      if (enabled) {
        var comment=getScreenQuestionFactorsComment();
        setExpertiseQuestionFactorsComment(qnumber,comment);
        queueCurrentExpertiseFactorsComment(qnumber,comment);
      }
    }
  }
  return true;
}


function isPrevQuestionAvailable()
{
  var bqnumber = getCurrentBlockQuestionNumber();
  var backallow = getCurrentBlockBackwardAllowed();
  var backlimit = getCurrentBlockBackwardLimit();
  var available = (bqnumber>1) && backallow && ((backlimit==0) || (CurrentBlockBackwardLevel<backlimit));
  return available;
}



function saveCurrentQuestionNeutralAnswers()
{
  var bnumber = getCurrentBlockNumber();
  var bqnumber = getCurrentBlockQuestionNumber();
  var qnumber = getCurrentQuestionAbsoluteNumber();
  var neutral = isNeutralQuestionSingleAnswer(qnumber);
  BlocksQuestionsNeutralAnswers[bnumber][bqnumber-1] = neutral;
}


function calcCurrentBlockNeutralAnswersPercent()
{
  var bnumber = getCurrentBlockNumber();
  var neutrals = BlocksQuestionsNeutralAnswers[bnumber];
  var count = 0;
  var length = neutrals.length;
  for (var i=0; i<length; i++) {
    if (neutrals[i]) count++;
  }
  var percent = count/length*100;
  return percent;
}


function isRestartNeutralAnswersOverride()
{
return false;
// нужно считать нейтральные ответы на каждую линейную шкалу, а не просто все подряд - пока это не готово 
// (нужно придумат, как безопасно использовать ключевую информацию на клиенте
  var override = false;
  var bneutral = getCurrentBlockNeutralAnswersControl();
  if (!bneutral) return false;
  if (bneutral) {
    var percent = calcCurrentBlockNeutralAnswersPercent();
    var bnumber = getCurrentBlockNumber();
    var min = getCurrentBlockNeutralAnswersPercentMin();
    var max = getCurrentBlockNeutralAnswersPercentMax();
    if ((min>0) && (percent>=min) && (percent<max)) {
      var message = "(Достигнут порог предупреждения по нейтральным ответам)";
      alert(message);
    } else
    if ((max>0) && (percent>=max)) {
      var message = "(Достигнут порог возврата по нейтральным ответам)";
      alert(message);
      override = true;
    }
  }
  return override;
}
