<?xml version="1.0" encoding="UTF-8"?>
<rmml>
<!--
$RCSfile: rnmc_stdMediaGroup.xml,v $
$Revision: 941 $

last change: $Date: 2009-02-06 17:24:37 +0300 (Пт, 06 фев 2009) $
             $Author: toha $

  Lacerta Project
  version 1.0.0.1
  Copyright (C) 2008 RNMC
-->

<!-- 
    Группа из нескольких объектов
-->
<composition name="rnmc_stdMediaGroup" class="rnmc_stdMediaObject" userEvents="asyncAction">
<script event="asyncAction"><![CDATA[
trace("asyncAction");
//  this.dispatchAction(new Array("showObject", "reseachObj"));
//  this.dispatchAction(new Array("showObjectOnly", "reseachObj.qtObj01"));
]]></script>
<script><![CDATA[
  this.type = "rnmc_stdVisibleGroup"
  this.visibility = OBJECT_VISIBILITY_UNDEFINED;

  this.objectState = OBJECT_STATE_HIDDEN;

  
//  для каждого объекта необходимо определить
//  какие эффекты к нему применимы
  this.fadeEffectEnabled = true;
  this.moveEffectEnabled = true;
  this.scaleEffectEnabled = false;
  
  
//  ОГРАНИЧЕНИЕ КОНТЕНТА
  this.watchRestriction = -1;
//  объект по умолчанию (если есть ограничения)
  this.defaultObjectId = null;

// диспетчер (если назначен)
  this.dispatchObject = null;
  this.dispatchFunction = null;

// содержимое (изображения, тексты, видео ...)
  this.childObjects = null;

//  условия
  this.attachedConditions = null;

  function parseConditionNode(srcNode){
    var xmlAttributeMap = null;
    var xmlAttribute = null;

    if(srcNode.nodeName == "condition"){
      xmlAttributeMap = srcNode.attributes;
      if(srcNode.textContent != null){
        if(!scene.Utils.validateConditionFormat(srcNode.textContent)){
          trace("#FF0000ОШИБКА: условие записано с синтаксическими ошибками: " + srcNode.textContent);
          return false;
        }
        var newCondition = new Object();
        if (xmlAttributeMap){
          xmlAttribute =  xmlAttributeMap.getNamedItem("id");
          if (xmlAttribute != null && xmlAttribute.specified)
            newCondition.id = xmlAttribute.value;
        }
        newCondition.plainTextCommand = srcNode.textContent;
        newCondition.evalString = translateConditionString(srcNode.textContent);
        if(!this.attachedConditions){
          this.attachedConditions = new Array();
        }
        this.attachedConditions.push(newCondition);
      } else {
      
      }
    }

    return true;
  }

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

    this.x = 0;
    this.y = 0;
    this.childObjects =  new Array();
    
    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 == "false")
        this.disabled = true;
      xmlAttribute =  xmlAttributeMap.getNamedItem("restriction");
      if (xmlAttribute != null && xmlAttribute.specified){
        switch((xmlAttribute.value).toLowerCase()){
        case "exclusive_visible":
          this.watchRestriction = RESTRICTION_EXCLUSIVE_VISIBLE;
           break;
        case "exclusive_pressed":
          this.watchRestriction = RESTRICTION_EXCLUSIVE_PRESSED;
          break;
        default:
          trace("rnmc_stdGroup: неизвестное ограничение (restriction == " + xmlAttribute.value + ")");
          break;
        }
      }
    }
    xmlNode = srcNode.firstChild;
    this.loadChildsObject(srcNode);
    while(xmlNode){
      if(xmlNode.nodeName == "param"){
        this.parseParamNode(xmlNode);
      } else if(xmlNode.nodeName == "actions"){
        rnmc_stdMediaObject_parseActionsNode(xmlNode);
      } else if(xmlNode.nodeName == "effects"){
        this.parseEffectsNode(xmlNode);
      } else if(xmlNode.nodeName == "effect"){
        this.parseEffectNode(xmlNode);
      } else if(xmlNode.nodeName == "condition"){
        this.parseConditionNode(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);        
      } else if(xmlNode.nodeName == "objectives"){
        this.parseObjectivesNode(xmlNode);
      } else if(xmlNode.nodeName == "properties"){
        parsePropertiesNode(xmlNode);
      }
      xmlNode = xmlNode.nextSibling;
    }
  //  если есть ограничения на нажатия кнопок
    if(this.watchRestriction == RESTRICTION_EXCLUSIVE_PRESSED){
      for(var i = 0; i < this.childObjects.length; i++){
        if(this.childObjects[i].type == "rnmc_stdButton"){
          this.childObjects[i].setPressCallBack(this, this.notifyChildButtonPressed);
          this.childObjects[i].setReleaseCallBack(this, this.notifyChildButtonPressed);
        }
      }
    }
    else if(this.watchRestriction == RESTRICTION_EXCLUSIVE_VISIBLE){
      //  устанавливать callback не нужно, т.к. и бех него уведомления приходят
      /*
      for(var i = 0; i < this.childObjects.length; i++){
        this.childObjects[i].setShowCallBack(this, this.notifyChildObjectShown);
      }
      */
    }
    return true;
  };

  function loadChildsObject(srcNode){
    if (!srcNode)
      return false;

    if (this.childObjects == null)
      this.childObjects = new Array();

    var xmlNode = srcNode.firstChild;
    while(xmlNode){
      var newObject = scene.Utils.initStdObjectFromNode(xmlNode, this);
      if(newObject){
    //    для шаблона Integration    
        if(this.integration)
            newObject.idUnique = this.childObjects.length;                
        this.childObjects.push(newObject);
    //    для шаблона Integration    
        if(newObject.quantity > 1){    
            this.childObjects[this.childObjects.length-1].copies = new Array(newObject.quantity);                    
            for(var i = 1; i < newObject.quantity; i++){
                var newObject2 = scene.Utils.initStdObjectFromNode(xmlNode, this);
                newObject2.quantity = 1;
                newObject2.copy = true;
                newObject2.idUnique = this.childObjects.length - 1;
                this.childObjects[this.childObjects.length-1].copies[i] = newObject2;
            }
        }
      }
      xmlNode = xmlNode.nextSibling;
    };
    return true;
  }
  
  function getChildObject(objID){
    for(var i = 0; i < this.childObjects.length; i++){
      if(this.childObjects[i].id == objID)
        return this.childObjects[i];
    }
    return null
  }  

  function loadObject(){
    this.x     = this.objectX;
    this.y      = this.objectY;
    this.depth = this.objectDepth;

    if (this.objectHitArea != null)
      this.hitArea = this.objectHitArea;  
  }

  function unloadObject(){
//trace("group: " + this.id + " - unloadObject()");
    for(var i = 0; i < this.childObjects.length; i++){
      this.childObjects[i].effectsEnabled = false;
      this.childObjects[i].hideObject();
    }
    this.visible = false;
  }

//  показ группы
  function showObject(){
    this.loadObject();

    this.objectState = OBJECT_STATE_VISIBLE;
    
    // если задано выравнивание внутри композиции
    if (this.layoutMode == LAYOUT_VERTICAL || this.layoutMode == LAYOUT_HORIZONTAL){
      var newX = 0;//this.x;
      var newY = 0;//this.y;
    for(var i = 0; i < this.childObjects.length; i++){
      if(this.childObjects[i].visibility == OBJECT_VISIBILITY_TRUE){
        this.childObjects[i].showObject();
          
          this.childObjects[i].x = newX;
          this.childObjects[i].y = newY;
          
          switch(this.layoutMode){
            case LAYOUT_VERTICAL:
              newY += this.childObjects[i].height;
              break;
            case LAYOUT_HORIZONTAL:
              newX += this.childObjects[i].width;
              break;
          }
        }
      }
    } else {
      for(var i = 0; i < this.childObjects.length; i++){
        if(this.childObjects[i].visibility == OBJECT_VISIBILITY_TRUE){
          this.childObjects[i].showObject();
        }
      }
    }

  // проверка накладываемых на группу ограничений
    if(this.watchRestriction == RESTRICTION_EXCLUSIVE_PRESSED){
      for(var i = 0; i < this.childObjects.length; i++){
        if(this.childObjects[i].type == "rnmc_stdButton"){
          if(this.childObjects[i].buttonPressed){
            this.notifyChildButtonPressed(this.childObjects[i].id);
            break;
          }
        }
      }
    } else if(this.watchRestriction == RESTRICTION_EXCLUSIVE_VISIBLE){
      for(var i = 0; i < this.childObjects.length; i++){
        if(this.childObjects[i].visible){
          var newAction  = new Array("showObjectOnly", this.childObjects[i].id);
          this.doAction(newAction);
          break;
        }
      }
    }

  //  перебор присоединённых эффектов для показа
    this.effectsTarget = this;
    var effectsStarted = this.startEffects(EVENT_ON_SHOW);
    if(effectsStarted == 0){
      this.visible = true;
    }

    if(this.showCallBackFunction != null && this.showCallBackObject != null)
      this.showCallBackFunction.call(this.showCallBackObject, this.id);

  // если определены действия на соответствующие события
    if(this.actionsList && this.actionsList[EVENT_ON_ROLLOVER])
      this.onRollOver = this.onRollOverHandlerAlias;
    if(this.actionsList && this.actionsList[EVENT_ON_ROLLOUT])
      this.onRollOut = this.onRollOutHandlerAlias;
    if(this.actionsList && this.actionsList[EVENT_ON_PRESS])
      this.onPress = this.onPressHandlerAlias;
    if(this.actionsList && this.actionsList[EVENT_ON_RELEASE])
      this.onRelease = this.onReleaseHandlerAlias;

  //  OBJECTIVES for onShow
    if(this.onShowObjectives && this.objectivesList){
      for(var i = 0; i < this.objectivesList.length; i++){
        if(this.objectivesList[i] == "onShow"){
          this.objectivesList[i].complete = true;
          this.checkObjectives();
        }
      }
    }
  //  END OBJECTIVES for onShow

    this.applyActions(EVENT_ON_SHOW);
  };

  function hideObject(){
//trace("group: " + this.id + " - hideObject()");
    if(this.objectState == OBJECT_STATE_VISIBLE){
      this.childObjectRunning = 0;
      var effectsStarted = this.startEffects(EVENT_ON_HIDE);
      if(effectsStarted == 0){
        //  если в группе нет своих эффектов на hide
        this.childObjectEffects = 0;
        for(var i = 0; i < this.childObjects.length; i++){  
          if(this.childObjects[i].attachedEffects
            && this.childObjects[i].attachedEffects[EVENT_ON_HIDE]){
          // если есть эффекты у дочерних объектов
            this.childObjects[i].setHideCallBack(this, this.notifyChildObjectHidden);
            this.childObjectRunning++;
          }
          this.childObjects[i].hideObject();
        }
        if(this.childObjectRunning == 0){
          //  значит нет ни одного child'a у которого присходят эффекты
          this.visible = false;  
          this.objectState = OBJECT_STATE_HIDDEN;          
        }
      } else {
        for(var i = 0; i < this.childObjects.length; i++){  
          if(this.childObjects[i].attachedEffects && this.childObjects[i].attachedEffects[EVENT_ON_HIDE]){  
            // если есть эффекты у дочерних объектов
            this.childObjects[i].setHideCallBack(this, this.notifyChildObjectHidden);
            this.childObjectRunning++;
            this.childObjects[i].hideObject();
          } 
        }
      }
      //  OBJECTIVES for onHide
      if(this.onHideObjectives && this.objectivesList){
        for(var i = 0; i < this.objectivesList.length; i++){
          if(this.objectivesList[i] == "onHide"){
            this.objectivesList[i].complete = true;
            this.checkObjectives();
          }
        }
      }
      //  END OBJECTIVES for onHide
      this.applyActions(EVENT_ON_HIDE);
      //this.objectState = OBJECT_STATE_VISIBLE;
    }
  };
  
//  Переопределена, т.к. помимо подсчета своих эффектов надо проверять
//  количество дочерних элементов у которых еще что-то происходит
//  сообщение от эффекта
  function notifyEffectComplete(effectObject){
    if(this.actionsList && this.actionsList[EVENT_ON_COMPLETE_EFFECT]){
      for(var i = 0; i < this.actionsList[EVENT_ON_COMPLETE_EFFECT].length; i++){
        if(this.actionsList[EVENT_ON_COMPLETE_EFFECT].eventParam
          && this.actionsList[EVENT_ON_COMPLETE_EFFECT].eventParam == effectObject.id){
          parent.dispatchAction(this.actionsList[EVENT_ON_COMPLETE_EFFECT]);
        }
      }
    }
    effectObject.clearCallBack();
    this.effectsRunning--;
    if(effectObject.effectEvent == EVENT_ON_HIDE){
      if(this.effectsRunning == 0 && this.childObjectRunning == 0){
        this.unloadObject();
        //  если назначена функция обратного вызова
        if(this.hideCallBackFunction != null && this.hideCallBackObject != null)
          this.hideCallBackFunction.call(this.hideCallBackObject, this.id);
      }
    }
  }

  function positionObject(objX, objY, objW, objH){
    if (objX != 'undefined' && objX != null)
      this.x = parseInt(objX);
    if (objY != 'undefined' && objY != null)
      this.y = parseInt(objY);

    //rnmc_stdMediaObject_positionObject(objX, objY, objW, objH);
  }

  function setDispatcher(targetObject, targetFunction){
    if(targetObject && targetFunction){
      this.dispatchObject = targetObject;
      this.dispatchFunction = targetFunction;
    }
  }

  //  функция возвращает путь до объекта от корня (самого шаблона)
  function getFullPath(){
    var parentPath = null;
    if(!this.id){
//trace("#FF0000Ошибка: невозвожно получить полный путь к объекту " + objectId);  
      return "";
    } else {
      if("getFullPath" in parent)
        parentPath = parent.getFullPath();
    }
    if(parentPath){
      return parentPath + "." + this.id;
    } else {
      return this.id;
    }
  }
  
  //  функция установки координат и рамеров объекта
  function setPosition(newX, newY, newWidth, newHeight, newDepth, newRatio){
    if (newX)
      this.x = parseInt(newX);
    if (newY)
      this.y = parseInt(newY);
    if (newDepth)
      this.depth = parseInt(newDepth);
  }

  //  ============================    C O N D I T I O N S    ===========================
  //  превращение в выражение, которое можно передать в eval
  function translateConditionString(conditionString){
    var commandForEvaluate = conditionString;
    conditionString = scene.Utils.replaceString(conditionString, "\n", ""); 
    conditionString = scene.Utils.replaceString(conditionString, "\r", ""); 
    conditionString = scene.Utils.replaceString(conditionString, "\t", ""); 
    commandForEvaluate = scene.Utils.replaceString(commandForEvaluate, "\n", ""); 
    commandForEvaluate = scene.Utils.replaceString(commandForEvaluate, "\r", ""); 
    commandForEvaluate = scene.Utils.replaceString(commandForEvaluate, "\t", ""); 
    //  делаем замену для проверки св-в объектов
    for(var i = 0; i < conditionString.length; i++){
      if(conditionString[i] == "["){
        var closeParenthesis = conditionString.indexOf("]", i);
        var objectName = conditionString.slice(i + 1, closeParenthesis);
        var closeProperty = (conditionString.slice(closeParenthesis + 2)).search(/\W/);
        var propertyName = conditionString.slice(closeParenthesis + 2, (closeParenthesis + closeProperty + 2));
        commandForEvaluate = scene.Utils.replaceString(commandForEvaluate, "[" + objectName + "]." + propertyName,
          "getObjectProperty(\"" + objectName + "\", \"" + propertyName + "\")");
      }
    }
    //  Extra tests  =========================================================
    //  тут надо конечно в будущем учесть, что внутри test() могут быть скобки
    var testIndex = commandForEvaluate.indexOf("test(");
    while(testIndex >= 0){
      var closeParenthesis = commandForEvaluate.indexOf(")", (testIndex + 5));
      var testContent = commandForEvaluate.slice(testIndex + 5, closeParenthesis);
      var testParams = testContent.split(",");
      var replaceWith = "false";
      if(testParams.length >= 2){
        switch(testParams[0]){
        case "isStepVisited":
          replaceWith = "scene.Labwork.resultManager.getStepVisited(" + parseInt(testParams[1]) + ")";
          break;
        case "isStepExec":         
          replaceWith = "scene.Labwork.resultManager.getStepResult(" + parseInt(testParams[1]) + ")";
// trace("isStepExec  "+replaceWith);
          break;
        default:
          trace("#FF0000ОШИБКА: неизвестное выражение в condition: test(" + testContent + ")");
          break;
        }
      }
      commandForEvaluate = scene.Utils.replaceString(commandForEvaluate, "test(" + testContent + ")", replaceWith);
      testIndex = commandForEvaluate.indexOf("test(");
    }
    //  делаем замену для actions  ===========================================
    for(var i = 0; i < conditionString.length; i++){
      if(conditionString[i] == "{"){
        var closeParenthesis = conditionString.indexOf("}", i);
        var actionCommand = conditionString.slice(i + 1, closeParenthesis);
        var actions = (actionCommand).split(";");
        for(var j = 0; j < actions.length; j++){
          var parsedCommand = null;
          var newCommand = actions[j].split(":");
          if(newCommand.length > 2){
            for (var k = 2; k < newCommand.length; ++k)
              newCommand[1] += ":" + newCommand[k]
            parsedCommand = new Array(newCommand[0], newCommand[1]);
          }
          else
            parsedCommand = newCommand;
            
          var evalCommand = "this.dispatchAction(new Array(\""
            + parsedCommand[0] + "\", \"" + parsedCommand[1] + "\"));";

          commandForEvaluate = scene.Utils.replaceString2(
            commandForEvaluate,
            parsedCommand[0] + ":" + parsedCommand[1],
            evalCommand);
        };
      }
    }
    return commandForEvaluate;
  }

  function testCondition(conditionObject){
    try{
      eval(conditionObject.evalString);
    }
    catch(ex){
      trace("#FF0000Error: " + ex);
    }
  }

  function getObjectProperty(objName, objProperty){
trace(this.id + ".get property: " + objName + ", " + objProperty);
	if(objName.charAt(0) == "."){
      if(objName.charAt(1) == "."){
      // относительно родительской группы
        var objId = objName.slice(1);
        return parent.getObjectProperty(objId, objProperty);
      } else if (objName == "."){
/*
        if (this.propertysList) {
          if (this.propertysList[objProperty] != undefined)
            return this.propertysList[objProperty];
        }
*/
        return rnmc_stdMediaObject_getObjectProperty(objName, objProperty);
      } else {
        // относительно текущей группы
        var objId = objName.slice(1);
        var index = objId.indexOf(".");
        if (index != -1){
          var parentId = objId.slice(0, index);
          var childId = objId.slice(index+1);
          for(var i = 0; i < this.childObjects.length; i++){
            if(this.childObjects[i].id == parentId){
              return this.childObjects[i].getObjectProperty("." + childId, objProperty);
            }
          }
        } else {
          for(var i = 0; i < this.childObjects.length; i++){
            if(this.childObjects[i].id == objId){
              return this.childObjects[i].getObjectProperty(objId, objProperty);
            }
          }
        }
      }
    } else {
      return scene.Labwork.currentStep.getObjectProperty("." + objName, objProperty);
    }
    return null;
  }

  function setObjectProperty(objName, objProperty, propertyValue){
//trace(this.id + ".testing property: " + objName + "| " + objProperty+ "| " + propertyValue);
    if(objName.charAt(0) == "."){
      if(objName.charAt(1) == "."){
      // относительно родительской группы
        var objId = objName.slice(1);
        parent.setObjectProperty(objId, objProperty, propertyValue);
      } else if (objName == "."){
        if (!this.propertysList)
          this.propertysList = new Array();
        this.propertysList[objProperty] = propertyValue;
      } else {
      // относительно текущей группы
        var objId = objName.slice(1);
        var index = objId.indexOf(".");
        if (index != -1){
          var parentId = objId.slice(0, index);
          var childId = objId.slice(index+1);
          for(var i = 0; i < this.childObjects.length; i++){
            if(this.childObjects[i].id == parentId){
              this.childObjects[i].setObjectProperty(
                "." + childId, objProperty, propertyValue);
            }
          }
        } else {
          for(var i = 0; i < this.childObjects.length; i++){
            if(this.childObjects[i].id == objId){
              this.childObjects[i].setObjectProperty(
                objId, objProperty, propertyValue);
            }
          }
        }
      }
    } else {
      scene.Labwork.currentStep.setObjectProperty(
        "." + objName, objProperty, propertyValue);
    }
  }

  //  ============================    A C T I O N  S    ===============================
// Функция производит доставку сообщения объекту,
// который должен его выполнить

  /*  Будем считать, что действие направлено на
   *  объект заданный в singleAction[1].
   *  Формат строки задания объекта:
   *  - id1.[id2.]idn  - путь к объекту с корня сцены (абсолютный путь)
   *  - .id1.[id2.]idn - путь к объекту относительно исочника его выброса (относительный путь)
   *  - ..       - начать поиск с "родительского" объекта
   */
  function dispatchAction(singleAction){
//trace("dispatchAction:" + singleAction);

    for (var i = 0; i < singleAction.length; ++i)
      singleAction[i] = scene.Utils.trim(singleAction[i]);

    if (singleAction[0] == "asyncAction"){
//      this.fireEvent("asyncAction");
      return;
    }
    if (singleAction[1] != null){
      if(singleAction[1].slice(0,8) == "LABWORK." ||
         singleAction[1].slice(0,8) == "LABWORK"){
        //  если написано ключевое слово LABWORK - значит целевой 
        //  объект - глобальный отправляем на обработку в Loader
        singleAction = singleAction.slice(0);
        singleAction[1] = singleAction[1].slice(8);
        scene.Labwork.doAction(singleAction);
      } else if(singleAction[1].charAt(0) == "."){
        if(singleAction[1].charAt(1) == "."){
        // !!!! Сделать копию массива !!!
          singleAction = singleAction.slice(0);
          singleAction[1] = singleAction[1].slice(1);
          parent.dispatchAction(singleAction);
        } else {
        // !!!! Сделать копию массива !!!
          singleAction = singleAction.slice(0);    
          singleAction[1] = singleAction[1].slice(1);
          this.doAction(singleAction);
        }
      } else {
        scene.Labwork.currentStep.doAction(singleAction);
      }
    } else {
      switch (singleAction[0]) {
        case "goToStep":
        case "goToStepWithId":
        case "goPreviousStep":
        case "goNextStep":
        case "goFirstStep":
        case "goLastStep":
        case "goToSummary":
          scene.Labwork.currentStep.doAction(singleAction);
          break;

        default:
          // действие без параметров - сразу перенаправить в doAction
          this.doAction(singleAction);
          break;
      }
    }
  }

//  Функция непосредственно выполняет действие заданное параметром
  function doAction(singleAction){
//trace("group: " + this.id + " - 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);
        // !!!! Сделать копию массива !!!
          singleAction = singleAction.slice(0);
          singleAction[1] = singleAction[1].slice(index+1);
          for(var i = 0; i < this.childObjects.length; i++){
            if(this.childObjects[i].id == childId){
              if("doAction" in this.childObjects[i])
                this.childObjects[i].doAction(singleAction);
            }
          }
          return;
        }
      }
    }
    switch(singleAction[0]){
      case "testConditions":
      //  ???????????????????????????????????????????????????????
        break;
      case "testCondition":
        if(this.attachedConditions){
          for(var i = 0; i < this.attachedConditions.length; i++){
            if(this.attachedConditions[i].id == singleAction[1]){
              this.testCondition(this.attachedConditions[i]);
            }
          }
        }
        break;
      case "applyEffect":
        this.effectsTarget = this;
        var effectsStarted = this.startEffectWithId(singleAction[1]);
        break;
      case "pressButton":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if(this.childObjects[i].type == "rnmc_stdButton"){
              this.childObjects[i].pressButton();
            }
          }
        }
        break;
      case "unpressButton":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1])
            if(this.childObjects[i].type == "rnmc_stdButton")
              this.childObjects[i].unpressButton();
        }
        break;
      case "releaseButton":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1])
            if(this.childObjects[i].type == "rnmc_stdButton" )
              this.childObjects[i].releaseButton();
        }
        break;
      case "releaseAllButtons":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].type == "rnmc_stdButton" )
            this.childObjects[i].releaseButton();
        }
        break;
      case "enableButton":
        //for(var i = 0; i < this.childObjects.length; i++){
        //  if(this.childObjects[i].type == "rnmc_stdButton" )
        //    this.childObjects[i].enableButton();
        //}
        break;
      case "disableButton":
        //for(var i = 0; i < this.childObjects.length; i++){
        //  if(this.childObjects[i].type == "rnmc_stdButton" )
        //    this.childObjects[i].disableButton();
        //}
        break;
      case "showObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if(!this.childObjects[i].disabled){
              this.childObjects[i].showObject();  
              this.notifyChildObjectShown(this.childObjects[i].id);
            }
          }
        }
        break;
      case "resetObject":
        for(var i = 0; i < this.childObjects.length; ++i){
          if(this.childObjects[i].id == singleAction[1]){
            if(!this.childObjects[i].disabled){
              this.childObjects[i].resetObject();
            }
          }
        }
        break;
      case "checkObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if(!this.childObjects[i].disabled){
              this.childObjects[i].checkObject();
            }
          }
        }
        break;
      case "frozenObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if(!this.childObjects[i].disabled)
              this.childObjects[i].frozenObject();
          }
        }
        break;
      case "unfrozenObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if(!this.childObjects[i].disabled)
              this.childObjects[i].unfrozenObject();
          }
        }
        break;		
      case "enableObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if ("enableObject" in this.childObjects[i]){
              this.childObjects[i].enableObject();
            }
          }
        }
        break;
      case "disableObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if ("disableObject" in this.childObjects[i]){
              this.childObjects[i].disableObject();
            }
          }
        }
        break;
      case "enableAllObjects":
        for(var i = 0; i < this.childObjects.length; i++){
            if ("enableObject" in this.childObjects[i]){
              this.childObjects[i].enableObject();
            }
        }
        break;
      case "disableAllObjects":
        for(var i = 0; i < this.childObjects.length; i++){
            if ("disableObject" in this.childObjects[i]){
              this.childObjects[i].disableObject();
            }
        }
        break;
      case "enableAllButtons":
        for(var i = 0; i < this.childObjects.length; i++){
            if (this.childObjects[i].type == "rnmc_stdButton" && 
                "enableObject" in this.childObjects[i]){
              this.childObjects[i].enableObject();
            }
        }
        break;
      case "disableAllButtons":
        for(var i = 0; i < this.childObjects.length; i++){
            if (this.childObjects[i].type == "rnmc_stdButton" && 
                "disableObject" in this.childObjects[i]){
              this.childObjects[i].disableObject();
            }
        }
        break;
      case "showObjectOnly":
        for(var i = 0; i < this.childObjects.length; i++){
          if(!this.childObjects[i].disabled){
            if(this.childObjects[i].id == singleAction[1]){
              this.childObjects[i].showObject();
              this.notifyChildObjectShown(this.childObjects[i].id);
            } else {
              this.childObjects[i].hideObject();
            }
          }
        }
        break;
      case "hideObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if(!this.childObjects[i].disabled)
              this.childObjects[i].hideObject();
          }
        }
        break;
      case "hideAllObjects":
        for(var i = 0; i < this.childObjects.length; i++){
          if(!this.childObjects[i].disabled)
            this.childObjects[i].hideObject();
        }
        break;
      case "saveObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if("saveAs" in this.childObjects[i]){
              this.childObjects[i].saveAs();
            }
          }
        }
        break;
      case "copyObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if("saveToClipboard" in this.childObjects[i])
              this.childObjects[i].saveToClipboard();
          }
        }
        break;
      case "playObjectOnly":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if("playObject" in this.childObjects[i])
              this.childObjects[i].playObject();
          } else {
            if("stopObject" in this.childObjects[i])
              this.childObjects[i].stopObject();
          }
        }
        break;
      case "playObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if("playObject" in this.childObjects[i])
              this.childObjects[i].playObject();
          }
        }
        break;        
      case "stopObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if("stopObject" in this.childObjects[i])
              this.childObjects[i].stopObject();
          }
        }
        break;
      case "pauseObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            if("pauseObject" in this.childObjects[i])
              this.childObjects[i].stopObject();
          }
        }
        break;        
      case "setPosition":
        var newPosX = 0;
        var newPosY = 0;
        var newPosWidth = 0;
        var newPosHeight = 0;
        var newPosDepth = 0;
        var newPosRatio = null;
        var newPositionParam = (singleAction[1]).split(",");
        if(newPositionParam.length < 6){
          trace("#FF0000Ошибка - неверный формат параметров в действии setPosition:" + singleAction[1]);
          return;
        }
        var objectId = newPositionParam[0];
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == objectId){
            if(newPositionParam[1])
              newPosX = newPositionParam[1];
            if(newPositionParam[2])
              newPosY = newPositionParam[2];
            if(newPositionParam[3] && parseInt(newPositionParam[3]) > 0)
              newPosWidth = newPositionParam[3];
            if(newPositionParam[4] && parseInt(newPositionParam[4]) > 0)
              newPosHeight = newPositionParam[4];
            if(newPositionParam[5])
              newPosDepth = newPositionParam[5];
            if(newPositionParam[6])
              newPosRatio = newPositionParam[6];
            this.childObjects[i].setPosition(newPosX, newPosY, newPosWidth, newPosHeight, newPosDepth, newPosRatio);
          }
        }
        break;
      case "resetPosition":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            this.childObjects[i].resetPosition();
          }
        }
        break;
      case "zoomInObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            this.childObjects[i].zoomIn();
          }
        }
        break;
      case "zoomOutObject":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].id == singleAction[1]){
            this.childObjects[i].zoomOut();
          }
        }
        break;
      case "playQTAngle":
        var newMinAngle = 0;
        var newMaxAngle = 0;
        var newPositionParam = (singleAction[1]).split(",");
        if(newPositionParam.length < 3){
          trace("#FF0000Ошибка - неверный формат параметров в действии playQTAngle:" + singleAction[1]);
          return;
        }
        var objectId = newPositionParam[0];
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].type == "rnmc_stdQuickTime" && this.childObjects[i].id == objectId){
            if(newPositionParam[1])
              newMinAngle = newPositionParam[1];
            if(newPositionParam[2])
              newMaxAngle = newPositionParam[2];
            this.childObjects[i].playQtFromAngleToAngle(newMinAngle, newMaxAngle);
          }
        }
        break;
      case "checkCrossword":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].type == "rnmc_Crossword"
            && this.childObjects[i].id == singleAction[1]){
            this.childObjects[i].checkObject();
          }
        }
        break;
      case "resetCrossword":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].type == "rnmc_Crossword"
            && this.childObjects[i].id == singleAction[1]){
            this.childObjects[i].resetObject();
          }
        }
        break;
      case "displayStepResult":
//trace("#FF0000displayStepResult");
        var stepId = null;
        var objectId = null;
        var stepResultValue = null;
        if(singleAction[1]){
          var actionParams = (singleAction[1]).split(",");
          if(actionParams.length < 2){
            trace("#FF0000Ошибка - неверный формат параметров в действии displayStepResult:" + singleAction[1]);
            return;
          }
          objectId = actionParams[0];
          for(var i = 0; i < this.childObjects.length; i++){
            if(this.childObjects[i].type == "rnmc_stdText" && this.childObjects[i].id == objectId){
              if(actionParams[1])
                stepId = actionParams[1];
              stepResultValue = scene.Labwork.resultManager.getStepResult(stepId);
              if(scene.Labwork.resultManager.getStepVisited(stepId)){
                if(parseInt(stepResultValue) >= 0 && parseInt(stepResultValue) <= 100){
                  this.childObjects[i].setTextValue(stepResultValue + " %");
                }
              } else {
                this.childObjects[i].setTextValue(" - ");
              }
            }
          }
        }
        break;
      case "displayTotalResult":
        for(var i = 0; i < this.childObjects.length; i++){
          if(this.childObjects[i].type == "rnmc_stdText" && this.childObjects[i].id == singleAction[1]){
            var totalResultValue = scene.Labwork.resultManager.getTotalResult();
            if(parseInt(totalResultValue) >= 0 && parseInt(totalResultValue) <= 100){
              this.childObjects[i].setTextValue(totalResultValue + " %");
            } else {
              this.childObjects[i].setTextValue(" - ");
            }
          }
        }
        break;
      case "resetLabworkStatistic":  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        
        break;      
      case "fireLink":
        scene.Utils.fireLink(singleAction[1]);
        break;
      case "hideHint":
        if (scene.Hint)
          scene.Hint.stopHint();
        break;
      case "setProperty":
        var param = singleAction[1].split(",");
        if (param.length == 2)
          this.setObjectProperty(".", param[0], param[1]);
        else
          this.setObjectProperty(".", param[1], param[2]);
        break;
    };
  }

  //  Сообщение от дечернего объекта о показе
  function notifyChildObjectShown(objectId){
//trace("rnmc_stdGroup (" + this.id + ").notifyChildObjectShown(" + objectId + ")");
    if(this.watchRestriction == RESTRICTION_EXCLUSIVE_VISIBLE){
      for(var i = 0; i < this.childObjects.length; i++){
        if(this.childObjects[i].id != objectId)
          if(!this.childObjects[i].disabled){
            this.childObjects[i].hideObject();
        }
      }
    }

  //  если группа ещё не показана (а дочерний уже показан), то надо её показать
  //  и сообщить об этом родительской объекту
    if(!this.visible){
    
      loadObject();
    //  показываем только сам группу без вызова showObject(),
    //  т.е. без учета того, какие объекты в ней видны
      this.visible = true;

    //  меняем состояние группы на OBJECT_STATE_VISIBLE (т.к. что-то из содержимого показано)
      this.objectState = OBJECT_STATE_VISIBLE;
      parent.notifyChildObjectShown(this.id);
    }
  }

//  Сообщение от дочернего объекта о тож что объект спрятан
  function notifyChildObjectHidden(){
//trace("#notifyChildObjectHidden; childObjectRunning == " + this.childObjectRunning);
    this.childObjectRunning--;
    if(this.childObjectRunning == 0 && this.effectsRunning == 0){
      this.unloadObject();
      //  если назначена функция обратного вызова
      if(this.hideCallBackFunction != null && this.hideCallBackObject != null)
        this.hideCallBackFunction.call(this.hideCallBackObject, this.id);
    }
  }

  function notifyChildButtonPressed(objectId){
//trace("rnmc_stdGroup (" + this.id + ").notifyChildButtonPressed(" + objectId + ")");
    if(this.watchRestriction == RESTRICTION_EXCLUSIVE_PRESSED){
      for(var i = 0; i < this.childObjects.length; i++){
        if(this.childObjects[i].type == "rnmc_stdButton"){
          if(this.childObjects[i].id != objectId){
            this.childObjects[i].setButtonState(BUTTON_STATE_NORMAL);
          }
        }
      }
    }
  }

  //  =============================================================
  //  для работы  с автоАттачем
  function getChildPosition(objectId){
    var childPosition = null;
    for(var i = 0; i < this.childObjects.length; i++){
      if(this.childObjects[i].id == objectId){
        childPosition = this.childObjects[i].getPosition();
      }
    }
    return childPosition;
  }

  //   сообщение о изменнении позиции некоторого объекта
  function notifyPositionChanged(objectId){
    for(var i = 0; i < this.childObjects.length; i++){
      if(this.childObjects[i].autoAttachTarget == objectId){
        this.childObjects[i].updatePosition();
      }
    }
  }

  //  лучше будет её отсюда убрать
  function buttonDispatcher(btnId){
    if(this.watchRestriction == RESTRICTION_EXCLUSIVE_PRESSED){
      for(var i = 0; i < this.childObjects.length; i++){
        if(this.childObjects[i].type == "rnmc_stdButton"){
          if(this.childObjects[i].id != btnId){
            this.childObjects[i].setButtonState(BUTTON_STATE_NORMAL);
          }
        }
      }
    }
    else if(this.watchRestriction == RESTRICTION_EXCLUSIVE_VISIBLE){
      for(var i = 0; i < this.childObjects.length; i++){
        if(!this.childObjects[i].disabled){
          if(this.childObjects[i].id != btnId)
            this.childObjects[i].hideObject();
        }
      }
    }

    //if(this.targetFunction != null && this.dispatchObject != null)
    //  this.targetFunction.call(this.dispatchObject, this.id);
  }

  //  GLOBAL PROPERTIES
//  тестирует значение переменной на равенство некоторому значению
  function testGlobalProperty(propertyName,  propertyValue){
//trace("#FF0000rnmc_stdMediaGroup.testGlobalProperty()");
    if(scene.Labwork.getGlobalProperty(propertyName) == propertyValue){
      return true;
    } else {
      return false;
    }
  }
  
//////////////////////////////////////////////////////////
// Функции, относящиеся к статистике по работе с объектом
//
  function getResult(resultsArray){
    if(this.childObjects){
      for(var i = 0; i < this.childObjects.length; i++){
        if ("getResult" in this.childObjects[i]){
          this.childObjects[i].getResult(resultsArray);
        }
      }
    }
    if(this.objectivesList && this.objectivesList.length > 0){
      var objectivesCopmplete = true;
      for(var i = 0; i < this.objectivesList.length; i++){  
        if(!this.objectivesList[i].optional && !this.objectivesList[i].complete){
          objectivesCopmplete = false;
        }
      }
      if(objectivesCopmplete){
        var resultString = "100;" + this.objectiveWeight;
        resultsArray.push(resultString);
      } else {
        var resultString = "0;" + this.objectiveWeight;
        resultsArray.push(resultString);      
      }
    }
  }

  function getErrors(){
    this.objectErrors = 0;
    for(var i = 0; i < this.childObjects.length; i++){
      if (!("getErrors" in this.childObjects[i]))
        continue;
      this.objectErrors += this.childObjects[i].getErrors();
    }

    return this.objectErrors;
  }

  function getHelps(){
    this.objectHelps = 0;
    for(var i = 0; i < this.childObjects.length; i++){
      if (!("getHelps" in this.childObjects[i]))
        continue;
      this.objectHelps += this.childObjects[i].getHelps();
    }

    return this.objectHelps;
  }
  
  function countObjectResult(results, crAlg, message){
    var cr;
    
    cr = new Composition();
    cr._class = "rnmc_CRAlgorithms";
    cr.parent = this;
    
    cr.CountingResults(results, crAlg, message);
    
//trace("Object result is counted.");
  }

  function checkObject(){
    if (this.childObjects){
      for(var i = 0; i < this.childObjects.length; i++){
        if(!this.childObjects[i].disabled)
          this.childObjects[i].checkObject();
      }
    }
    
    this.check_ib_is_true = true;
        
    for(var i = this.childObjects.length-1; i >= 0; i--){
      if(this.childObjects[i].type == "rnmc_stdInputEx"){
      
        if (this.checkModeAfter == CHECK_MODE_AFTER_READ_ONLY && 
            this.childObjects[i].setReadOnly){
          this.childObjects[i].setReadOnly(true);
        }
        
        if (!this.childObjects[i].check_res_is_true){
          this.check_ib_is_true = false;
          
          if (this.checkModeAfter == CHECK_MODE_AFTER_WRITE){
            if (this.childObjects[i].isTestObject != null && 
                this.childObjects[i].isTestObject() == true &&
                this.childObjects[i].OnSetFocus != null){
              setFocus(this.childObjects[i].objectContent);
            }
          }
            
          //break;
        }
      }
    }
    
    if(this.check_ib_is_true && rnmc_stdMediaObject_checkActions(EVENT_INPUTBOX_ON_ALL_COMPLETE)){
      rnmc_stdMediaObject_applyActions(EVENT_INPUTBOX_ON_ALL_COMPLETE);
    }
    if(!this.check_ib_is_true && rnmc_stdMediaObject_checkActions(EVENT_INPUTBOX_ON_ALL_WRONG)){
      rnmc_stdMediaObject_applyActions(EVENT_INPUTBOX_ON_ALL_WRONG);
    }
  }
  
  function onTimeout(timer_id){
    // Прокинем сообщение по дочерним элементам
    if (this.childObjects && this.childObjects.length > 0){
      for (var i = 0; i < this.childObjects.length; ++i){
        if ("onTimeout" in this.childObjects[i]){
          this.childObjects[i].onTimeout(timer_id);
        }
      }
    }
    
    // а тут сидит основной обработчик
    rnmc_stdMediaObject_onTimeout(timer_id);
  }
]]></script>
</composition>
</rmml>
