<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="../xsltforms/xsltforms.xsl" type="text/xsl"?>
<?xsltforms-options debug="no"?>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://www.w3.org/1999/xhtml"
      xmlns:xf="http://www.w3.org/2002/xforms"
      xmlns:ev="http://www.w3.org/2001/xml-events"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>
<head>
	<title>Open Street Map</title>

	<style type="text/css">
	  body { font-family: sans-serif; margin: 2em; width: 50em}
          pre { margin-left: 3em; background-color: #ddddFF; border: thin black solid; clear: both; padding-left: 1em }
	  label { display: inline-block; width: 3em; margin: 0 1em }
	  .br:after {content: "\A"}
          .br {display:block}
	  div.map { line-height: 0}
	  .map, .mouse {
		height: 512px; width: 512px;
		white-space: nowrap;
		overflow: hidden; 
		margin: 0;
		float: left; 
		border: 1px solid #ccc;
	  }
	  .mouse {position: relative; top: -512px} 
	  .space {height: 512px; width: 512px;}
	  .small .value img {height: 1cm; width: 1cm}
	  .diag {float: right;}
	</style> 
	<model xmlns="http://www.w3.org/2002/xforms">
 	    <instance id="map">
		<map xmlns="">
		    <zoom>10</zoom>
		    <lasty>22315225</lasty><lastx>33530568</lastx>
		    <posx/><posy/>
		    <x/><y/>
		    <tilesize>256</tilesize>
		    <scale/>
		    <maxpos/>
		    <maxzoom>18</maxzoom>
		    <offx/><offy/>
		    <site>http://tile.openstreetmap.org/</site>
		    <urltl/><urltm/><urltr/>
		    <urlml/><urlmm/><urlmr/>
		    <urlbl/><urlbm/><urlbr/>
		    <offsets/>
		    <homex>33530568</homex>
		    <homey>22315225</homey>
                    <mouse>
			<x>0</x>
			<y>0</y>
			<state>up</state>
			<cursor/>
			<start><x/><y/></start>
			<end><x/><y/></end>
			<move><x/><y/></move>
                     </mouse>
		</map>
	    </instance>
	    <bind nodeset="scale" calculate="power(2, 26 - ../zoom)"/>
	    <bind nodeset="maxpos" calculate="power(2, 26)-1"/>
	    <bind nodeset="posx" calculate="../lastx - (../mouse/move/x * (../scale div ../tilesize))"/>
	    <bind nodeset="posy" calculate="../lasty - (../mouse/move/y * (../scale div ../tilesize))"/>
	    <bind nodeset="x" calculate="floor(../posx div ../scale)"/>
	    <bind nodeset="y" calculate="floor(../posy div ../scale)"/>

            <bind nodeset="urltl" calculate="concat(../site, ../zoom, '/', ../x - 1, '/', ../y - 1, '.png')"/>
	    <bind nodeset="urltm" calculate="concat(../site, ../zoom, '/', ../x,     '/', ../y - 1, '.png')"/>
	    <bind nodeset="urltr" calculate="concat(../site, ../zoom, '/', ../x + 1, '/', ../y - 1, '.png')"/>
	    <bind nodeset="urlml" calculate="concat(../site, ../zoom, '/', ../x - 1, '/', ../y,     '.png')"/>
	    <bind nodeset="urlmm" calculate="concat(../site, ../zoom, '/', ../x,     '/', ../y,     '.png')"/>
	    <bind nodeset="urlmr" calculate="concat(../site, ../zoom, '/', ../x + 1, '/', ../y,     '.png')"/>
	    <bind nodeset="urlbl" calculate="concat(../site, ../zoom, '/', ../x - 1, '/', ../y + 1, '.png')"/>
	    <bind nodeset="urlbm" calculate="concat(../site, ../zoom, '/', ../x,     '/', ../y + 1, '.png')"/>
	    <bind nodeset="urlbr" calculate="concat(../site, ../zoom, '/', ../x + 1, '/', ../y + 1, '.png')"/>

	    <bind nodeset="offx" calculate="floor(((../posx - ../x * ../scale) div ../scale)*../tilesize)" />
	    <bind nodeset="offy" calculate="floor(((../posy - ../y * ../scale) div ../scale)*../tilesize)" />
            <bind nodeset="offsets" calculate="concat('margin-left: ', 0 - (../offx), 'px; margin-top: ', 0 - (../offy), 'px;')" />

	    <bind nodeset="mouse/cursor" calculate="if(../state = 'up', 'pointer', 'move')"/>
	    <bind nodeset="mouse/end/x" calculate="if(../../state = 'down', ../../x, .)"/>
	    <bind nodeset="mouse/end/y" calculate="if(../../state = 'down', ../../y, .)"/>
	    <bind nodeset="mouse/move/x" calculate="../../end/x - ../../start/x"/>
	    <bind nodeset="mouse/move/y" calculate="../../end/y - ../../start/y"/>

	</model>
</head>
<body>
    <group xmlns="http://www.w3.org/2002/xforms">
	<group>
	    <group>
	    	<trigger>
		    <label>Home</label>
	            <setvalue ev:event="DOMActivate" ref="lastx" value="../homex"/>
	            <setvalue ev:event="DOMActivate" ref="lasty" value="../homey"/>
	    	</trigger>
	    	<trigger>
	            <label>Set Home</label>
	            <setvalue ev:event="DOMActivate" ref="homex" value="../lastx"/>
	            <setvalue ev:event="DOMActivate" ref="homey" value="../lasty"/>
	    	</trigger>
	    </group>
      	    <trigger>
		<label>&#x2212;</label> <!-- minus -->
		<setvalue ev:event="DOMActivate" ref="zoom" value="if(. = 0, 0, . - 1)"/>
      	    </trigger>
      	    <input ref="zoom"><label>zoom</label></input>
	    <trigger>
		<label>+</label>
		<setvalue ev:event="DOMActivate" ref="zoom" value="if(. &gt;= ../maxzoom, ../maxzoom, . + 1)"/>
	    </trigger>
	</group>
	<group>
	    <trigger>
		<label>←</label>
		<setvalue ev:event="DOMActivate" ref="lastx" value=". - ../scale"/>
	    </trigger>
      	    <input ref="lastx"><label>lastx</label></input>
	    <trigger>
		<label>→</label>
		<setvalue ev:event="DOMActivate" ref="lastx" value=". + ../scale"/>
	    </trigger>
	</group>
	<group>
	    <trigger>
		<label>↓</label>
		<setvalue ev:event="DOMActivate" ref="lasty" value=". + ../scale"/>
	    </trigger>
      	    <input ref="lasty"><label>lasty</label></input>
	    <trigger>
		<label>↑</label>
		<setvalue ev:event="DOMActivate" ref="lasty" value=". - ../scale"/>
	    </trigger>
	</group>
	<select1 appearance="full" ref="site"><label>Map</label>
	<item><label>Standard</label><value>http://tile.openstreetmap.org/</value></item>
	<item><label>Cycle</label><value>http://tile.opencyclemap.org/cycle/</value></item>
	<item><label>Transport</label><value>http://tile2.opencyclemap.org/transport/</value></item>
	<item><label>Impression</label><value>http://tile.stamen.com/watercolor/</value></item>
	<item><label>Satellite</label><value>http://otile1.mqcdn.com/tiles/1.0.0/sat/</value></item>
	</select1>
<!--    <output ref="urlmm"/>
	<output ref="offsets"><label>Offsets</label></output>
        last: <output ref="lastx"/>, <output ref="lasty"/>
        start: <output ref="mouse/start/x"/>, <output ref="mouse/start/y"/>
        end: <output ref="mouse/end/x"/>, <output ref="mouse/end/y"/>
        move: <output ref="mouse/move/x"/>, <output ref="mouse/move/y"/> -->
<h:br/>
    </group>
	<!-- These next two divs, which are positioned over each other by the CSS, are needed because ev:defaultAction
	     seems not to work in the implementation I am using -->
   <div class="map" style="cursor: {mouse/cursor}">
      <div style="{offsets}">
	<group xmlns="http://www.w3.org/2002/xforms">
	  <group>
	    <output ref="urltl" mediatype="image/*"/>
	    <output ref="urltm" mediatype="image/*" />
	    <output ref="urltr" mediatype="image/*" />
	  </group>
	  <group>
	    <output ref="urlml" mediatype="image/*" />
	    <output ref="urlmm" mediatype="image/*" />
	    <output ref="urlmr" mediatype="image/*" />
	  </group>
	  <group>
	    <output ref="urlbl" mediatype="image/*" />
	    <output ref="urlbm" mediatype="image/*" />
	    <output ref="urlbr" mediatype="image/*" />
	  </group>
	</group>
      </div>
    </div>
    <div class="mouse">
        <div style="cursor: {mouse/cursor}">
	    <group class="space" xmlns="http://www.w3.org/2002/xforms">
		<action ev:event="mousemove">
			<setvalue ref="mouse/x" value="event('clientX')"/>
			<setvalue ref="mouse/y" value="event('clientY')"/>
		</action>
	        <action ev:event="mousedown" ev:defaultAction="cancel">
		    <setvalue ref="mouse/state">down</setvalue>
		    <setvalue ref="mouse/start/x" value="event('clientX')"/>
		    <setvalue ref="mouse/start/y" value="event('clientY')"/>
    		</action>
	        <action ev:event="mouseup" ev:defaultAction="cancel">
		    <setvalue ref="mouse/state">up</setvalue>
		    <setvalue ref="lastx" value="../posx"/>
		    <setvalue ref="lasty" value="../posy"/>
		    <setvalue ref="mouse/start/x" value="../../end/x"/>
		    <setvalue ref="mouse/start/y" value="../../end/y"/>
		    <!-- Not sure why this is necessary;
		         either something to do with the recalc algorithm that I have forgotten, or a bug :-) -->
		    <setvalue ref="mouse/move/x" value="0"/>
		    <setvalue ref="mouse/move/y" value="0"/>

    		</action>

	    <action ev:event="dblclick">
                <setvalue ref="zoom" value="if(. &gt;= ../maxzoom, ../maxzoom, . + 1)"/>
            </action>
            <action ev:event="mousewheel" >
	        <setvalue ref="zoom" value="if(event('wheelDelta') &gt; 0, if(. &gt;= ../maxzoom, ../maxzoom, . + 1), if(. &lt;= 0, 0, . - 1))"/>
            </action>

	    </group>
        </div>
    </div>
</body>
</html>
