<?xml version="1.0" encoding="UTF-8"?>
<rmml>
<!--
$RCSfile: rnmc_stdTimer.xml $
$Revision: 957 $

last change: $Date: 2009-02-17 14:00:06 +0300 (Вт, 17 фев 2009) $
             $Author: toha $

	Lacerta Project
	version 1.0.0.1
	Copyright (C) 2007-2009 RNMC
-->
<composition name="rnmc_stdTimer">
<sequencer name="updateSequencer" playing="false" loop="true">
<script>
	updateTimer();
</script>
</sequencer>
<script><![CDATA[
	this.id = null;
	this.visibility = OBJECT_VISIBILITY_TRUE;
	this.objectPlaying = OBJECT_PLAYING_UNDEFINED;

//
	this.timeOut = 0;
	this.timerVisible = false;
	this.timerX = 0;
	this.timerY = 0;
	this.timerDepth = 0;
	this.timerStyle = null;
	this.timerPanelFormat = null;//"%elapsed%";
	this.timeFormat = "MM:SS";

	this.timerPanel = null;
	this.playStart = 0;
	this.playTime = 0;
	this.currentTime = 0;
	this.lastTimerValue = 0;

	this.onStartTimerActions = null;
	this.onTimeOutActions = null;

	this.timerCallBackObject = null;
	this.timerCallBackFunction = null;
  
  // тут хранятся объекты, которым следцет отправить оповещение 
  // о истекшем времен
  this.bindObjects = null;

	function initFromNode(srcNode){
		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("playing");
			if (xmlAttribute != null && xmlAttribute.specified
				&& xmlAttribute.value == "true"){
				this.objectPlaying = OBJECT_PLAYING_TRUE;
			} else {
				this.objectPlaying = OBJECT_PLAYING_FALSE;
			}
			
		// Для совместимости со старым синтаксисом
			xmlAttribute =  xmlAttributeMap.getNamedItem("x");
			if (xmlAttribute != null && xmlAttribute.specified)
				this.timerX = parseInt(xmlAttribute.value);
			xmlAttribute =  xmlAttributeMap.getNamedItem("y");
			if (xmlAttribute != null && xmlAttribute.specified)
				this.timerY = parseInt(xmlAttribute.value);
			xmlAttribute =  xmlAttributeMap.getNamedItem("width");
			if (xmlAttribute != null && xmlAttribute.specified)
				this.objectWidth = parseInt(xmlAttribute.value);
			xmlAttribute =  xmlAttributeMap.getNamedItem("height");
			if (xmlAttribute != null && xmlAttribute.specified)
				this.objectHeight = parseInt(xmlAttribute.value);				
			xmlAttribute =  xmlAttributeMap.getNamedItem("style");
			if (xmlAttribute != null && xmlAttribute.specified)
				this.timerStyle = xmlAttribute.value;
			xmlAttribute =  xmlAttributeMap.getNamedItem("format");
			if (xmlAttribute != null && xmlAttribute.specified
				&& this.timerPanelFormat == null)
				this.timerPanelFormat = xmlAttribute.value;
		}
		xmlNode = srcNode.firstChild;
		while(xmlNode){
			if(xmlNode.nodeName == "param"){
				xmlAttributeMap = xmlNode.attributes;
				if(xmlAttributeMap){
					xmlAttribute =  xmlAttributeMap.getNamedItem("display");
					if (xmlAttribute != null && xmlAttribute.specified)
						if ((xmlAttribute.value).toLowerCase() == "true")
							this.timerVisible = true;
						else
							this.timerVisible = false;
					xmlAttribute =  xmlAttributeMap.getNamedItem("timeout");
					if (xmlAttribute != null && xmlAttribute.specified)
						this.timeOut = parseInt((xmlAttribute.value)*1000);
					xmlAttribute =  xmlAttributeMap.getNamedItem("x");
					if (xmlAttribute != null && xmlAttribute.specified)
						this.timerX = parseInt(xmlAttribute.value);
					xmlAttribute =  xmlAttributeMap.getNamedItem("y");
					if (xmlAttribute != null && xmlAttribute.specified)
						this.timerY = parseInt(xmlAttribute.value);
					xmlAttribute =  xmlAttributeMap.getNamedItem("depth");
					if (xmlAttribute != null && xmlAttribute.specified)
						this.timerDepth = parseInt(xmlAttribute.value);
					xmlAttribute =  xmlAttributeMap.getNamedItem("style");
					if (xmlAttribute != null && xmlAttribute.specified)
						this.timerStyle = xmlAttribute.value;
					xmlAttribute =  xmlAttributeMap.getNamedItem("format");
					if (xmlAttribute != null && xmlAttribute.specified
						&& this.timerPanelFormat == null)
						this.timerPanelFormat = xmlAttribute.value;
					xmlAttribute =  xmlAttributeMap.getNamedItem("timeFormat");
					if (xmlAttribute != null && xmlAttribute.specified)
						this.timeFormat = xmlAttribute.value;
				}
			} else if(xmlNode.nodeName == "actions"){
				this.onStartTimerActions = scene.Utils.parseActionsNode(xmlNode, "onStartTimer");
				this.onTimeOutActions = scene.Utils.parseActionsNode(xmlNode, "onTimeOut");
			} else if(xmlNode.nodeName == "bind" && xmlNode.textContent){
        this.bindObjects = this.parseBind(xmlNode.textContent);
			} else if(xmlNode.nodeName == "format"){
			// Нужно доделать обработчик
				if(xmlNode.textContent){
					this.timerPanelFormat = xmlNode.textContent;
				}
			}
			xmlNode = xmlNode.nextSibling;
		}

		if (this.timerPanelFormat == null)
			this.timerPanelFormat = "%elapsed%";

		return true;
	}

	function showObject(){
//trace("rnmc_stdTimer.showObject()");
		if(this.timerVisible){		//	если нужна визуализация
			if(!this.timerPanel){
				this.timerPanel = new Text();
				this.timerPanel.parent = this;
			}
			if(this.timerStyle){
				if (scene.StyleManager.styleExists(this.timerStyle))
					this.timerPanel.style = this.timerStyle;
			}
			this.timerPanel.x = this.timerX;
			this.timerPanel.y = this.timerY;
			this.timerPanel.visible = true;
			this.visible = true;
			this.depth = this.timerDepth;
		}
		if(this.objectPlaying == OBJECT_PLAYING_TRUE){
			this.startTimer();
		}
	}

	function hideObject(){
		if(this.timerPanel){
			this.timerPanel.parent = null;
			this.timerPanel = null;
		}
		this.visible = false;
	}

	function playObject(){
		startTimer();
	}

	function pauseObject(){
		stopTimer();
	}

	function stopObject(){
		stopTimer();
		resetTimer();
	}

	function startTimer(){
		this.playStart = Player._time;
		if(this.onStartTimerActions){
			for(var i = 0; i < this.onStartTimerActions.length; i++){
				parent.dispatchAction(this.onStartTimerActions[i]);
			}
		}
		//this.lastTimerValue = parseInt(((Player._time - this.playStart) + this.playTime)/1000);
		updateTimerPanel();
		if(((Player._time - this.playStart) + this.playTime) < this.timeOut){
			this.updateSequencer.playing = true;
		}
	}

	function stopTimer(){
		updateSequencer.playing = false;
		if(this.playStart > 0){
			this.playTime += (Player._time - this.playStart);
		}
	}

	function resetTimer(){
		updateSequencer.playing = false;
		//this.currentTime = 0;
		this.playStart = 0;
		this.playTime = 0;
	}

	function updateTimer(){
		var newTime = parseInt(((Player._time - this.playStart) + this.playTime)/1000);
		if (newTime != this.lastTimerValue){
			this.lastTimerValue = newTime;
			updateTimerPanel();
		}
		if(this.timeOut > 0){
			if (((Player._time - this.playStart) + this.playTime) >= this.timeOut){
				updateSequencer.playing = false;
//				this.currentTime = parseInt(this.timeOut/1000);
				updateTimerPanel();
				if(this.onTimeOutActions){
					for(var i = 0; i < this.onTimeOutActions.length; i++){
						parent.dispatchAction(this.onTimeOutActions[i]);
					}
				}
				if(this.timerCallBackFunction != null && this.timerCallBackObject != null){
					this.timerCallBackFunction.call(this.timerCallBackObject, this.id);
				}
        if (this.bindObjects && this.bindObjects.length > 0){
          this.doActionBinds(this.bindObjects);
        }
			}
		}
	}

	function updateTimerPanel(){
		if(this.timerVisible && this.timerPanel){
			var formatString = this.timerPanelFormat;
			if(this.timeOut){
				var re = new RegExp("(%total%)", "g");
				formatString = formatString.replace(re,
					scene.Utils.translateSecondsToTimeFormat(parseInt(this.timeOut/1000), this.timeFormat));
			}
			re = new RegExp("(%elapsed%)", "g");
			formatString = formatString.replace(re,
				scene.Utils.translateSecondsToTimeFormat(this.lastTimerValue, this.timeFormat));
			if(this.timeOut){
				re = new RegExp("(%remaining%)", "g");
				formatString = formatString.replace(re,
					scene.Utils.translateSecondsToTimeFormat(parseInt(this.timeOut/1000) - this.lastTimerValue, this.timeFormat));
			}
			this.timerPanel.value = formatString;
		}
	}

	function setTimeoutCallback(pointerToObject, callbackFunction){
		this.timerCallBackObject = pointerToObject;
		this.timerCallBackFunction = callbackFunction;
	}

	function setDisplayParams(newVisible, newX, newY, newDepth, newStyle, newPanelFormat, newTimeFormat){
		if(newVisible != undefined)
			this.timerVisible = newVisible;
		if(newX != undefined)
			this.timerX = newX;
		if(newY != undefined)
			this.timerY = newY;
		if(newDepth != undefined)
			this.timerDepth = newDepth;
		if(newStyle != undefined)
			this.timerStyle = newStyle;
		if(newPanelFormat != undefined)
			this.timerPanelFormat = newPanelFormat;
		if(newTimeFormat != undefined)
			this.timeFormat = newTimeFormat;
	}

//	
	function setCurrentTime(currentTime, /*optional*/ totalTime){
		if(currentTime != undefined)
			this.lastTimerValue = parseInt(currentTime);
		if(totalTime != undefined)
			this.timeOut = parseInt(totalTime) * 1000;
		this.updateTimerPanel();
	}
  
  function parseBind(strValue){
    var str = "";
    var ret_objs = new Array();
    
    if (!strValue || strValue == "")
      return ret_objs;
      
    var objs = strValue.split(";");
    
    if (objs && objs.length > 0){
      for (var i = 0; i < objs.length; ++i){
        str = objs[i];
        if (str != "" && str.search(/^(\.\.)/) != -1){
        // ищем объект у родителя
          // убираем ".."
          str = str.replace(/^(\.\.)/, "");
          // убираем все пробелы
          str = str.replace(/\s+/g, "");
          var childs = str.split(".");
          
          var f_objs = {type: "parent", objs: childs}
          
          ret_objs.push(f_objs);
        }else if (str != "" && str.search(/^(\.)/) != -1){
        // ищем объект у себя
          // убираем "."
          str = str.slice(1);
          // убираем все пробелы
          str = str.replace(/\s+/g, "");
          var childs = str.split(".");
          
          var f_objs = {type: "current", objs: childs}
          
          ret_objs.push(f_objs);
        }else if (str != ""){
        // ищем объект c корня сцены
          // убираем все пробелы
          str = str.replace(/\s+/g, "");
          var childs = str.split(".");
          
          var f_objs = {type: "step", objs: childs}
          
          ret_objs.push(f_objs);
        }
      }
    }
    
    return ret_objs;
  }
  
  function doActionBinds(bindObjs){
    for (var i = 0; i < bindObjs.length; ++i){
      var childs = bindObjs[i].objs;
      
      if (childs && childs.length > 0){
        var parent_obj = null;
        var find_obj = null;
        
        switch (bindObjs[i].type){
          case "parent":
            parent_obj = this.parent;
            break;
          case "step":
            parent_obj = scene.Labwork.currentStep;
            break;
          case "current":
            parent_obj = this;
            break;
        }
        
        for (var j = 0; j < childs.length; ++j){
          if (find_obj)
            parent_obj = find_obj;
            
          if (!parent_obj)
            break;
            
          if ("getChildObject" in parent_obj){
            objs_ret = parent_obj.getChildObject(childs[j]);
            find_obj = objs_ret;
          }else{
            find_obj = null;
            break;
          }
        }
        
        if (find_obj){
          if ("onTimeout" in find_obj){
            find_obj.onTimeout(this.id);
          }
        }
      }
    }
  }
]]></script>
</composition>
</rmml>