# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - GetStreetView Macro
    Tool to get lat, lng, yaw, pitch and zoom for GoogleStreetView macro.
    by JasonMcArthur <jason@personaltelco.net>
"""

def execute(macro,text):
    gkey = 'ABQIAAAA7rwZfsyEYZknlS0QWmZI4RQUexDMtc4eREioiWSpX_Y7fpoKghQhUCefr4eJwudYofs3YH9eyyZ3_g'     
    gkey2 = 'ABQIAAAA7rwZfsyEYZknlS0QWmZI4RRyEbBFkcIcf1l0xXknIhElMWaAuBQ_2YFGNyOJB1ziI9lSzlpCIilgNw'
    math = '%'
    html = '''
<script type="text/javascript">
    // set proper key for www. and wiki. subdomains.
    if( (window.location.href).indexOf("www.") == -1 ) {
        writeScript("%s");  
    } else { 
        writeScript("%s");}                                                    
function writeScript(key) {var ret='<'+'script src="http://maps.google.com/maps?file=api&v=2.x&key='+key+'"'+'type="text/javascript"><'+'/script>';document.write(ret);}  
</script> 
    <script type="text/javascript">
    function layerControl() {
    }
    layerControl.prototype = new GControl();
    layerControl.prototype.initialize = function(map) {
      geoXml = new GGeoXml("http://map.personaltelco.net/feed.kml");

      var container = document.createElement("div");
      container.style.width = "200px";
      var sv = new GStreetviewOverlay();

      var onDiv = document.createElement("div");
      this.setButtonStyle_(onDiv);
      onDiv.appendChild(document.createTextNode("StreetView"));
      var onLink = document.createElement("a");
      onLink.innerHTML = "<br />On";
      GEvent.addDomListener(onLink, "click", function() {
        map.addOverlay(sv);
      });
      onDiv.appendChild(onLink)
      onDiv.appendChild(document.createTextNode(" | "));
      //onDiv.innerHTML = " | "
      var offLink = document.createElement("a");
      offLink.innerHTML = " Off";
      GEvent.addDomListener(offLink, "click", function() {
        map.removeOverlay(sv);
      });
      onDiv.appendChild(offLink)
      container.appendChild(onDiv)

      var nonDiv = document.createElement("div");
      this.setButtonStyle_(nonDiv);
      nonDiv.style.left = "7em";
      container.appendChild(nonDiv);
      nonDiv.appendChild(document.createTextNode("View Nodes"));
      var nonLink = document.createElement("a");
      nonLink.innerHTML = "<br />On";
      GEvent.addDomListener(nonLink, "click", function() {
        map.addOverlay(geoXml);
      });
      nonDiv.appendChild(nonLink)
      nonDiv.appendChild(document.createTextNode(" | "));
      var noffLink = document.createElement("a");
      noffLink.innerHTML = " Off";
      GEvent.addDomListener(noffLink, "click", function() {
        map.removeOverlay(geoXml);;
      });
      nonDiv.appendChild(noffLink)
      container.appendChild(nonDiv)

      map.getContainer().appendChild(container);
      return container;
    }
    // By default, the control will appear in the top left corner of the
    // map with 7 pixels of padding.
    layerControl.prototype.getDefaultPosition = function() {
      return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(55, 7));
    }

    // Sets the proper CSS for the given button element.
    layerControl.prototype.setButtonStyle_ = function(button) {
      button.style.textDecoration = "none";
      //button.style.color = "#000000";
      button.style.position = "absolute";
      button.style.backgroundColor = "white";
      button.style.font = "small Arial";
      button.style.border = "1px solid black";
      button.style.padding = "2px";
      button.style.marginBottom = "3px";
      button.style.textAlign = "center";
      button.style.width = "6em";
      button.style.cursor = "pointer";
      //button.style.filters.alpha.opacity="80";
      button.style.MozOpacity="0.8";
    }

    var map;
    var myPano;   
    var panoClient;
    var nextPanoId;
    var center = new GLatLng(45.52310,-122.67133);

    function initMap() {
      panoClient = new GStreetviewClient();      
      // setup and configure map
      map = new GMap2(document.getElementById("mapDiv"));
      map.setMapType(G_HYBRID_MAP);
      map.addControl(new GScaleControl());
      map.addControl(new GMapTypeControl());
      map.addControl(new GSmallMapControl());
      map.addControl(new layerControl());
      map.setCenter(center, 15);
      map.enableContinuousZoom();      
      map.enableScrollWheelZoom();
      //map.addOverlay(new GTrafficOverlay({incidents: true}));
      
      //map.addControl(new ExtMapTypeControl({showTraffic: true, showTrafficKey: true}));
      
      // setup draggable and rotating guy icon
      var guyIcon = new GIcon(G_DEFAULT_ICON);
      // Leprechan icon
      guyIcon.image = "http://maps.gstatic.com/mapfiles/cb/leprechan_arrow-0.png";
      // Normal man icon
      //guyIcon.image = "http://maps.gstatic.com/mapfiles/cb/man_arrow-0.png";
      guyIcon.transparent = "http://maps.gstatic.com/mapfiles/cb/man-pick.png";
      guyIcon.shadow = "";
      guyIcon.imageMap = [
        26,13, 30,14, 32,28, 27,28, 28,36, 18,35, 18,27, 16,26,
        16,20, 16,14, 19,13, 22,8
      ];
      guyIcon.iconSize = new GSize(49, 52);
      guyIcon.iconAnchor = new GPoint(25, 35);  // near base of feet
      guyIcon.infoWindowAnchor = new GPoint(25, 5);  // top of head     
      
      marker = new GMarker(center, {icon: guyIcon, draggable: true});
      map.addOverlay(marker);
      lastMarkerLocation = center;
      geocoder = new GClientGeocoder();
      GEvent.addListener(marker, "dragend", onDragEnd);
      GEvent.addListener(marker, "click", showPanoData);

      // update streetview client when location is selected on map
      GEvent.addDomListener(map, "click", function(overlay,latlng) {
        panoClient.getNearestPanorama(latlng, showPanoData);
        marker.setLatLng(latlng);
      });

      // setup and configure streetview client
      var POV = {yaw:0,pitch:-5};
      panoClient = new GStreetviewClient(); 
      myPano = new GStreetviewPanorama(document.getElementById("pano"));
      myPano.setLocationAndPOV(center, POV);
      GEvent.addListener(myPano, "error", handleNoFlash);  
      panoClient.getNearestPanorama(center, showPanoData);
      GEvent.addListener(myPano, "yawchanged", showStats);
      GEvent.addListener(myPano, "yawchanged", onYawChange);
      GEvent.addListener(myPano, "zoomchanged", showStats);
      
      // update map as user moves locations in the streetview client
      GEvent.addListener(myPano, "initialized", function(call) {
      var center = call.latlng;
      map.setCenter(center);
      marker.setLatLng(center);
      });
      showStats();
    }
    
    function showPanoData(panoData) {
      // get and fill out infowindow
      if (panoData.code != 200) {
        //GLog.write('showPanoData: Server rejected with code: ' + panoData.code);
          document.getElementById("statDiv").innerHTML = "No panorama available!";
          return;
      }
      myPano.setLocationAndPOV(panoData.location.latlng);
      GEvent.addListener(myPano, "newpano", onNewLocation);
      showStats();
    }

    function showStats() {
      // return POV and coords    
      var geocoder = null;
      geocoder = new GClientGeocoder();
      var stats = "";            
      var pov = myPano.getPOV();
      var point = marker.getLatLng();
      
      estats = "&lt;&lt;GoogleStreetView&#40;" + point + "," + pov.yaw + "," + pov.pitch + "," + pov.zoom;
      stats = estats.replace(/\(| |\)/g, "");
      document.getElementById("statDiv").innerHTML = stats + ")&gt;&gt;";
      //point = marker.getLatLng();      
      // Reverse Geocoder
      geocoder.getLocations(point, function(addresses) {
        if(addresses.Status.code != 200) {
          document.getElementById("statDesc").innerHTML = "<br />No address found";
        } else {
          address = addresses.Placemark[0];
          var myHtml = address.address;
          document.getElementById("statDesc").innerHTML = "<br />" + myHtml;
        }
      });
    }

    function next() {
      // Get the next panoId
      panoClient.getPanoramaById(nextPanoId, showPanoData, showStats);
    }
    
    function onYawChange(newYaw) {
      var GUY_NUM_ICONS = 16;
      var GUY_ANGULAR_RES = 360/GUY_NUM_ICONS;
      if (newYaw < 0) {
        newYaw += 360;
      }
      guyImageNum = Math.round(newYaw/GUY_ANGULAR_RES) %s GUY_NUM_ICONS;
      guyImageUrl = "http://maps.gstatic.com/mapfiles/cb/leprechan_arrow-" + guyImageNum + ".png";
      //guyImageUrl = "http://maps.google.com/intl/en_us/mapfiles/cb/man_arrow-.png";
      marker.setImage(guyImageUrl);
    }

    function onNewLocation(lat, lng) {
      var center = new GLatLng(lat, lng);
      marker.setLatLng(center);
      showStats();
    }
 
    function onDragEnd() {
      var center = marker.getLatLng();
      if (myPano) {
        panoClient.getNearestPanorama(center, onResponse);
        showStats();
      }
    }

    function onResponse(response) {
      if (response.code != 200) {
        marker.setLatLng(lastMarkerLocation);
      } else {
        var center = new GLatLng(response.Location.lat, response.Location.lng);
        marker.setLatLng(center);
        lastMarkerLocation = center;
        panoClient.getNearestPanorama(center, showPanoData);
        myPano.setLocationAndPOV(marker.getLatLng(), null)
        showStats();
      }
    }
    
    
    function showAddress(address) {
      if (geocoder) {
        geocoder.getLatLng(
          address,
          function(point) {
            if (!point) {
              alert(address + " not found");
            } else {
              map.setCenter(point, 17);
              //var marker = new GMarker(point);
              //map.addOverlay(marker);
              marker.setLatLng(point)
              panoClient.getNearestPanorama(point, showPanoData);
              myPano.setLocationAndPOV(point, null)
              //marker.openInfoWindowHtml(address);
              showStats();
            }
          }
        );
      }
    }

    function handleNoFlash(errorCode) {
      if (errorCode == FLASH_UNAVAILABLE) {
        alert("Error: Flash doesn't appear to be supported by your browser");
        return;
      }
    }  
    </script>
    <script type="text/javascript">
        window.onload = initMap
        window.onunload=GUnload
    </script>
    <form action="#" onsubmit="showAddress(this.address.value); return false">
      <p>
        <input type="text" size="60" name="address" value="226 NW Davis St, Portland, OR" />
        <input type="submit" value="Go!" />
      </p>
<span id="statDiv" style=""></span>
<div id="statDesc" style="height:30px;padding-bottom:10px;"></div>
<p>
<div id="pano" style="width:350px;height:350px;border:1px solid #000;float:left;"></div>
<div id="mapDiv" style="width350px;height:350px;border:1px solid #000;margin-left:355px;"></div>
    ''' % (gkey, gkey2, math)
    return html
