<?xml version="1.0" encoding="UTF-8"?>
<!--
$RCSfile: rnmc_stdQuestion.xml $
$Revision: 1032 $

last change: $Date: 2009-03-24 18:24:47 +0300 (Вт, 24 мар 2009) $
             $Author: toha $

  Lacerta Project
  version 1.0.0.1
  Copyright (C) 2007-2009 RNMC
-->

<rmml>
<composition name="rnmc_stdQuestion" class="rnmc_stdMediaGroup">
<script><![CDATA[
  this.type = "rnmc_Question";

//  =================================================================
//  настройки элемента

//  вывод вопросов в произвольном порядке
  this.questionsRandom = true;
//  количество вопросов которое необходимо задать (-1 - все)
  this.questionsToDisplay = -1;
//  возможность перебора вопросов
  this.allowSelection = true;
//  разрешено повторно отвечать на вопросы
  this.allowMultipleAttempts = true;
//  стиль запрета на повторное отвечание на один и тот же вопрос
  this.excludeStyle = QUESTION_DISABLE;
//  зацикливание набора вопросов (т.е. после последнего переходит к первому и наоборот)
  this.selectionCycling = true;

//  произвольный порядок вывода ответов на экран
//  настройка учитываецца если не указано иного в отдельном вопросе
  this.answersRandom = true;

//  автопереход к слежующему вопросу
  this.autoSkip = false;

//  направления перехода при autoskip (когда отвечают на вопрос -
//  происходит автопереход к другому возможному вопросу)
//  this.autoSkipDirection = QUESTION_AUTOSKIP_BACK; // - к предыдущему возможному в наборе
//  this.autoSkipDirection = QUESTION_AUTOSKIP_RANDOM; // - к произвольному возможному в наборе
  this.autoSkipDirection = QUESTION_AUTOSKIP_FORWARD; // - к следующему возможному в наборе

//  время в миллисекундах при автопереходе к слеующему вопросу
  this.autoSkipTimeout = 2000;

//  id для setTimeout
  this.autoSkipTimer = -1;

//  ограничение на максимальное количесвто ответов ддля одного вопроса на экране
  this.maxAnswersAllowed = -1;

//  если установлен -то в вопросе можно выбрать только один ответ (галочка будет перескакивать)
  this.answersOnlyOneSelected = "auto";

//  момент проверки ответов вопроса
  this.checkMode = QUESTION_CHECK_AFTER;

//  лайот
  this.answersLayout = LAYOUT_VERTICAL;
//  стартовые координаты для ответов (по умолчанию - т.е. если в конкретном
//  вопросе не заданы другие)
  this.answersX = 0;
  this.answersY = 0;

//  массив вопросов
  this.questionsArray = null; 

//  текущий вопрос (группа вопросов)
  this.questionIndex = null;
//  последовательность вопросов
  this.questionSequence = null;

//  номер текущего вопроса
  this.currentQuestionIndex = -1;

//  действия, выполняющиеся када все вопросы сичтаются отвеченными
//  т.е. имеют state != QUESTION_STATE_NOTANSWERED
  this.onAllQuestionsAnsweredActions = null;
  
  this.answeredRightActions = null;
  this.answeredWrongActions = null;
  this.onShowQuestion       = null;
  this.onHideQuestion       = null;
  this.onSelectAllElements  = null;

//  Специализированные кнопки (а накуя я не знаю, мона
//  генерить action на лету - тада даже если их нет - ничо страшного)
  this.btnPreviousQuestion = null;
  this.btnNextQuestion = null;
  this.btnCheckAnswers = null;
  this.btnResetAnswers = null;

//  настройки счётчика вопросов
  this.counterVisible = false;
  this.counterObject = null;
  this.counterFormat = null;
  this.counterStyle = null;
  this.counterX = 0;
  this.counterY = 0;

//  настройки чекбокса
  this.checkBoxNormalBorder   = null;
  this.checkBoxNormalMark     = null;
  this.checkBoxDisabledBorder = null;
  this.checkBoxDisabledMark   = null;
  
  this.errorCheckBoxSrc = null;
  
  this.noSelectCheckBoxImg = null;  //f

// Количество впросов на которые пользователь ответил
  this.questionsAnswered = 0;

// текущий результат выполнения задания
  this.objectResult = 0;

//  загрузка шага
  function initFromNode(srcNode) {
    if (!srcNode)
      return

    var xmlNode = null;
    var xmlAttributeMap = null;
    var xmlAttribute = null;

    xmlAttributeMap = srcNode.attributes;
    if (xmlAttributeMap){
      xmlAttribute = xmlAttributeMap.getNamedItem("id");
      if (xmlAttribute != null && xmlAttribute.specified)
        this.id = xmlAttribute.value;
      xmlAttribute = xmlAttributeMap.getNamedItem("visible");
      if (xmlAttribute != null && xmlAttribute.specified){
        if(xmlAttribute.value == "true")
          this.visibility = OBJECT_VISIBILITY_TRUE;
        else if(xmlAttribute.value == "false")
          this.visibility = OBJECT_VISIBILITY_FALSE;
      }
      xmlAttribute = xmlAttributeMap.getNamedItem("enabled");
      if (xmlAttribute != null && xmlAttribute.specified
        && xmlAttribute.value.toLowerCase() == "false")
        this.disabled = true;
    }

    this.questionsArray = new Array();
    this.childObjects = new Array();
    this.loadChildsObject(srcNode);

    var srcBase = null;
    if (srcNode.ownerDocument.source){
      var tmp = new String(srcNode.ownerDocument.source).replace("/\/.g", "\\").split("\\")
      tmp.pop();
      srcBase = tmp.join("\\");
    }

    xmlNode = srcNode.firstChild;
    while(xmlNode){
      if(xmlNode.nodeName == "settings"
        || xmlNode.nodeName == "param"){

      // разбор стандартных настроек
        this.parseParamNode(xmlNode);

      // Для совместимости с предыдущими версиями:
      // если режим подсчета не устанавливался, то бралось значение по-умолчанию
        if (this.crAlgorithm == "not_init")
          this.crAlgorithm = "discrete";

        var settingNode = xmlNode.firstChild;
        while(settingNode){
          if(settingNode.nodeName == "questions"){
            xmlAttributeMap = settingNode.attributes;
            if (xmlAttributeMap){
              xmlAttribute = xmlAttributeMap.getNamedItem("random");
              if (xmlAttribute != null && xmlAttribute.specified){
                if(xmlAttribute.value.toLowerCase() == "true"){
                  this.questionsRandom = true;
                } else {
                  this.questionsRandom = false;
                }
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("total");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.questionsToDisplay = parseInt(xmlAttribute.value);
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("allowMultiple");
              if (xmlAttribute != null && xmlAttribute.specified){
                if(xmlAttribute.value.toLowerCase() == "true"){
                  this.allowMultipleAttempts = true;
                } else {
                  this.allowMultipleAttempts = false;
                }
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("excludeStyle");
              if (xmlAttribute != null && xmlAttribute.specified){
                if(xmlAttribute.value.toUpperCase() == "EXCLUDE"){
                //  означает что вопросы будут исключаться из списка
                  this.excludeStyle = QUESTION_EXCLUDE;
                } else if(xmlAttribute.value.toUpperCase() == "DISABLE"){
                //  означает что вопросы будут отображаться
                //  в последнем отвеченном состоянии
                //  но будут недоступны для изменения ответов
                  this.excludeStyle = QUESTION_DISABLE;
                }
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("allowSelection");
              if (xmlAttribute != null && xmlAttribute.specified){
                if(xmlAttribute.value.toLowerCase() == "false"){
                  this.allowSelection = false;
                } else {
                  this.allowSelection = true;
                }
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("selectionCycling");
              if (xmlAttribute != null && xmlAttribute.specified){
                if(xmlAttribute.value.toLowerCase() == "false")
                  this.selectionCycling = false;
              }
              xmlAttribute =  xmlAttributeMap.getNamedItem("checkMode");
              if (xmlAttribute != null && xmlAttribute.specified){
                if(xmlAttribute.value.toUpperCase() == "CHECK_AFTER"){
              //  означает что проверятся ответы будт после
              // нажатия кнопки проверить
                  this.checkMode = QUESTION_CHECK_AFTER;
                } else if(xmlAttribute.value.toUpperCase() == "CHECK_IMMEDIATELY"){
              //  означает что проверятся ответы будт после первого нажатия
                  this.checkMode = QUESTION_CHECK_IMMEDIATELY;
                }
              };
            }
          } else if(settingNode.nodeName == "answers"){
            xmlAttributeMap = settingNode.attributes;
            if (xmlAttributeMap){
              xmlAttribute = xmlAttributeMap.getNamedItem("answersRandom");
              if (xmlAttribute != null && xmlAttribute.specified){
                if(xmlAttribute.value.toLowerCase() == "true"){
                  this.answersRandom = true;
                } else {
                  this.answersRandom = false;
                }
              }
              xmlAttribute =  xmlAttributeMap.getNamedItem("answersLayout");
              if (xmlAttribute != null && xmlAttribute.specified){
                if(xmlAttribute.value.toUpperCase() == "LAYOUT_NO"){
                //  означает что ответы на экране будут
                //  расставлены не в столбцы или строчки,
                //  а по указанным коодинатам
                  this.answersLayout = LAYOUT_NO;
                } else if(xmlAttribute.value.toUpperCase() == "LAYOUT_VERTICAL"){
                //  означает что ответы на экране будут выстроены вертикально
                  this.answersLayout = LAYOUT_VERTICAL;
                } else if(xmlAttribute.value.toUpperCase() == "LAYOUT_HORIZONTAL"){
                //  означает что ответы на экране будут выстроены горизонтально
                  this.answersLayout = LAYOUT_HORIZONTAL;
                }
              };
              xmlAttribute = xmlAttributeMap.getNamedItem("resultMode");
              if (xmlAttribute != null && xmlAttribute.specified){
                if((xmlAttribute.value).toUpperCase() == "SIMPLE_COUNT"){
                //  простой подсчёт результатов - типа если поставлена
                //  галка не там где надо - ошибка сразу, процент 0
                //  this.answersResultCount = QUESTION_SIMPLE_CHECK; - вариант Никиты
                  this.crAlgorithm = "discrete";
                } else if((xmlAttribute.value).toUpperCase() == "MXK_COUNT"){
                //  this.answersResultCount = QUESTION_MXK_CHECK; - вариант Никиты
                  this.crAlgorithm = "smooth_err";
                }
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("onlyOneSelected");
              if (xmlAttribute != null && xmlAttribute.specified){
                if((xmlAttribute.value).toLowerCase() == "true"){
                  this.answersOnlyOneSelected = true;
                } else if((xmlAttribute.value).toLowerCase() == "auto"){
                  this.answersOnlyOneSelected = "auto";
                } else {
                  this.answersOnlyOneSelected = false;
                }
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("maxAllowed");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.maxAnswersAllowed = parseInt(xmlAttribute.value);
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("answersX");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.answersX = parseInt(xmlAttribute.value);
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("answersY");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.answersY = parseInt(xmlAttribute.value);
              }
            }
          } else if(settingNode.nodeName == "counter"){
            xmlAttributeMap = settingNode.attributes;
            if (xmlAttributeMap){
              this.counterVisible = true;
              xmlAttribute =  xmlAttributeMap.getNamedItem("format");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.counterFormat = xmlAttribute.value;
              };
              xmlAttribute = xmlAttributeMap.getNamedItem("style");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.counterStyle = xmlAttribute.value;
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("x");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.counterX = parseInt(xmlAttribute.value);
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("y");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.counterY = parseInt(xmlAttribute.value);
              }
            }
          } else if(settingNode.nodeName == "autoskip"){
            xmlAttributeMap = settingNode.attributes;
            if (xmlAttributeMap){
              this.autoSkip = true;
              xmlAttribute =  xmlAttributeMap.getNamedItem("direction");
              if (xmlAttribute != null && xmlAttribute.specified){
                switch(xmlAttribute.value.toUpperCase()){
                case "FORWARD":
                  this.autoSkipDirection = QUESTION_AUTOSKIP_FORWARD;
                  break;
                case "BACK":
                  this.autoSkipDirection = QUESTION_AUTOSKIP_BACK;
                  break;
                case "RANDOM":
                  this.autoSkipDirection = QUESTION_AUTOSKIP_RANDOM;
                  break;
                }
              };
              xmlAttribute = xmlAttributeMap.getNamedItem("timeout");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.autoSkipTimeout = parseInt(xmlAttribute.value);
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("enabled");
              if (xmlAttribute != null && xmlAttribute.specified){
                if (xmlAttribute.value.toLowerCase() == "false")
                  this.autoSkip = false;
              }
            }
          } else if(settingNode.nodeName == "checkbox"){
            xmlAttributeMap = settingNode.attributes;
            if (xmlAttributeMap){
              xmlAttribute =  xmlAttributeMap.getNamedItem("normalBorder");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.checkBoxNormalBorder =
                  scene.Utils.makePathSrc(srcBase, xmlAttribute.value);
              };
              xmlAttribute = xmlAttributeMap.getNamedItem("normalMark");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.checkBoxNormalMark =
                  scene.Utils.makePathSrc(srcBase, xmlAttribute.value);
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("disabledBorder");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.checkBoxDisabledBorder =
                  scene.Utils.makePathSrc(srcBase, xmlAttribute.value);
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("disabledMark");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.checkBoxDisabledMark =
                  scene.Utils.makePathSrc(srcBase, xmlAttribute.value);
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("errorCheckBox");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.errorCheckBoxSrc =
                  scene.Utils.makePathSrc(srcBase, xmlAttribute.value);
              }
              xmlAttribute = xmlAttributeMap.getNamedItem("noSelectCheckBox");
              if (xmlAttribute != null && xmlAttribute.specified){
                this.noSelectCheckBoxSrc =
                  scene.Utils.makePathSrc(srcBase, xmlAttribute.value);
              }
            }
          }
          settingNode = settingNode.nextSibling;
        }
      } else if(xmlNode.nodeName == "questions"){
        var questionNode = xmlNode.firstChild;
        while(questionNode){
          if(questionNode.nodeName == "question"){
            var newObject = new Composition();
            newObject._class = "question_singleQuestion";
            newObject.parent = this;
          //  устанавливаем св-ва вопроса по умолчанию ----
            newObject.crAlgorithm = this.crAlgorithm;
            newObject.excludeStyle = this.excludeStyle;
            newObject.allowMultipleAttempts = this.allowMultipleAttempts;
            newObject.maxAnswersAllowed = this.maxAnswersAllowed;
            newObject.answersOnlyOneSelected = this.answersOnlyOneSelected;
            newObject.checkMode = this.checkMode;
            newObject.answersRandom = this.answersRandom;
            newObject.answersLayout = this.answersLayout;
            newObject.answersX = this.answersX;
            newObject.answersY = this.answersY;

            newObject.checkBoxNormalBorder   = this.checkBoxNormalBorder;
            newObject.checkBoxNormalMark     = this.checkBoxNormalMark;
            newObject.checkBoxDisabledBorder = this.checkBoxDisabledBorder;
            newObject.checkBoxDisabledMark   = this.checkBoxDisabledMark;
            
            newObject.errorCheckBoxSrc       = this.errorCheckBoxSrc;
      newObject.noSelectCheckBoxSrc       = this.noSelectCheckBoxSrc;
      
          //  ---------------------------------------------
            newObject.visible = false;
            if(newObject.initFromNode(questionNode)){
              this.questionsArray.push(newObject);
            } else {
              newObject.parent = null;
              newObject = null;
            }
          }
          questionNode = questionNode.nextSibling;
        }
      } else if(xmlNode.nodeName == "actions"){
        this.parseActionsNode(xmlNode);

        this.onAllQuestionsAnsweredActions =
          scene.Utils.parseActionsNode(xmlNode, "onAllQuestionAnswered");

      //  действия - если отвечен верно
        this.answeredRightActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredRight");

      //  действия - если отвечен неверно
        this.answeredWrongActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredWrong");
          
      // показали вопрос
        this.onShowQuestion =
          scene.Utils.parseActionsNode(xmlNode, "onShowQuestion");
          
      // скрыли вопрос вопрос
        this.onHideQuestion =
          scene.Utils.parseActionsNode(xmlNode, "onHideQuestion");  
          
      // действие - вывод сообщение, что выбраны все эллементы
        this.onSelectAllElements =
          scene.Utils.parseActionsNode(xmlNode, "onSelectAllElements");  
/*
      //  действия - если результат ответа ниже порогового значения 
        this.answeredBelowResultActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredBelowResult");

      //  действия - если результат ответа выше порогового значения 
        this.answeredAboveResultActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredAboveResult");

      //  действия - если результат ответа находицца между
      //    двумя значенимя в формате "нижн;верхн"
        this.answeredBetweenResultsActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredBetweenResult");
*/
      } else if(xmlNode.nodeName == "effects"){
        this.parseEffectsNode(xmlNode);
      } else if(xmlNode.nodeName == "objectives"){
        this.parseObjectivesNode(xmlNode);
      } else if(xmlNode.nodeName == "conditions"){
        var conditionNode = xmlNode.firstChild;
        while(conditionNode){
          if(conditionNode.nodeName == "condition"){
            this.parseConditionNode(conditionNode);
          }
          conditionNode = conditionNode.nextSibling;
        }
        this.parseConditionNode(xmlNode);
      }
      xmlNode = xmlNode.nextSibling;
    }

  //  поиск кнопок с соответствующимим id и установка callback'ов
    for(var i = 0; i < this.childObjects.length; i++){
      if(this.childObjects[i].type == "rnmc_stdButton"){
        switch(this.childObjects[i].id){
        case "btnPreviousQuestion":
        //  надобность этого мягко говоря под вопросом
          this.btnPreviousQuestion = this.childObjects[i];
          this.childObjects[i].setReleaseCallBack(this, this.buttonDispatcher);
          break;
        case "btnNextQuestion":
        //  надобность этого мягко говоря под вопросом
          this.btnNextQuestion = this.childObjects[i];
          this.childObjects[i].setReleaseCallBack(this, this.buttonDispatcher);
          break;
        case "btnCheck":
        //  надобность этого мягко говоря под вопросом
          this.btnCheckAnswers = this.childObjects[i];
          this.childObjects[i].setReleaseCallBack(this, this.buttonDispatcher);
          break;
        case "btnReset":
        //  надобность этого мягко говоря под вопросом
          this.btnResetAnswers = this.childObjects[i];
          this.childObjects[i].setReleaseCallBack(this, this.buttonDispatcher);
          break;
        }
      }
    }
    if(this.counterVisible){
      this.counterObject = new Text();
      this.counterObject.parent = this;
      this.counterObject.visible = true;
      this.counterObject.x = this.counterX;
      this.counterObject.y = this.counterY;
      if(this.counterStyle){
        this.counterObject.style = this.counterStyle;
      }
    }
    return true;
  }

  function showObject(){
  //  для объекта question
    this.questionSequence = new Array();
    if(this.questionsRandom){
  // random
      var tempSequence = new Array();
      for(var i = 0; i < this.questionsArray.length; i++)
        tempSequence.push(i);
      if(this.questionsToDisplay > 0){
        this.questionSequence =
          scene.Utils.permutateArray(tempSequence, this.questionsToDisplay);
      } else {
        this.questionSequence =
          scene.Utils.permutateArray(tempSequence);
      }
    } else {
      if(this.questionsToDisplay > 0)
        for(var i = 0; i < this.questionsArray.length
          && i < this.questionsToDisplay; i++)
          this.questionSequence.push(i);
      else
        for(var i = 0; i < this.questionsArray.length; i++)
          this.questionSequence.push(i);
    }

    if(this.allowSelection){
      if(this.btnPreviousQuestion && this.questionSequence.length > 1){
        this.btnPreviousQuestion.showObject();
      }
      if(this.btnNextQuestion && this.questionSequence.length > 1){
        this.btnNextQuestion.showObject();
      }
    }

    if ( this.autoSkip && this.autoSkipDirection == QUESTION_AUTOSKIP_RANDOM){
      var notAnsweredQuestions = new Array();
      for(var i = 0; i < this.questionSequence.length; i++){
        if(this.questionsArray[this.questionSequence[i]].questionState == QUESTION_STATE_NOTANSWERED){
          notAnsweredQuestions.push(i);
        }
      }
      if(notAnsweredQuestions.length > 0){
        var questionIndex = Math.round(Math.random()*notAnsweredQuestions.length - 0.5);
        this.showQuestion(notAnsweredQuestions[questionIndex]);
      }
    } else {
      this.showQuestion(0);
    }
    
    rnmc_stdMediaGroup_showObject();
  }

  function hideObject(){
    for(var i = 0; i < this.questionsArray.length; i++)
      this.questionsArray[i].hideObject();

    rnmc_stdMediaGroup_hideObject();
  }

// отображение счетчика вопросов
  function updateCounter(){ 
    if(this.counterVisible && this.counterObject){
      if(this.counterFormat){
        var str = this.counterFormat.slice(0);
        str = str.replace(/%total%/g, this.questionSequence.length);
        str = str.replace(/%elapsed%/g, this.questionsAnswered); //this.currentQuestionIndex + 1);
        str = str.replace(/%number%/g, this.currentQuestionIndex + 1);
        str = str.replace(/%remaining%/g, (this.questionSequence.length - this.questionsAnswered));
        this.counterObject.value = str;
      } else {
        this.counterObject.visible = false;
      }
    }
  }

// отображение вопроса по индексу
  function showQuestion(questionIndex){
    if(questionIndex >= 0 && questionIndex < this.questionSequence.length){
    
      if (this.currentQuestionIndex != questionIndex)
      {
        if(this.currentQuestionIndex >= 0){
        //  выполнение при скрытии воспроса
          if(this.onHideQuestion){
            for(var i = 0; i < this.onHideQuestion.length; ++i)
              this.dispatchAction(this.onHideQuestion[i]);
          }

          this.questionsArray[this.questionSequence[this.currentQuestionIndex]].hideObject();
        }
        this.currentQuestionIndex = questionIndex;
      }

    //===========================================================
      if(!this.selectionCycling){
      //  если нет зацикливания набора вопросов
      //    - то управляем кнопками вперёд/назад здесь
        var questionsBeforeCurrent = 0;
        var questionsAfterCurrent = 0;
        if(!this.allowMultipleAttempts && this.excludeStyle == QUESTION_EXCLUDE){
          for(var i = 0; i < this.questionSequence.length; i++){
            if(this.questionsArray[this.questionSequence[i]].questionState == QUESTION_STATE_NOTANSWERED){
              if(i < this.currentQuestionIndex){
                questionsBeforeCurrent++;
              } else if(i > this.currentQuestionIndex){
                questionsAfterCurrent++;
              }
            }
          }
        } else {
          for(var i = 0; i < this.questionSequence.length; i++){
            if(i < this.currentQuestionIndex){
              questionsBeforeCurrent++;
            } else if(i > this.currentQuestionIndex){
              questionsAfterCurrent++;
            }
          }
        }
        if(questionsBeforeCurrent == 0){
          if(this.btnPreviousQuestion){
            this.btnPreviousQuestion.hideObject();
          }
        } else {
          if(this.btnPreviousQuestion){
            this.btnPreviousQuestion.showObject();
          }
        }
        if(questionsAfterCurrent == 0){
          if(this.btnNextQuestion){
            this.btnNextQuestion.hideObject();
          }  
        } else {
          if(this.btnNextQuestion){
            this.btnNextQuestion.showObject();
          }
        }
      }
    //===========================================================

      this.updateCounter();
      if(this.checkMode == QUESTION_CHECK_AFTER){
        if(this.questionsArray[this.questionSequence[this.currentQuestionIndex]].allowMultipleAttempts
          || this.questionsArray[this.questionSequence[this.currentQuestionIndex]].questionState == QUESTION_STATE_NOTANSWERED){
          if(this.btnCheckAnswers)
            this.btnCheckAnswers.showObject();
          if(this.btnResetAnswers )
            this.btnResetAnswers.showObject();
        } else {
          if(this.btnCheckAnswers)
            this.btnCheckAnswers.hideObject();
          if(this.btnResetAnswers )
            this.btnResetAnswers.hideObject();
        }
      }
      this.questionsArray[this.questionSequence[this.currentQuestionIndex]].showObject();
    //  выполнение при скрытии воспроса
      if(this.onShowQuestion){
        for(var i = 0; i < this.onShowQuestion.length; ++i)
          this.dispatchAction(this.onShowQuestion[i]);
      }
    }
  }

  function previousQuestion(){
  //  сначала очищаем autoskip timeout, а то если человек уже
  //  перешёл к другому вопросу (если есть возмжность выбора) - будет кисло
    try{
      this.clearTimeout(this.autoSkipTimer);
    }
    catch(ex){
      trace("#FF0000Error: " + ex);
    }
    var i = this.currentQuestionIndex;
    while(true){
      if(i == 0){
        i = this.questionSequence.length - 1;
      } else {
        i--;
      };
      if(i == this.currentQuestionIndex){
        break;
      } else {
        if(this.allowMultipleAttempts){
        //  можно отвечать на один и тот же вопрос несколько раз
          this.showQuestion(i);
          break;
        } else {
          if(this.questionsArray[this.questionSequence[i]].questionState == QUESTION_STATE_ANSWERED){
            if(this.excludeStyle == QUESTION_DISABLE){
              this.showQuestion(i);
              break;
            }
          } else {
            this.showQuestion(i);
            break;
          }
        }
      }
    }
  }

  function nextQuestion(){
  //  сначала очищаем autoskip timeout, а то если человек уже
  //  перешёл к другому вопросу (если есть возмжность выбора) - будет ошибка
    try{
      this.clearTimeout(this.autoSkipTimer);
    }
    catch(ex){
      trace("#FF0000Error: " + ex);
    }
    var i = this.currentQuestionIndex;
    while(true){
      if(i == this.questionSequence.length - 1){
        i = 0;
      } else {
        i++;
      };
      if(i == this.currentQuestionIndex){
        break;
      } else {
        if(this.allowMultipleAttempts){
        //  можно отвечать на один и тот же вопрос несколько раз
          this.showQuestion(i);
          break;
        } else {
          if(this.questionsArray[this.questionSequence[i]].questionState == QUESTION_STATE_ANSWERED){
            if(this.excludeStyle == QUESTION_DISABLE){
              this.showQuestion(i);
              break;
            }
          } else {
            this.showQuestion(i);
            break;
          }
        }
      }
    }
  }

//  обновляет текущее состояние статистики - шоб 
//  даже если прервали - то посчиталось
  function updateStepResult(){
    var totalQuestions = 0;
    var totalPercents = 0;
    for(var i = 0; i < this.questionSequence.length; i++){
      if(this.questionsArray[this.questionSequence[i]].questionState == QUESTION_STATE_ANSWERED){
        totalPercents += this.questionsArray[this.questionSequence[i]].currentResult;
        totalQuestions++;
      } else {
        totalQuestions++;
      }
    }
    this.objectResult = Math.round(totalPercents/totalQuestions);
  }

  function notifyQuestionAnswered(newResultStr, annotationText){
    var notAnsweredQuestions = 0;
    var newResult = newResultStr.objectResult;
    this.updateStepResult();
    if(!this.allowMultipleAttempts){
      if(this.btnCheckAnswers){
        this.btnCheckAnswers.hideObject();
      }
      if(this.btnResetAnswers){
        this.btnResetAnswers.hideObject();
      }
    }
    scene.Labwork.addNewResult(newResult, annotationText);
    for(var i = 0; i < this.questionSequence.length; i++){
      if(this.questionsArray[this.questionSequence[i]].questionState == QUESTION_STATE_NOTANSWERED){
        notAnsweredQuestions++;
      }
    }

  // Подсчитать количество заданий (вопросов) на которые пользователь не ответил
    this.questionsAnswered = this.questionSequence.length - notAnsweredQuestions;

  // Обновить счетчики
    updateCounter();
    
  //  выводим сообщение
    if(newResultStr.message && this.onSelectAllElements){
      for(var i = 0; i < this.onSelectAllElements.length; i++){
        this.dispatchAction(this.onSelectAllElements[i]);
      }
    }
  //  выполнение общие действия при правильном ответе
    if(newResult == 100 && this.answeredRightActions){
      for(var i = 0; i < this.answeredRightActions.length; i++){
        this.dispatchAction(this.answeredRightActions[i]);
      }
    }
  //  выполнение общие действия при не правильном ответе
    if(newResult < 100 && this.answeredWrongActions){
      for(var i = 0; i < this.answeredWrongActions.length; i++){
        this.dispatchAction(this.answeredWrongActions[i]);
      }
    }

  //  если ответили на все вопросы - выполняем необходимые действия
    if(notAnsweredQuestions == 0){
      if(this.autoSkip){
        this.autoSkipTimer = this.setTimeout("this.onAnsweredQuestionsTimeout()", this.autoSkipTimeout);
      }
      else {
        if(this.onAllQuestionsAnsweredActions){
          for(var i = 0; i < this.onAllQuestionsAnsweredActions.length; i++){
            this.dispatchAction(this.onAllQuestionsAnsweredActions[i]);
          }
        }
      }
    } else {
      if(this.autoSkip){
        if(notAnsweredQuestions == 1 && this.selectionCycling){
          if(this.btnPreviousQuestion){
            this.btnPreviousQuestion.hideObject();
          }
          if(this.btnNextQuestion){
            this.btnNextQuestion.hideObject();
          }
        }
      //  если необходимо автоматиечски перейти к следующему вопросу
        this.autoSkipTimer = this.setTimeout("this.onAutoSkipTimeout()", this.autoSkipTimeout);
      }
    }
  }

//  обработчик таймера завершения ответа на все вопросы, если включен автоперехода к другому вопросу  
  function onAnsweredQuestionsTimeout() {
    if(!this.autoSkip)
      return;

    if(this.onAllQuestionsAnsweredActions){
      for(var i = 0; i < this.onAllQuestionsAnsweredActions.length; i++){
        this.dispatchAction(this.onAllQuestionsAnsweredActions[i]);
      }
    }
  }

//  обработчик таймера втоперехода к другому вопросу
  function onAutoSkipTimeout(){
    if(!this.autoSkip)
      return;

    switch(this.autoSkipDirection){
    case QUESTION_AUTOSKIP_FORWARD:  
      this.nextQuestion();
      break;
    case QUESTION_AUTOSKIP_BACK:
      this.previousQuestion();
      break;
    case QUESTION_AUTOSKIP_RANDOM:
      var notAnsweredQuestions = new Array();
      for(var i = 0; i < this.questionSequence.length; i++){
        if(this.questionsArray[this.questionSequence[i]].questionState == QUESTION_STATE_NOTANSWERED){
          notAnsweredQuestions.push(i);
        }
      }
      if(notAnsweredQuestions.length > 0){
        var questionIndex = Math.round(Math.random()*notAnsweredQuestions.length - 0.5);
        this.showQuestion(notAnsweredQuestions[questionIndex]);
      }
      break;
    }
  }

  function buttonDispatcher(btnId){
      switch(btnId){
    case "btnPreviousQuestion":
      if(this.allowSelection)
        this.previousQuestion();
      break;
    case "btnNextQuestion":
      if(this.allowSelection)
        this.nextQuestion();
      break;
    case "btnCheck":
    //  проверка ответов
      this.questionsArray[this.questionSequence[this.currentQuestionIndex]].checkAnswers();
      break;
    case "btnReset":
    //  сброс ответов
      var theAnswer = this.questionsArray[this.questionSequence[this.currentQuestionIndex]];
      if (theAnswer.questionState != QUESTION_STATE_NOTANSWERED){
        theAnswer.resetAnswers();
        this.showQuestion(this.currentQuestionIndex);
      } else
        theAnswer.resetAnswers();
      break;
      }
  }

  function getResult(resultsArray){
    if(resultsArray && this.crAlgorithm != "none"){
      var resultString = this.objectResult + ";1.0";
      resultsArray.push(resultString);
    }

    rnmc_stdMediaGroup_getResult(resultsArray);
  }

  function dispatchAction(singleAction){
//  trace("901"+singleAction)
    for (var i = 0; i < singleAction.length; ++i)
      singleAction[i] = scene.Utils.trim(singleAction[i]);

    if (singleAction[0] == "hideAnswers"){	
        this.questionsArray[this.questionSequence[this.currentQuestionIndex]].hideAnswers();
    } else if (singleAction[0] == "hideQuestion"){
      this.questionsArray[this.questionSequence[
        this.currentQuestionIndex]].hideObject();
    } else
      rnmc_stdMediaGroup_dispatchAction(singleAction);
  }
  
  function doAction(singleAction){
    if (singleAction[1] != null){
      if (singleAction[1].substr(0, 6) != "eHint:"){
        var index = singleAction[1].indexOf(".");
        if (index != -1){
          var childId = singleAction[1].slice(0, index);
          if (childId == "[question]"){
            singleAction = singleAction.slice(0);
            singleAction[1] = singleAction[1].slice(index+1);
            if (this.questionsArray && this.questionSequence
              && this.questionsArray[this.questionSequence])
            this.questionsArray[this.questionSequence[this.currentQuestionIndex]].doAction(singleAction);
            return;
          }
        }
      }
    }
    
    switch(singleAction[0]){
    case "resetObject":
      if (singleAction[1] == null){
        this.resetObject();
        return;
      }
      break;
    }

    rnmc_stdMediaGroup_doAction(singleAction);
  }
  
  function resetObject() {
    var theAnswer = this.questionsArray[this.questionSequence[this.currentQuestionIndex]];
    theAnswer.resetAnswers();
    rnmc_stdMediaObject_resetObject();
  }
]]></script>
</composition>

<composition name="question_singleQuestion" class="rnmc_stdMediaGroup">
<script><![CDATA[
//  состояние
  this.questionState = QUESTION_STATE_NOTANSWERED;
  this.questionDisabled = false;
//  текущий результат для данного конкретного вопроса
  this.currentResult = 0;
  this.currentErrors = 0;

//  вывод ответов в произвольном порядке или в том котором в файле
  this.answersRandom = false;
//  режим 'отключения' вопроса. QUESTION_EXCLUDE - исключает вопрос из набора вопросов
//  QUESTION_DISABLED - вопрос после отвечания доступен только для просмотра
  this.excludeStyle = QUESTION_EXCLUDE;
//  возможность повторного ответа на данный вопрос
//  если true - можно отвечать до посинения, при этом результатом
//  для данного вопроса считается последний результат
  this.allowMultipleAttempts = true;

//  режим проверки ответов - 
  this.checkMode = QUESTION_CHECK_AFTER;

//  ограничение на максимальное количесвто ответов для одного вопроса на экране
  this.maxAnswersAllowed = -1;
//  если установлен -то в вопросе можно выбрать только один ответ (галочка будет перескакивать)
  this.answersOnlyOneSelected = false;

//  координаты и стиль вывода ответов
  this.answersStartX = -1;
  this.answersStartY = -1;
  this.answerAlign = "QUESTION_ANSWERALIGN_DOWN";

//  настройки чекбокса
  this.checkBoxNormalBorder   = null;
  this.checkBoxNormalMark     = null;
  this.checkBoxDisabledBorder = null;
  this.checkBoxDisabledMark   = null;
  
  this.errorCheckBoxSrc = null;

//  массив ответов
  this.answersArray = null;
//  последовательность вывода ответов на экран
  this.answersSequence = null;
  this.rightAnswers = 0;
  this.wrongAnswers = 0;

//координаты ответов
  this.startAnswerX = 50;
  this.startAnswerY = 100;

//  переменные для сохранения состояния ответов (если нужна
//  блокировка повторного ответа например)
//  последовательновательность ответов на экране
  this.lastAnswersSequence = null;
//  последовательность галочек (отмечено - 1, неотмечено - 0)
  this.lastCheckedSequence = null;

//  =================================================================
//  действия, специфичные для отдельного вопроса
//  действия - если отвечен верно
  this.answeredRightActions = null;
//  действия - если отвечен неверно
  this.answeredWrongActions = null;
//  действия - если результат ответа ниже порогового значения 
  this.answeredBelowResultActions = null;
//  действия - если результат ответа выше порогового значения 
  this.answeredAboveResultActions = null;
//  действия - если результат ответа находицца между двумя значенимя в формате "нижн;верхн"
  this.answeredBetweenResultsActions = null;

  this.attemptsCount = 0;

  function initFromNode(srcNode){
    var xmlNode = null;
    var xmlAttributeMap = null;
    var xmlAttribute = null;

    this.childObjects = new Array();
    this.answersArray = new Array();
    this.loadChildsObject(srcNode);

    xmlAttributeMap = srcNode.attributes;
    if (xmlAttributeMap){
      xmlAttribute = xmlAttributeMap.getNamedItem("id");
      if (xmlAttribute != null && xmlAttribute.specified)
        this.id = xmlAttribute.value;
    }

    xmlNode = srcNode.firstChild;
    while(xmlNode){
      if(xmlNode.nodeName == "param"){
        xmlAttributeMap = xmlNode.attributes;
        if (xmlAttributeMap){
          xmlAttribute =  xmlAttributeMap.getNamedItem("x");
          if (xmlAttribute != null && xmlAttribute.specified)
            this.x = parseInt(xmlAttribute.value);
          xmlAttribute =  xmlAttributeMap.getNamedItem("y");
          if (xmlAttribute != null && xmlAttribute.specified)
            this.y = parseInt(xmlAttribute.value);

          xmlAttribute = xmlAttributeMap.getNamedItem("answersRandom");
          if (xmlAttribute != null && xmlAttribute.specified){
            if(xmlAttribute.value == "true"){
              //  настройка перемешивания ответов для данного вопроса
              this.answersRandom = true;    //  перемешиваем
            } else {
              this.answersRandom = false;    //  не перемешиваем
            }
          }
          xmlAttribute =  xmlAttributeMap.getNamedItem("answersLayout");
          if (xmlAttribute != null && xmlAttribute.specified){
            if(xmlAttribute.value == "LAYOUT_NO"){
            //  означает что ответы на экране будут расставлены не в столбцы или строчки,
            //  а по указанным коодинатам
              this.answersLayout = LAYOUT_NO;
            } else if(xmlAttribute.value == "LAYOUT_VERTICAL"){
            //  означает что ответы на экране будут выстроены вертикально
              this.answersLayout = LAYOUT_VERTICAL;
            } else if(xmlAttribute.value == "LAYOUT_HORIZONTAL"){
            //  означает что ответы на экране будут выстроены горизонтально
              this.answersLayout = LAYOUT_HORIZONTAL;
            }
          };
          xmlAttribute = xmlAttributeMap.getNamedItem("allowMultiple");
          if (xmlAttribute != null && xmlAttribute.specified){
            if(xmlAttribute.value == "true"){
              this.allowMultipleAttempts = true;
            } else {
              this.allowMultipleAttempts = false;
            }
          }          
          xmlAttribute = xmlAttributeMap.getNamedItem("maxAllowed");
          if (xmlAttribute != null && xmlAttribute.specified){
            this.maxAnswersAllowed = parseInt(xmlAttribute.value);
          }
          xmlAttribute = xmlAttributeMap.getNamedItem("onlyOneSelected");
          if (xmlAttribute != null && xmlAttribute.specified){
            if((xmlAttribute.value).toLowerCase() == "true"){
              this.answersOnlyOneSelected = true;
            } else if((xmlAttribute.value).toLowerCase() == "auto"){
              this.answersOnlyOneSelected = "auto";
            } else {
              this.answersOnlyOneSelected = false;
            }
          }
          xmlAttribute = xmlAttributeMap.getNamedItem("answersX");
          if (xmlAttribute != null && xmlAttribute.specified){
            this.answersX = parseInt(xmlAttribute.value);
          }
          xmlAttribute = xmlAttributeMap.getNamedItem("answersY");
          if (xmlAttribute != null && xmlAttribute.specified){
            this.answersY = parseInt(xmlAttribute.value);
          }
          xmlAttribute =  xmlAttributeMap.getNamedItem("checkMode");
          if (xmlAttribute != null && xmlAttribute.specified){
            if(xmlAttribute.value == "CHECK_AFTER"){
            //  означает что проверятся ответы будт после нажатия кнопки проверить
              this.checkMode = QUESTION_CHECK_AFTER;
            } else if(xmlAttribute.value == "CHECK_IMMEDIATELY"){
            //  означает что проверятся ответы будт после первого нажатия
              this.checkMode = QUESTION_CHECK_IMMEDIATELY;
            }
          };
        }
      } else if(xmlNode.nodeName == "answer"){
      //  инициализация объекта "ответ"
        var newObject = new Composition();
        newObject._class = "question_singleAnswer";
        newObject.parent = this;
        newObject.visible = true;
        if(newObject.initFromNode(xmlNode)){
        //  создаётся чекбокс, который стандартными аттач-методами
        //  крепится к объекту
          var checkBox = new Composition();
          checkBox._class = "rnmc_stdCheckBox";
          checkBox.parent = this;
          checkBox.visible = false;
        //  установка св-в чекбокса, необходимых для отображения
          checkBox.id                = "chkBox_" + newObject.id;
          checkBox.boxSrcNormal      = this.checkBoxNormalBorder;
          checkBox.markSrcNormal     = this.checkBoxNormalMark;
          checkBox.boxSrcDisabled    = this.checkBoxDisabledBorder;
          checkBox.markSrcDisabled   = this.checkBoxDisabledMark;
          checkBox.autoAttachTarget  = newObject.id;
          checkBox.visibility        = OBJECT_VISIBILITY_TRUE;
          checkBox.autoAttachStyle   = AUTOATTACH_LEFT_CENTER;
          checkBox.autoAttachOffsetX = 30;
          checkBox.autoAttachOffsetY = 0;
          checkBox.setPressCallBack(newObject, newObject.onAnswerChanged);
          newObject.checkBox = checkBox;
        //  
          this.answersTotal++;
          if(newObject.rightAnswer){
            this.rightAnswers++;
          } else {
            this.wrongAnswers++;
          }
          if(this.maxAnswersAllowed > 0 && this.rightAnswers > this.maxAnswersAllowed){
            trace("#FF0000Ошибка: число правильных ответов больше чем всего разрешено.");
          }

          // Toha: Добавил возможность отображение ошибки в выборе ответа
          // за место checkBox
          newObject.errorCheckBoxSrc = this.errorCheckBoxSrc;
          newObject.noSelectCheckBoxSrc = this.noSelectCheckBoxSrc;  //f
          
          this.answersArray.push(newObject);
          this.childObjects.push(newObject);
          this.childObjects.push(checkBox);
        } else {
          newObject.parent = null;
          newObject = null;
        }
      } else if(xmlNode.nodeName == "actions"){
        this.parseActionsNode(xmlNode);

      //  действия - если отвечен верно
        this.answeredRightActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredRight");

      //  действия - если отвечен неверно
        this.answeredWrongActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredWrong");

      //  действия - если результат ответа ниже порогового значения 
        this.answeredBelowResultActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredBelowResult");

      //  действия - если результат ответа выше порогового значения 
        this.answeredAboveResultActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredAboveResult");

      //  действия - если результат ответа находицца между
      //    двумя значенимя в формате "нижн;верхн"
        this.answeredBetweenResultsActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredBetweenResult");
      }
      xmlNode = xmlNode.nextSibling;
    }
    
    if (this.answersOnlyOneSelected = "auto" ) {
      this.answersOnlyOneSelected = this.rightAnswers > 1 ? false : true;
    }
    // если удачно  инициализированно
    return true;
  }

  function showObject(){
 
    if(this.allowMultipleAttempts
      || this.questionState == QUESTION_STATE_NOTANSWERED){
    //  если на этот вопрос можно отвечать повторно	или он не отвечен
      if(this.answersRandom){
	  
        if(this.maxAnswersAllowed > 0){
        //  значит есть ограничение на количество ответов
          var answersSelected = 0;
          var tempSequence = new Array();

          for(var i = 0; i < this.answersArray.length; i++)
            tempSequence.push(i);
          var permutatedSequence = scene.Utils.permutateArray(tempSequence);  

          tempSequence = new Array();
          for(var i = 0; i < permutatedSequence.length; i++){
            if(this.answersArray[permutatedSequence[i]].rightAnswer){
              tempSequence.push(permutatedSequence[i]);
              answersSelected++;
            }
          }

          for(var i = 0; i < permutatedSequence.length && answersSelected < this.maxAnswersAllowed; i++){
            if(!this.answersArray[permutatedSequence[i]].rightAnswer){
              answersSelected++;
              tempSequence.push(permutatedSequence[i]);
            }
          }

          this.answersSequence = scene.Utils.permutateArray(tempSequence, tempSequence.length);
        } else {
        //  нет ограничений на количество ответов
          var tempSequence = new Array();
          for(var i = 0; i < this.answersArray.length; i++)
            tempSequence.push(i);
          this.answersSequence = scene.Utils.permutateArray(tempSequence, tempSequence.length);
        }
      } else {          //  если не надо перемешивать ответы
        if(this.maxAnswersAllowed > 0){
          var answersSelected = 0;
          this.answersSequence = new Array();

          for(var i = 0; i < this.answersArray.length; i++){
            if(this.answersArray[i].rightAnswer){
              this.answersSequence.push(i);
              answersSelected++;
            }
          }

          for(var i = 0; i < this.answersArray.length
            && answersSelected < this.maxAnswersAllowed; i++){
            if(!this.answersArray[i].rightAnswer){
              answersSelected++;
              this.answersSequence.push(i);
            }
          }
        } else {
        //  нет ограничений на количество ответов
          this.answersSequence = new Array();
          for(var i = 0; i < this.answersArray.length; i++){
            this.answersSequence.push(i);
          }
        }
      }

      var currentAnswerX = this.answersX;
      var currentAnswerY = this.answersY;

      for(var i = 0; i < this.answersSequence.length; i++){
        this.answersArray[this.answersSequence[i]].answerChecked = false;
        switch(this.answersLayout){
        case LAYOUT_NO:
//trace("1290--"+this.answersArray[this.answersSequence[i]].id+"  x="+this.answersArray[this.answersSequence[i]].x+"  y="+this.answersArray[this.answersSequence[i]].y);
          this.answersArray[this.answersSequence[i]].showObject();
		break;  
        case LAYOUT_VERTICAL:
          this.answersArray[this.answersSequence[i]].x = currentAnswerX;
          this.answersArray[this.answersSequence[i]].y = currentAnswerY;
          this.answersArray[this.answersSequence[i]].showObject();
          currentAnswerY += this.answersArray[this.answersSequence[i]].height;
          currentAnswerY += 20;                              // !!!!!!!!!!!!!!!
          break;
        case LAYOUT_HORIZONTAL:
          this.answersArray[this.answersSequence[i]].x = currentAnswerX;
          this.answersArray[this.answersSequence[i]].y = currentAnswerY;
          this.answersArray[this.answersSequence[i]].showObject();
          currentAnswerX += this.answersArray[this.answersSequence[i]].width;
          currentAnswerX += 20;                              // !!!!!!!!!!!!!!!
          break;
        }

        for(var j = 0; j < this.childObjects.length; j++){
          if(this.childObjects[j].type == "rnmc_stdCheckBox"){
            if(this.childObjects[j].autoAttachTarget == this.answersArray[this.answersSequence[i]].id){
              this.childObjects[j].uncheckObject();
            }
          }
        }
      }
    } else if(this.questionState == QUESTION_STATE_ANSWERED
        && this.excludeStyle == QUESTION_DISABLE){
		
      //  если на этот вопрос нельзя отвечать повторно и он уже отвечался
      //  восстанавливаем состояние этого вопроса которое было во время последнего ответа
      if(this.lastAnswersSequence){
        var currentAnswerX = this.answersX;
        var currentAnswerY = this.answersY;

        for(var i = 0; i < this.lastAnswersSequence.length; i++){
          switch(this.answersLayout){
          case LAYOUT_NO:
            this.answersArray[this.lastAnswersSequence[i]].showObject();
			 break;
          case LAYOUT_VERTICAL:
            this.answersArray[this.lastAnswersSequence[i]].x = currentAnswerX;
            this.answersArray[this.lastAnswersSequence[i]].y = currentAnswerY;
            this.answersArray[this.lastAnswersSequence[i]].showObject();
            currentAnswerY += this.answersArray[this.lastAnswersSequence[i]].height;
            currentAnswerY += 20;                            // !!!!!!!!!!!!!!!
            break;
          case LAYOUT_HORIZONTAL:
            this.answersArray[this.lastAnswersSequence[i]].x = currentAnswerX;
            this.answersArray[this.lastAnswersSequence[i]].y = currentAnswerY;
            this.answersArray[this.lastAnswersSequence[i]].showObject();
            currentAnswerX += this.answersArray[this.lastAnswersSequence[i]].width;
            currentAnswerX += 20;                            // !!!!!!!!!!!!!!!
            break;
          }
          for(var j = 0; j < this.childObjects.length; j++){
            if(this.childObjects[j].type == "rnmc_stdCheckBox"){
              if(this.childObjects[j].autoAttachTarget == this.answersArray[this.lastAnswersSequence[i]].id){
                if(this.lastCheckedSequence[i] == 1){
                  this.childObjects[j].checkObject();
                } else {
                  this.childObjects[j].uncheckObject();
                }
                this.childObjects[j].disableObject();
              }
            }
          }
        }
      }
    }

  //  корректное управление видимостью чекбоксов (потому как сами они не
  //  в состоянии понять, нжно показывацца или нет)
    for(var i = 0; i < this.answersArray.length; i++){
      if(this.answersSequence.indexOf(i) >= 0){
        //  значит этот вопрос показываем
	
        for(var j = 0; j < this.childObjects.length; j++){
          if(this.childObjects[j].type == "rnmc_stdCheckBox" &&
            this.childObjects[j].autoAttachTarget &&
            this.answersArray[i].id == this.childObjects[j].autoAttachTarget){
            this.childObjects[j].showObject();
		
          }
        }
      } else {
        for(var j = 0; j < this.childObjects.length; j++){
          if(this.childObjects[j].type == "rnmc_stdCheckBox" &&
            this.childObjects[j].autoAttachTarget &&
            this.answersArray[i].id == this.childObjects[j].autoAttachTarget){
            this.childObjects[j].hideObject(); 
          }
        }
      }
    }

  //  отображаем содержимое вопроса после отображения ответов 
  //  для того чтобы работал автоаттач чекбоксов (пока без обновления расположения)
    for(var i = 0; i < this.childObjects.length; i++){
      if(this.childObjects[i].type != "answer"
        && this.childObjects[i].type != "rnmc_stdCheckBox"){	
        if(this.childObjects[i].visibility == OBJECT_VISIBILITY_TRUE){
          this.childObjects[i].showObject();
        } 
      }
    }
	
    rnmc_stdMediaGroup_showObject();
  }

//  прячем вопрос
  function hideObject(){
    rnmc_stdMediaGroup_hideObject();
  }

  function checkAnswers(){
    //Увеличим счетчик попыток
    this.attemptsCount++;
//trace("1384--"+this.attemptsCount);   
    if(!this.allowMultipleAttempts || parent.autoSkip){
      for(var i = 0; i <  this.childObjects.length; i++){
        if(this.childObjects[i].type == "rnmc_stdCheckBox"){
          this.childObjects[i].disableObject();
        }
      }
    }
    
    for(var i = 0; i < this.answersSequence.length; i++){
      // Запомним на всякий случай, какие были обработчики,
      // т.к. могут сбросить ответы и начать отвечать заново
      this.answersArray[this.answersSequence[i]].onPress_prev_value = 
        this.answersArray[this.answersSequence[i]].onPress;
      this.answersArray[this.answersSequence[i]].onPress = null;
    }
    
    this.questionState = QUESTION_STATE_ANSWERED;
    
    var results;
    results = new scene.Utils.resultParam();
    results.init();
    
    var totalAnswers = 0;
    
    for(var i = 0; i < this.answersSequence.length; i++){
      totalAnswers++;

      if(this.answersArray[this.answersSequence[i]].rightAnswer){  //  правильный ответ
        if(this.answersArray[this.answersSequence[i]].answerChecked){
          results.rightElements++;
        } else {
        //  не отмечен правильный ответ - увеличиваем колво ошибок
          this.currentErrors++;
          results.wrongElements++;
		  if(this.answersArray[this.answersSequence[i]].visible==true)  //для того, чтобы не высвечивать, если саму строку не видно 
              this.answersArray[this.answersSequence[i]].setCheckBoxError();
    
        }
        
        results.allRightElements++;
      } else {                          //  неправильный ответ
        if(this.answersArray[this.answersSequence[i]].answerChecked){
          this.currentErrors++;
          results.wrongElements++;
          if(this.answersArray[this.answersSequence[i]].visible==true)  //для того, чтобы не высвечивать, если саму строку не видно
              this.answersArray[this.answersSequence[i]].setCheckBoxError();
        }
      }
    }
    
    this.objectErrors = results.wrongElements;
    
    if(this.checkMode == QUESTION_CHECK_IMMEDIATELY)
      results.attemptsCount = results.wrongElements;
    else
      results.attemptsCount = this.attemptsCount;
    
    results.allWrongElements = totalAnswers - results.allRightElements;
    results.allElements = results.allRightElements + results.allWrongElements;
    results.isTimeout = this.isOnTimeout;

    results.countResult(this.crAlgorithm);
    
    this.currentResult = results.objectResult;

    parent.notifyQuestionAnswered(results);
    if(!this.allowMultipleAttempts && this.excludeStyle == QUESTION_DISABLE){
    //  если нельзя отвечать повторно
      this.questionDisabled = true;
    //  сохраняем порядок отображения ответов
      this.lastAnswersSequence = this.answersSequence.slice(0);
    //  сохраняем расставленые галочки (в той последовательности,
    //  как выводились на экран - this.answersSequence)
    //  0 - галочки не стояло
    //  1 - галочка стояла
      if(this.lastCheckedSequence)
        this.lastCheckedSequence = null;
      this.lastCheckedSequence = new Array();
      
      for(var i = 0; i < this.answersSequence.length; i++){
        if(this.answersArray[this.answersSequence[i]].answerChecked){
          this.lastCheckedSequence.push(1);
        } else {
          this.lastCheckedSequence.push(0);
        }
      }
    }
    //  выполнение действий при ответе с некоторым результатом
//trace("1490--this.currentResult="+this.currentResult);	
    if(this.currentResult == 100 && this.answeredRightActions){
      for(var i = 0; i < this.answeredRightActions.length; i++){
        parent.dispatchAction(this.answeredRightActions[i]);
      }
    }
    if(this.currentResult == 0 && this.answeredWrongActions){
      for(var i = 0; i < this.answeredWrongActions.length; i++){
        parent.dispatchAction(this.answeredWrongActions[i]);
        //trace("#FF0000scene.Labwork.currentStep.dispatchAction(this.answeredWrongActions[i]);");
        //scene.Labwork.currentStep.dispatchAction(this.answeredWrongActions[i]);
      }
    }
    if(this.answeredBelowResultActions){
      for(var i = 0; i < this.answeredBelowResultActions.length; i++){
        if(parseInt(this.answeredBelowResultActions[i].eventParam) > this.currentResult)
          scene.Labwork.currentStep.dispatchAction(this.answeredBelowResultActions[i]);
      }
    }
    if(this.answeredAboveResultActions){
      for(var i = 0; i < this.answeredAboveResultActions.length; i++){
        if(parseInt(this.answeredBelowResultActions[i].eventParam) < this.currentResult)
          scene.Labwork.currentStep.dispatchAction(this.answeredAboveResultActions[i]);
      }
    }
    if(this.answeredAboveResultActions){
      for(var i = 0; i < this.answeredBetweenResultsActions.length; i++){
        var resultBounds = (this.answeredBetweenResultsActions[i].eventParam).split(";");
        if(resultBounds.length == 2){
          if(parseInt(resultBounds[0]) < this.currentResult
            && parseInt(resultBounds[1]) > this.currentResult)
            scene.Labwork.currentStep.dispatchAction(this.answeredBetweenResultsActions[i]);
        }
      }
    }
  }

  function resetAnswers(){
//    if(this.allowMultipleAttempts
//      || (!this.allowMultipleAttempts && this.questionState == QUESTION_STATE_NOTANSWERED)){
      for(var i = 0; i <  this.childObjects.length; i++){
        if(this.childObjects[i].type == "rnmc_stdCheckBox"){
          this.childObjects[i].enableObject();
          this.childObjects[i].uncheckObject();
          this.childObjects[i].showObject();
        } else if(this.childObjects[i].type == "answer"){
          this.childObjects[i].resetAnswer();
        }
      }
      this.questionState = QUESTION_STATE_NOTANSWERED;
//    }

    for(var i = 0; i < this.answersSequence.length; i++){
      // Восстановим значение
      this.answersArray[this.answersSequence[i]].onPress = 
        this.answersArray[this.answersSequence[i]].onPress_prev_value;
    }
  }

  function hideAnswers(){
    for(var i = 0; i < this.answersArray.length; i++){
      this.answersArray[i].hideObject();
    }
  }

  function notifyAnswerChanged(answerId, newState){

    if(this.answersOnlyOneSelected){   //если можно выбрать только 1 ответ и галка пескакивает
      for(var i = 0; i <  this.childObjects.length; i++){
        if(this.childObjects[i].type == "rnmc_stdCheckBox"){
          if(this.childObjects[i].id != ("chkBox_" + answerId)){
            this.childObjects[i].uncheckObject();
          } else {
            this.childObjects[i].checkObject();
          }
        } else if(this.childObjects[i].type == "answer"){
          if(this.childObjects[i].id != answerId){
            this.childObjects[i].answerChecked = false;
          }
        }
      }
    }
	var v_rightElements = 0;
	for(var i = 0; i < this.answersSequence.length; i++){
    
      if(this.answersArray[this.answersSequence[i]].rightAnswer){  //  правильный ответ
        if(this.answersArray[this.answersSequence[i]].answerChecked){
             v_rightElements++;
		 }
	  }
	}
	if(this.checkMode == QUESTION_CHECK_IMMEDIATELY){
		if(v_rightElements == this.rightAnswers){
//trace("1548--"+this.rightAnswers+"  "+v_rightElements);
			for(var i = 0; i <  this.childObjects.length; i++){
				if(this.childObjects[i].type == "rnmc_stdCheckBox"){
					this.childObjects[i].disableObject();
				}
			}
		}
      this.checkAnswers();
    }
  }
]]></script>
</composition>

<composition name="question_singleAnswer" class="rnmc_stdMediaGroup">
<script><![CDATA[
  this.type = "answer";
//  правильность ответа
  this.rightAnswer = false;
//  отмечен ли ответ (выбран) 
  this.answerChecked = false;
  
  // пути к файлам с галкой-ошибкой
  this.errorCheckBoxSrc = "";
  
  // сами картинки с галкой-ошибкой
  this.errorCheckBoxImg = null;

  // пути к файлам с воскл знаком
  this.noSelectCheckBoxSrc = "";
  
  // сами картинки с воскл знаком
  this.noSelectCheckBoxImg = null;
  
  //для каждого ответа свой список Actions
  this.answeredRightActions = null;
  this.answeredWrongActions = null;

  function initFromNode(srcNode){
    var xmlNode = null;
    var xmlAttributeMap = null;
    var xmlAttribute = null;

    this.childObjects = new Array();
    this.loadChildsObject(srcNode);

    xmlAttributeMap = srcNode.attributes;
    if (xmlAttributeMap){
      xmlAttribute = xmlAttributeMap.getNamedItem("id");
      if (xmlAttribute != null && xmlAttribute.specified)
        this.id = xmlAttribute.value;
    }

    xmlNode = srcNode.firstChild;
    while(xmlNode){
      if(xmlNode.nodeName == "param"){
        xmlAttributeMap = xmlNode.attributes;
        if (xmlAttributeMap){	
          xmlAttribute = xmlAttributeMap.getNamedItem("right");
          if (xmlAttribute != null && xmlAttribute.specified && xmlAttribute.value == "true"){
            this.rightAnswer = true;
          } else {
            this.rightAnswer = false;
          } 		
          xmlAttribute =  xmlAttributeMap.getNamedItem("x");  //<f
          if (xmlAttribute != null && xmlAttribute.specified && parent.answersLayout == LAYOUT_NO)
            this.x = parseInt(xmlAttribute.value);
          xmlAttribute =  xmlAttributeMap.getNamedItem("y");
          if (xmlAttribute != null && xmlAttribute.specified && parent.answersLayout == LAYOUT_NO)
            this.y = parseInt(xmlAttribute.value);    //f>
		}
      } else if(xmlNode.nodeName == "actions"){
        this.parseActionsNode(xmlNode);

      //  действия - если отвечен верно
        this.answeredRightActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredRight");

      //  действия - если отвечен неверно
        this.answeredWrongActions =
          scene.Utils.parseActionsNode(xmlNode, "onAnsweredWrong");
	  }
      xmlNode = xmlNode.nextSibling;
    }

  // если удачно  инициализированно
    return true;
  }

// показ ответа
  function showObject(){
//trace("1666-this  "+this);
  //  отображаем содержимое вопроса
    if (this.errorCheckBoxSrc != null && 
        this.errorCheckBoxSrc != "" && 
        this.errorCheckBoxImg == null){
      this.errorCheckBoxImg                   = new Composition();
      this.errorCheckBoxImg._class            = "rnmc_stdImage";
      this.errorCheckBoxImg.parent            = this.parent;
      this.errorCheckBoxImg.visible           = false;
      this.errorCheckBoxImg.id                = "error_img_" + this.id;
      this.errorCheckBoxImg.objectSrc         = this.errorCheckBoxSrc;
      this.errorCheckBoxImg.x                 = 0;
      this.errorCheckBoxImg.y                 = 0;
      this.errorCheckBoxImg.objectDepth       = this.depth - 1;
      this.errorCheckBoxImg.autoAttachTarget  = this.id;
      this.errorCheckBoxImg.autoAttachStyle   = AUTOATTACH_LEFT_CENTER;
      this.errorCheckBoxImg.autoAttachOffsetX = 30;
      this.errorCheckBoxImg.autoAttachOffsetY = 0;
      this.errorCheckBoxImg.loadObject();
    }
  
    if (this.noSelectCheckBoxSrc != null && 
        this.noSelectCheckBoxSrc != "" && 
        this.noSelectCheckBoxImg == null){
      this.noSelectCheckBoxImg                   = new Composition();
      this.noSelectCheckBoxImg._class            = "rnmc_stdImage";
      this.noSelectCheckBoxImg.parent            = this.parent;
      this.noSelectCheckBoxImg.visible           = false;
      this.noSelectCheckBoxImg.id                = "noSelect_img_" + this.id;
      this.noSelectCheckBoxImg.objectSrc         = this.noSelectCheckBoxSrc;
      this.noSelectCheckBoxImg.x                 = 0;
      this.noSelectCheckBoxImg.y                 = 0;
      this.noSelectCheckBoxImg.objectDepth       = this.depth - 2;
      this.noSelectCheckBoxImg.autoAttachTarget  = this.id;
      this.noSelectCheckBoxImg.autoAttachStyle   = AUTOATTACH_LEFT_CENTER;
      this.noSelectCheckBoxImg.autoAttachOffsetX = 30;
      this.noSelectCheckBoxImg.autoAttachOffsetY = 0;
      this.noSelectCheckBoxImg.loadObject();
    }
    for(var i = 0; i < this.childObjects.length; i++){	
      this.childObjects[i].showObject();
    }

    this.visible = true;
    this.onPress = onPressHandlerAlias;
	this.onRollOver = onRollOverHandlerAlias;
  }

  function hideObject(){

    for(var i = 0; i < this.childObjects.length; i++){
      this.childObjects[i].hideObject();
    }
	
	 if (this.checkBox)
		this.checkBox.hideObject();
    
    //rnmc_stdMediaGroup_hideObject();
    this.visible = false;
  }

  function unloadObject(srcNode){  
    if (this.checkBox)
      delete this.checkBox;
    rnmc_stdMediaGroup_unloadObject(srcNode);
  }

  function onPressHandler(){

    rnmc_stdMediaObject_onPressHandler();
    if (this.checkBox)
      this.checkBox.pressButton();
  }
 
  function onRollOverHandler(){

    rnmc_stdMediaObject_onRollOverHandler();
    if (this.checkBox)
      this.checkBox.rolloverButton();
  }
  
//  Никита: ПОКА ПЕРЕОПРЕДЕЛИЛ ТАК
//  лучшего способа пока не придумал
  function getPosition(){
    var positionArray = new Array();
    var realX = this.x;
    var realY = this.y;
    var realWidth = this.width;
    var realHeight = this.height;
    positionArray.push(realX, realY, realWidth, realHeight);
    return positionArray;
  }

  function onAnswerChanged(chkBoxId, currentSelected){
//trace("1747--this.checkMode="+parent.checkMode);
    if(currentSelected == CHECKBOX_STATE_CHECKED){
      this.answerChecked = true;
    } else {
      this.answerChecked = false;
    }
    parent.notifyAnswerChanged(this.id, this.answerChecked);
     if(parent.checkMode == QUESTION_CHECK_IMMEDIATELY){
//trace("1756-this.answeredRightActions-"+this.answeredRightActions);	
//  отмечен правильный ответ (выбран) и есть на это Actions:
		if(this.rightAnswer && this.answerChecked && this.answeredRightActions!=null){

			for(var i = 0; i < this.answeredRightActions.length; i++){
				this.dispatchAction(this.answeredRightActions[i]);
			}
		}
//trace("1763-this.answeredWrongActions-"+this.answeredWrongActions);	 
		if(!this.rightAnswer && this.answerChecked && this.answeredWrongActions!=null){

			for(var i = 0; i < this.answeredWrongActions.length; i++){
				this.dispatchAction(this.answeredWrongActions[i]);
			}

		}
     }	 
	}
  
  function setCheckBoxError(){
 //trace("setCheckBoxError  "+this.answerChecked+this.noSelectCheckBoxImg);
    if (this.checkBox && this.answerChecked &&
        this.errorCheckBoxImg != null ){
      this.errorCheckBoxImg.showObject();
      
      this.checkBox.visible = false;
    }
  if (this.checkBox && this.answerChecked==false &&
        this.noSelectCheckBoxImg != null ){
     //trace("setCheckBoxError1  "+this.answerChecked);
      this.noSelectCheckBoxImg.showObject();
      
      this.checkBox.visible = false;
    }
  }
  
  function resetAnswer(){
    this.answerChecked = false;
    
    if (this.errorCheckBoxImg)
      this.errorCheckBoxImg.hideObject();
    
    if (this.noSelectCheckBoxImg)
      this.noSelectCheckBoxImg.hideObject();
  }
]]></script>
</composition>
</rmml>
