<?xml version="1.0" encoding="UTF-8"?>
<rmml>
<!--
$RCSfile: rnmc_labwork_research.xml,v $
$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_labwork_research" class="rnmc_labwork_base">
<script><![CDATA[
	this.onAllZonesVisitedActions = null;
	this.stepResult = 0;

//	
	this.visitedEvent = EVENT_ON_PRESS;
	
	function loadStep(srcNode){
		var xmlNode = null;
		var xmlAttributeMap = null;
		var xmlAttribute = null;

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

		xmlNode = srcNode.firstChild;
		while(xmlNode){
			if(xmlNode.nodeName == "settings"){
				// разбор стандартных настроек
				this.parseSettingsNode(xmlNode);
				var settingNode = xmlNode.firstChild;
				// разбор специфичных настроек
				while(settingNode){
					if(settingNode.nodeName == "zone"){
						xmlAttributeMap = settingNode.attributes;
						if (xmlAttributeMap){
							xmlAttribute = xmlAttributeMap.getNamedItem("visitedEvent");
							if (xmlAttribute != null && xmlAttribute.specified){
								switch(xmlAttribute.value){
								case "onPress":
									this.visitedEvent = EVENT_ON_PRESS;
									break;
								case "onRelease":
									this.visitedEvent = EVENT_ON_RELEASE;
									break;
								case "onRollOver":
									this.visitedEvent = EVENT_ON_ROLLOVER;
									break;
								case "onRollOut":
									this.visitedEvent = EVENT_ON_ROLLOUT;
									break;
								}
							}
						}
					};
					settingNode = settingNode.nextSibling;
				}
			} else if(xmlNode.nodeName == "actions"){
				this.onAllZonesVisitedActions =
					scene.Utils.parseActionsNode(xmlNode, "onAllZonesVisited");
				this.parseActionsNode(xmlNode);
			} else if(xmlNode.nodeName == "zone"){
				var newObject = new Composition();
				newObject._class = "research_zone";
				newObject.parent = this;
				newObject.visitedEvent = this.visitedEvent;
				if(newObject.initFromNode(xmlNode)){
					this.childObjects.push(newObject);
				} else {
					newObject.parent = null;
					newObject = null;
				}
			} else if(xmlNode.nodeName == "group"){
				var newObject = new Composition();
				newObject._class = "research_group";
				newObject.parent = this;
				if(newObject.initFromNode(xmlNode)){
					this.childObjects.push(newObject);
				} else {
					newObject.parent = null;
					newObject = null;
				}
			} else {
				var newObject = scene.Utils.initStdObjectFromNode(xmlNode, this);
				if(newObject)
					this.childObjects.push(newObject);
			}

			xmlNode = xmlNode.nextSibling;
		}
		return true;
	};
	
	function startStep(){
//trace("rnmc_labwork_research.startStep()");
		rnmc_labwork_base_startStep();
	};

	function dispatchAction(singleAction){
		rnmc_labwork_base_dispatchAction(singleAction);
	}

	function notifyZoneVisited(){
	// сообщение о том что какая то зона найдена (надо проверить найдены ли остальные)
		var totalZones = 0;
		var visitedZones = 0;
		for(var i = 0; i < this.childObjects.length; i++){
			if(this.childObjects[i].type == "research_zone"){
				if(!this.childObjects[i].optional){
					totalZones++;
					if(this.childObjects[i].visited)
						visitedZones++;
				}
			} else if(this.childObjects[i].type == "research_group"){
				totalZones += this.childObjects[i].getTotalZones();
				visitedZones += this.childObjects[i].getVisitedZones();
			}
		}
		this.stepResult = Math.round((visitedZones/totalZones)*100);
		if(visitedZones == totalZones){
			if(this.onAllZonesVisitedActions){
				for(var i = 0; i < this.onAllZonesVisitedActions.length; i++){
					this.dispatchAction(this.onAllZonesVisitedActions[i]);
				}
			}
		}
		//	Случай, когда не задана ни одна зона
		//if(zonesTotal == 0)
		//trace(this.stepResult);
	}
	
	
	//	выполняет специфичные для шаблона rnmc_labwork_research действия
	function doAction(singleAction){
		switch(singleAction[0]){
		case "markZoneVisited":
			for(var i = 0; i < this.childObjects.length; i++){
				if(this.childObjects[i].type == "research_zone"	&&
					this.childObjects[i].id == singleAction[1]){
					this.childObjects[i].visited = true;
				}
			}
			break;
		default:
			rnmc_labwork_base_doAction(singleAction);
			break;
		};
	}
	
	function getResult(resultsArray){
		if(resultsArray){
			var resultString = this.stepResult + ";1.0";
			resultsArray.push(resultString);
		}
		rnmc_stdObject_getResult(resultsArray);		
	}	
]]></script>
</composition>

<composition name="research_zone">
<script><![CDATA[
	this.type = "research_zone";
	this.id = null;
	this.visibility = OBJECT_VISIBILITY_TRUE;
	this.visited = false;
	//	событие после которго зона считается найденной
	//	допускаются следующие значения:
	//	EVENT_ON_PRESS			//	нажатие кнопки мыши
	//	EVENT_ON_RELEASE		//	отпускание кнопки мыши
	//	EVENT_ON_ROLLOVER		//	наезд на объект
	//	EVENT_ON_ROLLOUT		//	съезд с объекта
	this.visitedEvent = EVENT_ON_PRESS;

	this.optional = false;

	this.zoneHitArea = null;
	this.zoneDepth = 0;
	this.zoneX = 0;
	this.zoneY = 0;

	this.zoneObjects = null;
	this.zonePressActions = null;
	this.zoneReleaseActions = null;
	this.zoneRolloverActions = null;
	this.zoneRolloutActions = null;

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

		this.zoneObjects = 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;
			}
		}
		xmlNode = srcNode.firstChild;
		while(xmlNode){
			if(xmlNode.nodeName == "param"){
				xmlAttributeMap = xmlNode.attributes;
				if (xmlAttributeMap){
					xmlAttribute = xmlAttributeMap.getNamedItem("visitedEvent");
					if (xmlAttribute != null && xmlAttribute.specified){
						switch(xmlAttribute.value.toLowerCase()){
						case "onpress":
							this.visitedEvent = EVENT_ON_PRESS;
							break;
						case "onrelease":
							this.visitedEvent = EVENT_ON_RELEASE;
							break;
						case "onrollover":
							this.visitedEvent = EVENT_ON_ROLLOVER;
							break;
						case "onrollout":
							this.visitedEvent = EVENT_ON_ROLLOUT;
							break;
						}
					}
					xmlAttribute = xmlAttributeMap.getNamedItem("optional");
					if (xmlAttribute != null && xmlAttribute.specified){
						if(xmlAttribute.value == "true")
							this.optional = true;
						else if(xmlAttribute.value == "false")
							this.optional = false;
					}
					xmlAttribute = xmlAttributeMap.getNamedItem("depth");
					if (xmlAttribute != null && xmlAttribute.specified){
						this.zoneDepth = parseInt(xmlAttribute.value);
					};
					xmlAttribute = xmlAttributeMap.getNamedItem("x");
					if (xmlAttribute != null && xmlAttribute.specified){
						this.zoneX = parseInt(xmlAttribute.value);
					};
					xmlAttribute = xmlAttributeMap.getNamedItem("y");
					if (xmlAttribute != null && xmlAttribute.specified){
						this.zoneY = parseInt(xmlAttribute.value);
					};
				}
			} else if(xmlNode.nodeName == "area"){
				if(xmlNode.textContent){
					var newObject = new Button();
					newObject.enabled = false;
					newObject.hitArea = xmlNode.textContent;
					xmlAttributeMap = xmlNode.attributes;
					if (xmlAttributeMap){
						xmlAttribute = xmlAttributeMap.getNamedItem("x");
						if (xmlAttribute != null && xmlAttribute.specified){
							newObject.x = parseInt(xmlAttribute.value);
						};
						xmlAttribute = xmlAttributeMap.getNamedItem("y");
						if (xmlAttribute != null && xmlAttribute.specified){
							newObject.y = parseInt(xmlAttribute.value);
						};
						xmlAttribute = xmlAttributeMap.getNamedItem("depth");
						if (xmlAttribute != null && xmlAttribute.specified){
							newObject.depth = parseInt(xmlAttribute.value);
						};
					}
					newObject.parent = this;
					this.zoneObjects.push(newObject);
				}
			} else if(xmlNode.nodeName == "mask"){
				xmlAttributeMap = xmlNode.attributes;
				if (xmlAttributeMap){
					var newObject = new Image();
					newObject.visible = false;
					newObject.enabled = false;
					newObject.parent = this;
					xmlAttribute = xmlAttributeMap.getNamedItem("x");
					if (xmlAttribute != null && xmlAttribute.specified){
						newObject.x = parseInt(xmlAttribute.value);
					};
					xmlAttribute = xmlAttributeMap.getNamedItem("y");
					if (xmlAttribute != null && xmlAttribute.specified){
						newObject.y = parseInt(xmlAttribute.value);
					};
					xmlAttribute = xmlAttributeMap.getNamedItem("depth");
					if (xmlAttribute != null && xmlAttribute.specified){
						newObject.depth = parseInt(xmlAttribute.value);
					};
					xmlAttribute = xmlAttributeMap.getNamedItem("src");
					if (xmlAttribute != null && xmlAttribute.specified){
						newObject.src = xmlAttribute.value;
					};
					newObject.hitArea = "opaque";
					this.zoneObjects.push(newObject);
				}
			} else if(xmlNode.nodeName == "actions"){
				this.zonePressActions = scene.Utils.parseActionsNode(xmlNode, "onPress");
				this.zoneReleaseActions = scene.Utils.parseActionsNode(xmlNode, "onRelease");
				this.zoneRolloverActions = scene.Utils.parseActionsNode(xmlNode, "onRollOver");
				this.zoneRolloutActions = scene.Utils.parseActionsNode(xmlNode, "onRollOut");
			};
			xmlNode = xmlNode.nextSibling;
		};
		return true;
	};

	function showObject(){
		this.x = this.zoneX;
		this.y = this.zoneY;
		this.depth = this.zoneDepth;
		if(this.zoneObjects){
			for(var i = 0; i < this.zoneObjects.length; i++){
				if(this.zonePressActions && this.zonePressActions.length > 0){
					this.zoneObjects[i].onPress = function(){
						zone_onPress();
					};
				}
				if(this.zoneReleaseActions && this.zoneReleaseActions.length > 0){
					this.zoneObjects[i].onRelease = function(){
						zone_onRelease();
					};
				}
				if(this.zoneRolloverActions && this.zoneRolloverActions.length > 0){
					this.zoneObjects[i].onRollOver = function(){
						zone_onRollover();
					};
				}
				if(this.zoneRolloutActions && this.zoneRolloutActions.length > 0){
					this.zoneObjects[i].onRollOut = function(){
						zone_onRollout();
					};
				}
				this.zoneObjects[i].visible = true;
				this.zoneObjects[i].enabled = true;
			};
		}
		this.visible = true;
	}

	function hideObject(){
		if(this.zoneObjects){
			for(var i = 0; i < this.zoneObjects.length; i++){
				this.zoneObjects[i].enabled = false;
				//this.zoneObjects[i].onPress = 
				//this.zoneObjects[i].onRelease = 
				//this.zoneObjects[i].onRollOver = 
				//this.zoneObjects[i].onRollOut = 
			};
		}
		this.visible = false;
	}

//	обработчики событий
	function zone_onPress(){
		if(this.zonePressActions){
			for(var i = 0; i < this.zonePressActions.length; i++){
				parent.dispatchAction(zonePressActions[i]);
			};
		};
		if(this.visitedEvent == EVENT_ON_PRESS){
			this.visited = true;
			parent.notifyZoneVisited(this.zoneId);
		}
	};

	function zone_onRelease(){
		if(this.zoneReleaseActions){
			for(var i = 0; i < this.zoneReleaseActions.length; i++){
				parent.dispatchAction(zoneReleaseActions[i]);
			};
		};
		if(this.visitedEvent == EVENT_ON_RELEASE){
			this.visited = true;
			parent.notifyZoneVisited(this.zoneId);
		}
	};

	function zone_onRollover(){
		if(this.zone_onRollover){
			for(var i = 0; i < zoneRolloverActions.length; i++){
				parent.dispatchAction(zoneRolloverActions[i]);
			};
		};
		if(this.visitedEvent == EVENT_ON_ROLLOVER){
			this.visited = true;
			parent.notifyZoneVisited(this.zoneId);
		}
	};

	function zone_onRollout(){
		if(this.zoneRolloutActions){
			for(var i = 0; i < zoneRolloutActions.length; i++){
				parent.dispatchAction(zoneRolloutActions[i]);
			};
		};
		if(this.visitedEvent == EVENT_ON_ROLLOUT){
			this.visited = true;
			parent.notifyZoneVisited(this.zoneId);
		}
	};
]]></script>
</composition>

<composition name="research_group" class="rnmc_stdMediaGroup">
<script><![CDATA[
	this.type = "research_group"

//	перетаскиваемая
	this.draggingEnabled = false;
//	размер зоны вокруг точки нажатия кнопки мыши 
//	при выходе из которой начинается таскание группы
	this.dragSensitivity = 10;
//	для таскания

//	атрибуты таскания объекта
	this.draggingMinXBound = 0;
	this.draggingMaxXBound = 0;
	this.draggingMinYBound = 0;
	this.draggingMaxYBound = 0;
	this.objectCaptured = false;
	this.draggingXOffset = 0;
	this.draggingYOffset = 0;

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

		rnmc_stdMediaGroup_initFromNode(srcNode);
		if(!this.childObjects)
			this.childObjects = new Array();

		xmlNode = srcNode.firstChild;
		while(xmlNode){
			if(xmlNode.nodeName == "param"){
				xmlAttributeMap = xmlNode.attributes;
				if (xmlAttributeMap){
					xmlAttribute = xmlAttributeMap.getNamedItem("draggable");
					if (xmlAttribute != null && xmlAttribute.specified
						&& xmlAttribute.value.toLowerCase() == "true"){
						this.draggingEnabled = true;
					};
					xmlAttribute = xmlAttributeMap.getNamedItem("dragSensitivity");
					if (xmlAttribute != null && xmlAttribute.specified){
						this.dragSensitivity = parseInt(xmlAttribute.value);
					};
					xmlAttribute =  xmlAttributeMap.getNamedItem("xMinBound");
					if (xmlAttribute != null && xmlAttribute.specified){
						this.draggingMinXBound = parseInt(xmlAttribute.value);
					}
					xmlAttribute =  xmlAttributeMap.getNamedItem("xMaxBound");
					if (xmlAttribute != null && xmlAttribute.specified){
						this.draggingMaxXBound = parseInt(xmlAttribute.value);
					}
					xmlAttribute =  xmlAttributeMap.getNamedItem("yMinBound");
					if (xmlAttribute != null && xmlAttribute.specified){
						this.draggingMinYBound = parseInt(xmlAttribute.value);
					}
					xmlAttribute =  xmlAttributeMap.getNamedItem("yMaxBound");
					if (xmlAttribute != null && xmlAttribute.specified){
						this.draggingMaxYBound = parseInt(xmlAttribute.value);
					}
				}
			} else if(xmlNode.nodeName == "zone"){
				var newObject = new Composition();
				newObject._class = "research_zone";
				newObject.parent = this;
				if(newObject.initFromNode(xmlNode)){
					//	устанавливаем признак того что в данной группе есть зоны
					 //	(для облегчения подсчёта результатов)
					this.hasChildZones = true;
					this.childObjects.push(newObject);
				} else {
					newObject.parent = null;
					newObject = null;
				}
			}
			xmlNode = xmlNode.nextSibling;
		}
		return true;
	};

	function showObject(){
//trace("research_group.showObject()");
		rnmc_stdMediaGroup_showObject();
		if(this.draggingEnabled){
			if(this.draggingMaxXBound - this.draggingMinXBound < this.width){
				trace("#FF0000Ошибка - границы таскания для объекта " + this.id + " заданы неверно.");
				if(this.width >= 1024){
					this.draggingMinXBound = 1024 - this.width;
					this.draggingMaxXBound = 0;
				} else {
					this.draggingMinXBound = 0;
					this.draggingMaxXBound =  1024 - this.width
				}
			}
			if(this.draggingMaxYBound - this.draggingMinYBound < this.height){
				trace("#FF0000Ошибка - границы таскания для объекта " + this.id + " заданы неверно.");
				if(this.height >= 600){
					this.draggingMinYBound = 600 - this.height;
					this.draggingMaxYBound = 0;
				} else {
					this.draggingMinYBound = 0;
					this.draggingMaxYBound = this.height - 600;
				}
			}
			if(this.x < this.draggingMinXBound){
				this.x = this.draggingMinXBound;
			} else if(this.x > this.draggingMaxXBound){
				this.x = this.draggingMaxXBound;
			}
			if(this.y < this.draggingMinYBound){
				this.y = this.draggingMinYBound;
			} else if(this.y > this.draggingMaxYBound){
				this.y = this.draggingMaxYBound;
			}
			
			this.onRelease = releaseHandler;
			this.onReleaseOutside = releaseHandler;
			this.onPress = pressHandler;
		}
	}

	function hideObject(){
		rnmc_stdMediaGroup_hideObject();
	}

	function getTotalZones(){
		var totalZones = 0;
		for(var i = 0; i < this.childObjects.length; i++){
			if(this.childObjects[i].type == "research_zone"){
				if(!this.childObjects[i].optional){
					totalZones++;
				}
			} else if(this.childObjects[i].type == "research_group"){
				totalZones += this.childObjects[i].getTotalZones();
			}
		}
		return totalZones;
	}

	function getVisitedZones(){
		var visitedZones = 0;
		for(var i = 0; i < this.childObjects.length; i++){
			if(this.childObjects[i].type == "research_zone"){
				if(!this.childObjects[i].optional && this.childObjects[i].visited)
						visitedZones++;
			} else if(this.childObjects[i].type == "research_group"){
				visitedZones += this.childObjects[i].getVisitedZones();
			}
		}
		return visitedZones;
	}

	function notifyZoneVisited(){
		parent.notifyZoneVisited();
	}

	function pressHandler(){
//trace("group.press");
		if(Mouse.target && Mouse.target.onPress){
			Mouse.target.onPress();
		}
		this.mouseStartX = Mouse.x;
		this.mouseStartY = Mouse.y;
		this.onMouseMove = mouseMoveHandler;
			
		if(this.width > Player.module.scenes.width){
			this.lowXBound = Player.module.scenes.width - this.width;
			this.upXBound = this.width;
		} else {
			this.lowXBound = 0;
			this.upXBound = Player.module.scenes.width;
		};
		if(this.height > Player.module.scenes.height){
			this.lowYBound = Player.module.scenes.height - this.height;
			this.upYBound = this.height;
		} else {
			this.lowYBound = 0;
			this.upYBound = Player.module.scenes.height;
		};
	};

	function releaseHandler(){
		if(!this.objectCaptured){
			if(Mouse.target.onRelease)
				Mouse.target.onRelease();
		}
		this.onMouseMove = null;
		this.objectCaptured = false;
	};

	function mouseMoveHandler(){
		if(!this.objectCaptured){
			if(Math.abs(Mouse.x - this.mouseStartX) >= this.dragSensitivity
				|| Math.abs(Mouse.y - this.mouseStartY) >= this.dragSensitivity ){
				this.objectCaptured = true;
				this.draggingXOffset = this.xMouse;
				this.draggingYOffset = this.yMouse;
			}
		} else {
			var newX = this.x + (this.xMouse - this.draggingXOffset);
			var newY = this.y + (this.yMouse - this.draggingYOffset);

			if(newX <= this.draggingMinXBound)
				newX = this.draggingMinXBound;
			else if(newX  >= this.draggingMaxXBound)
				newX = this.draggingMaxXBound;

			if(newY < this.draggingMinYBound)
				newY = this.draggingMinYBound;
			else if(newY  > this.draggingMaxYBound)
				newY = this.draggingMaxYBound;
			this.x = newX;
			this.y = newY;
		};
	};
	
//	выполняет специфичные для шаблона rnmc_labwork_research действия
	function doAction(singleAction){
		switch(singleAction[0]){
		case "markZoneVisited":
			for(var i = 0; i < this.childObjects.length; i++){
				if(this.childObjects[i].type == "research_zone"	&&
					this.childObjects[i].id == singleAction[1]){
					this.childObjects[i].visited = true;
				}
			}
			break;
		default:
			rnmc_stdMediaGroup_doAction(singleAction);
			break;
		};
	}
	
]]></script>
</composition>
</rmml>