<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="calculator.css" type="text/css"?>
<html:html xmlns="http://www.w3.org/2002/xforms/cr" xmlns:xforms="http://www.w3.org/2002/xforms/cr" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:internal="http://www.novell.com/calculator" xml:lang="en" xmlns:html="http://www.w3.org/1999/xhtml">
	<!-- Do some styling of the output -->
	<html:head>
	<html:title>Calculator</html:title>
	<!-- 
      The calculators state
    -->
	<model id="CalculatorModel" xmlns="http://www.w3.org/2002/xforms/cr">
		<instance>
			<calculator xmlns="http://www.novell.com/calculator">
				<!-- The first operand -->
				<r1>0</r1>
				<!-- The second operand -->
				<r2/>
				<!-- The memory register -->
				<mr/>
				<!-- Should r1 on next press -->
				<clear>false</clear>
				<!-- Store the type of operand 
             0 - equals
             1 - add
             2 - subtract
             3 - multiply
             4 - divide
          -->
				<operand/>
				<!-- place holders for parameter passings.
               p1 argument 1
               p2 argument 2
               ...
               
               This could also be a stack, but manipulating
               the stack would require a recalculate of the
               dependency graph for each operation (pop, push)
               which would affect performance.
          -->
				<p1/>
				<p2/>
				<p3/>
				<p4/>
				<p5/>
			</calculator>
		</instance>
		<!-- Appends a number to the current number. If an operand was pressed
           just before this then clear the number and start on a new number.
           
           p1 holds the number to insert
       -->
		<action ev:event="novell-insert-ciffer">
			<setvalue ref="/internal:calculator/internal:r1" value="
          number(
            if(boolean-from-string(/internal:calculator/internal:clear),
                      /internal:calculator/internal:p1,
                      concat(/internal:calculator/internal:r1, /internal:calculator/internal:p1)
                     )
          )"/>
			<setvalue ref="/internal:calculator/internal:clear">false</setvalue>
		</action>
		<!-- Sets the current operand 
           p1 holds the operand, see the instance for explanation of types
      -->
		<action ev:event="novell-operand">
			<!-- Makes sure two operands in a row will not perform an actual operation. E.g.
             12 ++ will not evaluate r1 to 24
        -->
			<setvalue ref="/internal:calculator/internal:operand" value="if(boolean-from-string(/internal:calculator/internal:clear),
                           string(0),
                           /internal:calculator/internal:operand
                         )
                        "/>
			<!-- Does the addition if the current operand was a + -->
			<setvalue ref="/internal:calculator/internal:r1" value="
                    number(
                      if( number(/internal:calculator/internal:operand) = 1,
                        string( number(/internal:calculator/internal:r2)+number(/internal:calculator/internal:r1)),
                        /internal:calculator/internal:r1
                      )
                    )"/>
			<!-- Does the subtraction if the current operand was a - -->
			<setvalue ref="/internal:calculator/internal:r1" value="
                    number(
                      if( number(/internal:calculator/internal:operand) = 2,
                        string( number(/internal:calculator/internal:r2)-number(/internal:calculator/internal:r1)),
                        /internal:calculator/internal:r1
                      )
                    )"/>
			<!-- Does the multiplication if the current operand was a * -->
			<setvalue ref="/internal:calculator/internal:r1" value="
                    number(
                      if( number(/internal:calculator/internal:operand) = 3,
                        string( number(/internal:calculator/internal:r2)*number(/internal:calculator/internal:r1)),
                        /internal:calculator/internal:r1
                      )
                    )"/>
			<!-- Does the division if the current operand was a / -->
			<setvalue ref="/internal:calculator/internal:r1" value="
                    number(
                      if( number(/internal:calculator/internal:operand) = 4,
                        string( number(/internal:calculator/internal:r2) div number(/internal:calculator/internal:r1)),
                        /internal:calculator/internal:r1
                      )
                    )"/>
			<!-- Moves the current r1 to r2 -->
			<setvalue ref="/internal:calculator/internal:r2" value="/internal:calculator/internal:r1"/>
			<!-- Sets the operand for the next operation -->
			<setvalue ref="/internal:calculator/internal:operand" value="/internal:calculator/internal:p1"/>
			<!-- Sets the marker flag -->
			<setvalue ref="/internal:calculator/internal:clear">true</setvalue>
		</action>
		<!-- Stores r1 in the memory -->
		<action ev:event="novell-store">
			<setvalue ref="/internal:calculator/internal:p1">0</setvalue>
			<dispatch target="CalculatorModel" name="novell-operand"/>
			<setvalue ref="/internal:calculator/internal:mr" value="/internal:calculator/internal:r1"/>
		</action>
		<!-- Gets the memory number -->
		<action ev:event="novell-get">
			<setvalue ref="/internal:calculator/internal:r1" value="/internal:calculator/internal:mr"/>
			<!-- The flag is clear because getting the number into r1 is just like a key press -->
			<setvalue ref="/internal:calculator/internal:clear">false</setvalue>
		</action>
		<!-- Clear the state of the calculator -->
		<action ev:event="novell-clear-calculator">
			<setvalue ref="/internal:calculator/internal:r1">0</setvalue>
			<setvalue ref="/internal:calculator/internal:r2">0</setvalue>
			<setvalue ref="/internal:calculator/internal:clear">false</setvalue>
			<setvalue ref="/internal:calculator/internal:operand">0</setvalue>
			<setvalue ref="/internal:calculator/internal:mr" value="if(boolean-from-string(/internal:calculator/internal:p1),
                           string(0),
                           /internal:calculator/internal:mr
                         )"/>
		</action>
		<!-- Initialize the calculator -->
		<action ev:event="xforms-initialize-done">
			<setvalue ref="/internal:calculator/internal:p1">true</setvalue>
			<dispatch target="CalculatorModel" name="novell-clear-calculator"/>
		</action>
	</model>
</html:head>
<html:body>
	<!-- The UI -->
	<group ref="/internal:calculator" xmlns="http://www.w3.org/2002/xforms/cr">
		<output ref="internal:r1" class="outputwindow"/>
	</group>
	<group ref="/internal:calculator" xmlns="http://www.w3.org/2002/xforms/cr">
		<trigger class="function">
			<label>C</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">false</setvalue>
				<dispatch target="CalculatorModel" name="novell-clear-calculator"/>
			</action>
		</trigger>
		<trigger class="function">
			<label>CR</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">true</setvalue>
				<dispatch target="CalculatorModel" name="novell-clear-calculator"/>
			</action>
		</trigger>
		<trigger class="function">
			<label>MS</label>
			<dispatch target="CalculatorModel" name="novell-store" ev:event="xforms-activate"/>
		</trigger>
		<trigger class="function">
			<label>MG</label>
			<dispatch target="CalculatorModel" name="novell-get" ev:event="xforms-activate"/>
		</trigger>
	</group>
	<group ref="/internal:calculator" xmlns="http://www.w3.org/2002/xforms/cr">
		<trigger class="number">
			<label>7</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">7</setvalue>
				<dispatch target="CalculatorModel" name="novell-insert-ciffer"/>
			</action>
		</trigger>
		<trigger class="number">
			<label>8</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">8</setvalue>
				<dispatch target="CalculatorModel" name="novell-insert-ciffer"/>
			</action>
		</trigger>
		<trigger class="number">
			<label>9</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">9</setvalue>
				<dispatch target="CalculatorModel" name="novell-insert-ciffer"/>
			</action>
		</trigger>
		<trigger class="operator">
			<label>+</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">1</setvalue>
				<dispatch target="CalculatorModel" name="novell-operand"/>
			</action>
		</trigger>
	</group>
	<group ref="/internal:calculator" xmlns="http://www.w3.org/2002/xforms/cr">
		<trigger class="number">
			<label>4</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">4</setvalue>
				<dispatch target="CalculatorModel" name="novell-insert-ciffer"/>
			</action>
		</trigger>
		<trigger class="number">
			<label>5</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">5</setvalue>
				<dispatch target="CalculatorModel" name="novell-insert-ciffer"/>
			</action>
		</trigger>
		<trigger class="number">
			<label>6</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">6</setvalue>
				<dispatch target="CalculatorModel" name="novell-insert-ciffer"/>
			</action>
		</trigger>
		<trigger class="operator">
			<label>-</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">2</setvalue>
				<dispatch target="CalculatorModel" name="novell-operand"/>
			</action>
		</trigger>
	</group>
	<group ref="/internal:calculator" xmlns="http://www.w3.org/2002/xforms/cr">
		<trigger class="number">
			<label>1</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">1</setvalue>
				<dispatch target="CalculatorModel" name="novell-insert-ciffer"/>
			</action>
		</trigger>
		<trigger class="number">
			<label>2</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">2</setvalue>
				<dispatch target="CalculatorModel" name="novell-insert-ciffer"/>
			</action>
		</trigger>
		<trigger class="number">
			<label>3</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">3</setvalue>
				<dispatch target="CalculatorModel" name="novell-insert-ciffer"/>
			</action>
		</trigger>
		<trigger class="operator">
			<label>*</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">3</setvalue>
				<dispatch target="CalculatorModel" name="novell-operand"/>
			</action>
		</trigger>
	</group>
	<group ref="/internal:calculator" xmlns="http://www.w3.org/2002/xforms/cr">
		<trigger class="number" id="zero">
			<label>0</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">0</setvalue>
				<dispatch target="CalculatorModel" name="novell-insert-ciffer"/>
			</action>
		</trigger>
		<trigger class="operator">
			<label>=</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">0</setvalue>
				<dispatch target="CalculatorModel" name="novell-operand"/>
			</action>
		</trigger>
		<trigger class="operator">
			<label>/</label>
			<action ev:event="xforms-activate">
				<setvalue ref="internal:p1">4</setvalue>
				<dispatch target="CalculatorModel" name="novell-operand"/>
			</action>
		</trigger>
	</group>
</html:body>
</html:html>

