<?xml version="1.0" encoding="UTF-8"?>
<otrunk id="16ec64ba-d49b-4746-ae57-cb01528117f5">
  <imports>
    <import class="org.concord.data.state.OTDataStore" />
    <import class="org.concord.data.state.OTDataChannelDescription" />
    <import class="org.concord.data.state.OTDataField" />
    <import class="org.concord.data.state.OTDataTable" />
    <import class="org.concord.datagraph.state.OTDataGraph" />
    <import class="org.concord.datagraph.state.OTDataAxis" />
    <import class="org.concord.datagraph.state.OTDataGraphable" />
    <import class="org.concord.datagraph.state.OTDataCollector" />
    <import class="org.concord.datagraph.state.OTMultiDataGraph" />
    <import class="org.concord.datagraph.state.OTPluginView" />
    <import class="org.concord.datagraph.state.OTDataBarGraphable" />
    <import class="org.concord.otrunk.OTIncludeRootObject" />
    <import class="org.concord.otrunk.OTInclude" />
    <import class="org.concord.otrunk.OTSystem" />
    <import class="org.concord.otrunk.biologica.OTOrganismPlacement" />
    <import class="org.concord.otrunk.biologica.OTEnvironment" />
    <import class="org.concord.otrunk.biologica.OTOrganism" />
    <import class="org.concord.otrunk.biologica.OTWorld" />
    <import class="org.concord.otrunk.biologica.agent.OTAgentSpecies" />
    <import class="org.concord.otrunk.biologica.agent.OTAgentTrait" />
    <import class="org.concord.otrunk.biologica.agent.OTAgentPropertyImageMap" />
    <import class="org.concord.otrunk.biologica.environment.OTAddAgentButton" />
    <import class="org.concord.otrunk.biologica.environment.OTEnvironmentHolder" />
    <import class="org.concord.otrunk.biologica.data.OTBiologicaModelDataProducer" />
    <import class="org.concord.otrunk.biologica.rules.OTRule" />
    <import class="org.concord.otrunk.biologica.rules.OTRuleCondition" />
    <import class="org.concord.otrunk.biologica.rules.OTRuleConsequence" />
    <import class="org.concord.otrunk.ui.OTCurriculumUnit" />
    <import class="org.concord.otrunk.ui.OTPlacement" />
    <import class="org.concord.otrunk.ui.snapshot.OTSnapshot" />
    <import class="org.concord.otrunk.ui.snapshot.OTSnapshotButton" />
    <import class="org.concord.otrunk.ui.snapshot.OTSnapshotAlbum" />
    <import class="org.concord.otrunk.ui.snapshot.OTSnapshotChooser" />
    <import class="org.concord.otrunk.view.OTViewEntry" />
    <import class="org.concord.otrunk.view.OTViewBundle" />
    <import class="org.concord.otrunk.view.OTViewMode" />
    <import class="org.concord.otrunk.view.document.OTCompoundDoc" />
    <import class="org.concord.otrunk.script.ui.OTScriptObject" />
    <import class="org.concord.otrunk.script.js.OTJavascript" />
    <import class="org.concord.otrunk.script.OTScriptEngineBundle" />
    <import class="org.concord.otrunk.script.OTScriptEngineEntry" />
    <import class="org.concord.otrunk.script.ui.OTScriptVariable" />
    <import class="org.concord.otrunk.script.ui.OTScriptVariableComponent" />
    <import class="org.concord.otrunk.script.ui.OTScriptVariableRealObject" />
    <import class="org.concord.otrunk.script.ui.OTScriptVariableView" />
    <import class="org.concord.otrunk.script.ui.OTScriptButton" />
    <import class="org.concord.otrunk.ui.OTChoice" />
    <import class="org.concord.framework.otrunk.view.OTFrame" />
  </imports>
  <objects>
    <OTSystem>
      <bundles>
        <object refid="8d880970-c22a-11dc-95ff-0800200c9a66" />
        <OTScriptEngineBundle>
          <engines>
            <OTScriptEngineEntry objectClass="org.concord.otrunk.script.js.OTJavascript" engineClass="org.concord.otrunk.script.js.OTJavascriptEngine" />
          </engines>
        </OTScriptEngineBundle>
      </bundles>
      <includes>
        <OTInclude href="../global-imports/er-view-bundle.otml" />
        <OTInclude href="species/fast-plants.otml" />
        <OTInclude href="species/white-rabbits.otml" />
      </includes>
      <root>
        <OTCompoundDoc local_id="mountain-model">
          <bodyText>
            <table width="100%">
              <tr>
                <td>
                  <object refid="${env-holder}" />
                </td>
                <td>
                  <table>
                    <tr>
                      <td valign="top" align="right">Amount of rain</td>
                      <td align="center">
                        High
                        <br />
                        <object refid="${mountain-height-radio}" />
                        <br />
                        Low
                        <br />
                      </td>
                    </tr>
                  </table>
                </td>
                <td width="30%">
                	<object refid="${graph}"/>
                </td>
              </tr>
            </table>
            <object refid="${slider-script}" />
          </bodyText>
          <documentRefs>
          <OTDataCollector name="Model Data"
							local_id="graph" multipleGraphableEnabled="false"
							autoScaleEnabled="false" showControlBar="false">
							<source>
								<OTDataGraphable connectPoints="true"
									color="0x00aa00" drawMarks="false" name="Number of organisms"
									xColumn="0" yColumn="1">
									<dataProducer>
										<OTBiologicaModelDataProducer local_id="dp" lineGraph="true">
											<modelHolder>
                                    			<object refid="${env-holder}" />
                                  			</modelHolder>
                                  			<species>
                                  				<string>Fast Plants</string>
                                  				<string>Rabbits</string>
                                  			</species>
                                  	</OTBiologicaModelDataProducer>
									</dataProducer>
								</OTDataGraphable>
							</source>
							<graphables>
								<OTDataGraphable connectPoints="true"
									color="0xff0000" drawMarks="false" name="Temperature"
									xColumn="0" yColumn="2">
									<dataProducer>
										<object refid="${dp}" />
									</dataProducer>
								</OTDataGraphable>
							</graphables>
							<xDataAxis>
								<OTDataAxis min="0" max="30"
									label="Time" units="s" local_id="xAxis">
								</OTDataAxis>
							</xDataAxis>
							<yDataAxis>
								<OTDataAxis min="0" max="200"
									label="Number of organisms" local_id="yAxis">
								</OTDataAxis>
							</yDataAxis>
						</OTDataCollector>
             <OTEnvironmentHolder local_id="env-holder" width="640" height="460" toolbar="run,reset,info cursor" useSpeedSlider="true">
          <environment>
            <OTEnvironment local_id="environment" environmentWidth="10" environmentHeight="10" width="570" height="445" showRunButton="false" winterLength="2" summerLength="50" showWinterImage="false" orgSizeMultiplier="3.0" backgroundImageSrc="images/soil_water_level1.png">
              <world>
                <OTWorld local_id="peasimple_world" speciesPath="org/concord/biologica/worlds/peasimple.xml" />
              </world>
              <rules>
                <OTRule description="rain affects growth rate">
                  <conditions>
                    <OTRuleCondition property="species name" equals="Fast Plants"/>
                  </conditions>
                  <consequences>
                  	 rain ranges from 0.0-1.0. GR should range from 5-50. We want max CoS at rain: 0.8 
                    <OTRuleConsequence property="growth rate" ruleScript="var distFrom8 = Math.abs(0.8-rain); return 0.1 - (distFrom8  / 10)">
                      <propertyVariables>
                        <string>rain</string>
                      </propertyVariables>
                    </OTRuleConsequence>
                  </consequences>
                </OTRule>
                <OTRule description="Chance of survival is normally 1">
                  <conditions>
                    <OTRuleCondition property="last environment change" minValue="6" />
                  </conditions>
                  <consequences>
                    <OTRuleConsequence property="chance of survival" newValueFloat="1.0"/>
                  </consequences>
                </OTRule>
                <OTRule description="rain affects chance of survival briefly after env change">
                  <conditions>
                    <OTRuleCondition property="last environment change" maxValue="5" />
                  </conditions>
                  <consequences>
                  	<!-- rain ranges from 0.0-1.0. CoS should range from 0.2-1.0. We want max CoS at rain: 0.8 -->
                    <OTRuleConsequence property="chance of survival" ruleScript="var distFrom8 = Math.abs(0.8-rain); return 1 - (distFrom8 / 2)">
                      <propertyVariables>
                        <string>rain</string>
                      </propertyVariables>
                    </OTRuleConsequence>
                  </consequences>
                </OTRule>
                <!--<OTRule description="rain affects resource consumption">
                  <conditions>
                    <OTRuleCondition property="species name" equals="Fast Plants"/>
                  </conditions>
                  <consequences>
                  	 rain ranges from 0.0-1.0. RC should range between 2-20. We want max CoS at rain: 0.8 
                    <OTRuleConsequence property="resource consumption rate" ruleScript="var distFrom8 = Math.abs(0.8-rain); return 4 + (distFrom8  * 20)">
                      <propertyVariables>
                        <string>rain</string>
                      </propertyVariables>
                    </OTRuleConsequence>
                  </consequences>
                </OTRule>
                <OTRule description="rabbit resource consumption is high">
                  <conditions>
                    <OTRuleCondition property="species name" equals="Rabbits"/>
                  </conditions>
                  <consequences>
                  	<OTRuleConsequence property="resource consumption rate" newValueFloat="17" />
                  </consequences>
                </OTRule>
                <OTRule description="rabbits die earlier if low on food">
                  <conditions>
                    <OTRuleCondition property="species name" equals="Rabbits"/>
                  </conditions>
                  <consequences>
                  	<OTRuleConsequence property="metabolism" newValueFloat="5" />
                  </consequences>
                </OTRule>
                <OTRule description="rabbits are near-sighted">
                  <conditions>
                    <OTRuleCondition always="true"/>
                  </conditions>
                  <consequences>
                  	<OTRuleConsequence property="vision distance" newValueFloat="20" />
                  </consequences>
                </OTRule>
              --></rules>
            </OTEnvironment>
          </environment>
              <scripts>
               </scripts>
              <addAgentsButtons>
                <OTAddAgentButton text="Add Plant A" quantity="150" click="false" limit="150">
                  <species>
                    <object refid="9fdc762d-1011-4900-9c27-f36f923bd53e" />
                  </species>
                </OTAddAgentButton>
                <OTAddAgentButton text="Add Rabbit" quantity="10"  click="false" limit="10">
	              <species>
	                <object refid="f05fc1b1-ea0e-4d6e-a21e-7d089860445a" />
	              </species>
	            </OTAddAgentButton>
              </addAgentsButtons>
            </OTEnvironmentHolder>
            <OTScriptObject local_id="slider-script" name="Script object">
              <script>
                <OTJavascript local_id="script">
                  <script>importPackage(Packages.java.lang);
importPackage(Packages.java.net);
importPackage(Packages.java.awt.geom);
importPackage(Packages.javax.swing);
importPackage(Packages.org.concord.framework.otrunk);
importPackage(Packages.org.concord.biologica.environment);

var env = envHolder.getEnvironment()
var otEnvHolderController
var lastEnvChange = 10
var baseUrl = otEnvHolder.getOTObjectService().getCodebase(otEnvHolder)
var addedRabbits = false;
							var startTime
							var time
							var previousTime
							var shownMessage
							var currChoice
							var doneChoices
             
function init() {
	env.addChangeListener(resetListener)
	env.addStepListener(stepListener)
	
	radio.getCurrentChoices().set(0, choice_0)
	radio.addOTChangeListener(radioChangeListener)
	
	setProperty("rain", 0.0)
	setProperty("food regrowth rate", 5)
	
	currChoice = radio.getCurrentChoices().get(0)
	doneChoices = [false, false, false, false, false];
	
	setup()
}

function setup() {
	
	var url = new URL(baseUrl, "images/soil_water_level1.png")
	envHolder.getEnvironmentView().addBackgroundImageUrl(url)
	url = new URL(baseUrl, "images/soil_water_level2.png")
	envHolder.getEnvironmentView().addBackgroundImageUrl(url)
	url = new URL(baseUrl, "images/soil_water_level4.png")
	envHolder.getEnvironmentView().addBackgroundImageUrl(url)
	url = new URL(baseUrl, "images/soil_water_level7.png")
	envHolder.getEnvironmentView().addBackgroundImageUrl(url)
	url = new URL(baseUrl, "images/soil_water_level10.png")
	envHolder.getEnvironmentView().addBackgroundImageUrl(url)
	
	var lastEnvChange = 10
	setProperty("last environment change", 10)
	addedRabbits = false;
	
	time = 0
	previousTime = 0
	shownMessage = false;
}

var stepHandler = 
{
	environmentStepped: function(evt)
	{
		if (checkForExtinction()){
			return;
		}
		setMatingRate();
		
		lastEnvChange++
		if (lastEnvChange &lt; 10){
        	setProperty("last environment change", lastEnvChange)
        }
        
        updateTime();
        if (!shownMessage &amp;&amp; time &gt; 20000){
        	doneChoices[parseInt(currChoice.getName())] = true;
				
        	var doneAll = true
        	for (var i = 0; i &lt; 5; i++){
        		if (!doneChoices[i])
        			doneAll = false;
        	}
        	
        	if (doneAll){
				showMessageAndLog( "Good job! You have experimented with all five rainfall levels.\nRecord the number of plants, then go to the next page.", env, envHolder, otEnvHolder);
        		shownMessage = true;
				envHolder.pauseAction()
        	} else {
        		showMessageAndLog( "Look at the graph. Record how many plants\nthere are and record that number in the data table above.\nThen run the experiment again with a different rainfall level.", env, envHolder, otEnvHolder)
				shownMessage = true;
				envHolder.pauseAction()
			}
        }
	}
}
var stepListener = new EnvironmentStepListener(stepHandler);

function checkForExtinction()
{
	if(addedRabbits &amp;&amp; env.getAgents(rabbitspecies).size() &lt; 1) {
		doneChoices[parseInt(currChoice.getName())] = true;
		showMessageAndLog("The level of rainfall you chose did not support\nthe plants and animals living in the ecosystem.\nReset the model and try again with a different rainfall level.", env, envHolder, otEnvHolder)
		addedRabbits = false;
		envHolder.pauseAction()
		shownMessage = true;
	} else if (!addedRabbits &amp;&amp; env.getAgents(rabbitspecies).size() &gt; 0) {
		addedRabbits = true;
	}
}

function setMatingRate()
{
	var allRabbits = env.getAgents(rabbitspecies); 
	var rabbitSize = allRabbits.size();
	var matingBonus = 3;
	var wanderThreshold = 10;
	var ageLimit = 450;
	var resourceConsumption = 15;
	if (rabbitSize &lt; 11) {
		matingBonus = 15;
		wanderThreshold = 1;
		ageLimit = 10000;
		resourceConsumption = 1;
	} else if (rabbitSize &gt; 25) {
		matingBonus = -10;
		wanderThreshold = 20;
		ageLimit = 200;
	} else if (rabbitSize &gt; 20) {
		matingBonus = -3;
		wanderThreshold = 15;
	}
	
	for (var i = 0; i &lt; allRabbits.size(); i++){
		allRabbits.get(i).setProperty("mating desire bonus", new Integer(matingBonus));
		allRabbits.get(i).setProperty("wander threshold", new Integer(wanderThreshold));
		allRabbits.get(i).setProperty("age limit", new Integer(ageLimit));
		allRabbits.get(i).setProperty("resource consumption rate", new Integer(resourceConsumption));
	}
}


var radioChangeHandler =
{
    stateChanged: function(evt)
    {
    	if (radio.getCurrentChoices().size() &lt; 1)
    		return;
    	var prevrain = env.getEnvironmentUnit(0,0).getProperty("rain")
    	
        currChoice = radio.getCurrentChoices().get(0)
        var rain = currChoice.getName()
        var url
        if (rain == "0"){
        	var url = new URL(baseUrl, "images/soil_water_level1.png")
        	setProperty("food regrowth rate", 0)
        	setProperty("rain", 0.0)
        } else if (rain == "1"){
        	var url = new URL(baseUrl, "images/soil_water_level2.png")
        	setProperty("food regrowth rate", 1)
        	setProperty("rain", 0.3)
        } else if (rain == "2"){
        	var url = new URL(baseUrl, "images/soil_water_level4.png")
        	setProperty("food regrowth rate", 2)
        	setProperty("rain", 0.6)
        } else if (rain == "3"){
        	var url = new URL(baseUrl, "images/soil_water_level7.png")
        	setProperty("food regrowth rate", 3)
        	setProperty("rain", 0.8)
        } else {
        	var url = new URL(baseUrl, "images/soil_water_level10.png")
        	setProperty("food regrowth rate", 2)
        	setProperty("rain", 1.0)
        }
        envHolder.getEnvironmentView().setBackgroundImageUrl(url)
        
        var currrain = env.getEnvironmentUnit(0,0).getProperty("rain")
        if (Math.abs(0.8 - currrain) &gt; Math.abs(0.8 - prevrain) &amp;&amp; env.getAllAgents().size() &gt; 0){
        	lastEnvChange = 0
        	setProperty("last environment change", 0)
        }
        
    }

}
var radioChangeListener = new OTChangeListener(radioChangeHandler)

function setProperty(prop, val){
		for (var i = 0; i &lt; 10; i++) {
			for (var j = 0; j &lt; 10; j++) {
				env.getEnvironmentUnit(i,j).setProperty(prop, new Float(val))
			}
		}
}

var resetHandler= {
	environmentChanged: function(evt){
		if (evt.getType() == EnvironmentChangeEvent.RESET){
			setup();
		} else if (evt.getType() == EnvironmentChangeEvent.RUN){
			startTime = System.currentTimeMillis()
		} else if (evt.getType() == EnvironmentChangeEvent.PAUSE){
			previousTime = time;
		}
	}
}
			
var resetListener = new EnvironmentChangeListener(resetHandler)

function updateTime(){
	timeSinceLastStart = System.currentTimeMillis() - startTime;
	time =  previousTime + timeSinceLastStart;
}

function save() {
  if (radio != null)
    radio.removeOTChangeListener(radioChangeListener)
  return true;
}

// by putting these urls after "src" we can ensure that the installer will cache
// the images:
// src="images/mountains2flipped.jpg"
// src="images/mountains3flipped.jpg"
// src="images/mountains4flipped.jpg"
// src="images/mountains5flipped.jpg"</script>
                  <scripts>
                    <OTJavascript src="scripts/common/message.js" />
                  </scripts>
                </OTJavascript>
              </script>
              <variables>
                <OTScriptVariable name="otEnvHolder">
                  <reference>
                    <object refid="${env-holder}" />
                  </reference>
                </OTScriptVariable>
                <OTScriptVariableRealObject name="envHolder">
                  <reference>
                    <object refid="${env-holder}" />
                  </reference>
                </OTScriptVariableRealObject>
                <OTScriptVariableRealObject name="rabbitspecies">
                  <reference>
                    <object refid="f05fc1b1-ea0e-4d6e-a21e-7d089860445a" />
                  </reference>
                </OTScriptVariableRealObject>
                <OTScriptVariableRealObject name="plantspecies">
                  <reference>
                    <object refid="9fdc762d-1011-4900-9c27-f36f923bd53e" />
                  </reference>
                </OTScriptVariableRealObject>
                <OTScriptVariable name="radio">
                  <reference>
                    <object refid="${mountain-height-radio}" />
                  </reference>
                </OTScriptVariable>
                <OTScriptVariable name="choice_0">
                  <reference>
                    <object refid="f8f30d75-f5b3-4451-a1d8-76d660b77e8a" />
                  </reference>
                </OTScriptVariable>
              </variables>
            </OTScriptObject>
            <OTChoice local_id="mountain-height-radio" name="Multiple choice" horizontal="false" alignContent="0">
              <choices>
                <OTCompoundDoc name="4">
                  <bodyText>5 (Most rain)</bodyText>
                </OTCompoundDoc>
                <OTCompoundDoc name="3">
                  <bodyText>4</bodyText>
                </OTCompoundDoc>
                <OTCompoundDoc name="2">
                  <bodyText>3</bodyText>
                </OTCompoundDoc>
                <OTCompoundDoc name="1">
                  <bodyText>2</bodyText>
                </OTCompoundDoc>
                <OTCompoundDoc id="f8f30d75-f5b3-4451-a1d8-76d660b77e8a" name="0">
                  <bodyText>1 (Least rain)</bodyText>
                </OTCompoundDoc>
              </choices>
              <currentChoices>
                <object refid="f8f30d75-f5b3-4451-a1d8-76d660b77e8a" />
              </currentChoices>
            </OTChoice>
          </documentRefs>
        </OTCompoundDoc>
      </root>
    </OTSystem>
  </objects>
</otrunk>

