/* appjet:version 0.1 */

import("lib-xmldom");
import("lib-jquery");

page.head.write('<script src="http://www.cachefile.net/scripts/prototype/1.6.0.2/prototype.js"></script>');
page.head.write('<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAABhseQMO-uDS72b2wAN2_ExSbC0oDTiLoRq8aIlx-YBXM5Dte8BQSH55ZtgPBfuGJyysxcjObXQ5-EQ" type="text/javascript"></script>');

//print(BODY({onload:"load()", onunload:"GUnload()"},DIV({id:"map",style:"width: 500px; height: 300px"})));

if (request.method == "GET") {
    print(
        DIV({id:"page_intro"},P(SPAN({style:"font-size:18pt"},
        B("WeatherCurve!")),
        BR("Congratulations to the people at Appjet. They have found commercial success! They hosted this application (and many others) for free, but now are ending their service. So, unfortunately, WeatherCurve with be temporarily discontinued on July 1 until I find time to build it elsewhere."),
        BR(SPAN({style:"font-size:8pt"},"Powered by ", link("http://www.weatherbug.com", "WeatherBug"))),
        BR(SPAN({style:"font-size:8pt"},"Submit your ", link("http://weathercurve.blogspot.com/2008/08/welcome-to-weathercurve.html", "comments"))))));
    
    print(DIV({id:"main"},
        DIV({id:"map_container"},DIV({id:"map",style:"width: 500px; height: 300px"})),
        DIV({id:"curve"}, "")),
        DIV({id:"mapcontrols"},
            "From:",INPUT({id:"startLoc",type:"text",name:"startLoc",value:"Atlanta,GA"}),
            " - To:",INPUT({id:"endLoc",type:"text",name:"endLoc",value:"Woodstock,GA"}),
            INPUT({id:"dirButton",type:"button",value:"Get Directions",onclick:"getDirections()"}),
            DIV({id:"statusBox"}, "Status: Waiting for user input.")
            )
        );

    print(DIV({id:"dir_steps"}, ""));
}
else {
    var stations = getWeather(eval("(" + request.params.latLons + ")"));
    page.setMode('plain');
    print(raw(stations));
}

function getWeather(geoPoints) {
    
  // Please be kind and register for your own Weather Bug user code.
  // They're free!
  // Thanks.
  // http://a3442904444.api.wxbug.net/getLiveCompactWeatherRSS.aspx?ACode=A3442904444&lat=33.75&long=-84.38
  var wbugUserCode = "A3442904444";
  var stations = new Array();

  for (var i = 0; i < geoPoints.length; i++) {
    params = {
      "ACode": wbugUserCode,
      "lat": geoPoints[i].lat ,
      "long": geoPoints[i].lon
    };
    g = wget("http://" + wbugUserCode + ".api.wxbug.net/getLiveCompactWeatherRSS.aspx", params);

    var feed = new XMLDoc(g);
    var stationNode = feed.selectNode("/channel/aws:weather/aws:station");

    stations[i] = {
      "lat": geoPoints[i].lat,
      "lng": geoPoints[i].lon,
      "city": stationNode.getAttribute("city"),
      "state": stationNode.getAttribute("state"),
      "zipcode": stationNode.getAttribute("zipcode"),
      "temperature": feed.selectNode("/channel/aws:weather/aws:temp").getText(),
      "wblink": feed.selectNode("/channel/aws:weather/aws:WebURL").getText(),
      "wbimage": feed.selectNode("/channel/aws:weather/aws:current-condition").getAttribute("icon")
    }
  }
  
  return stations;
};
/* appjet:css */
#main {
    height: 310px;
    width: 100%;
}

#map_container {
    float: left;
}

#mapcontrols {}

#status_box {}

#curve {
    float: right;
    padding: 50px;
}

#dir_steps {}

/* appjet:client */

function getDirectionsWithParams(startLoc, endLoc) {
//    alert('Directions from ' + startLoc + ' to ' + endLoc);
    map.clearOverlays();
    var gDir = new GDirections(map, document.getElementById('dir_steps'));
    GEvent.addListener(gDir, "addoverlay", function(){
//        alert("Everything should have been loaded by now!");
        var polyline = gDir.getPolyline();
        var dist = polyline.getLength();
//        alert("Polyline distance: " + dist);
        var interimPointCount = Math.min(Math.floor(dist / 100000), 8);
        
//        alert("Interim point count: " + interimPointCount);
        
        var points = new Array();
        
        var factor = Math.floor(dist / (interimPointCount + 1));
        for (var i = 0; i <= interimPointCount; i++) {
            points[i] = factor * i;
        }
        points[interimPointCount + 1] = dist;

//        alert("Total points: " + points.length);
        
        var pindex = 1;
        var pointCount = points.length;
        var vindex;
        var vertexCount = polyline.getVertexCount();
        var traversed = 0;
        var evalPoints = new Array();
        var latLons = new Array();
        // start city
        latLons.push(convertGeoPoint(polyline.getVertex(0)));

//        alert("Vertex count: " + vertexCount);
        for (vindex = 1; vindex < vertexCount - 1 && pindex < pointCount - 1; vindex++) {
//            alert("vindex:" + vindex + " pindex:" + pindex);
            var v1 = polyline.getVertex(vindex);
            var v2 = polyline.getVertex(vindex - 1);
            var legDist = v1.distanceFrom(v2);
            while (points[pindex] < traversed + legDist) {
                evalPoints.push(points[pindex]);
                pindex++;
//            alert("Yo! " + evalPoints.length + " " + pindex);
            }
            
            // convert point into a LatLon
            for (var i = 0; i < evalPoints.length; i++) {
                var factor = (evalPoints[i] - traversed) / legDist;
//                alert(v2.lng());
                var latlon = new GLatLng(v2.lat() + (v1.lat() - v2.lat()) * factor, v2.lng() + (v1.lng() - v2.lng()) * factor)
                latLons.push(convertGeoPoint(latlon));
                map.addOverlay(new GMarker(latlon));
//                alert(latLons.length);
            }
            evalPoints.length = 0;
            
            traversed += legDist;
        }
        
        // Ending city
        latLons.push(convertGeoPoint(polyline.getVertex(vertexCount - 1)));
        
//        alert("Number of lat_lons: " + latLons.length);
//        alert("latlons: " + Object.toJSON(latLons));
        var statusBox = $('statusBox');
        var parsedData = $('parsed_data');
        var curve = $('curve');
        statusBox.innerHTML = "Status: Querying for weather data.";
        curve.innerHTML = "<p>Collecting weather data for points along the route...</p>";
        
        new Ajax.Request('/', 
        {
            method:'post',
            parameters: {"latLons":Object.toJSON(latLons)},
            onSuccess: function(transport) {
                var response = transport.responseText || "no response text";
 //               alert("Success! \n\n" + response);
                statusBox.innerHTML = "Click on the red markers for current weather conditions.";
                //parsedData.innerHTML = parseCities(response);
                parseCities(response);
                curve.innerHTML = graphem(response);
            },
            onFailure: function() {
                alert('Something went wrong... Please try your request again.');
                statusBox.innerHTML = "The vast array of computing power is, sadly, asleep.";
            }
        });
     });
//     alert("Here we go!");
     gDir.load("from: " + startLoc + " to: " + endLoc);
     return false;
}

function convertGeoPoint(geoPoint) {
    return {lat:geoPoint.y, lon:geoPoint.x};
}

function parseCities(weatherData) {
    var resp = "";
    var weather = weatherData.evalJSON();
    for (var i=0; i < weather.length; i++) {
        resp += "<p>" + weather[i].city + "" + weather[i].temperature + "</p>";
        map.addOverlay(populateMarker(weather[i]));
    }
    return resp;
}

function populateMarker(locwx) {
    var point = new GLatLng(locwx.lat, locwx.lng);
    var htmlString = "<table><tr><td>"
    htmlString += locwx.city + "" + locwx.state + "<br />Temp: " + locwx.temperature;
    htmlString += "</td><td>";
    htmlString += "<a href=\"" + locwx.wblink + "\" target=\"_blank\"><img src=\"" + locwx.wbimage + "\"></a>";
    htmlString += "</td></tr></table>";
    var marker = new GMarker(point);
    GEvent.addListener(marker, "click", function() {
        marker.openInfoWindowHtml(htmlString);
    });
    
    return marker;
}

function graphem(weatherData) {
    var weather = weatherData.evalJSON();
    var lowerBound = parseInt(weather[0].temperature);
    var upperBound = lowerBound;
    for (var i=1; i < weather.length; i++) {
        var tempInt = parseInt(weather[i].temperature);
        if (tempInt < lowerBound) {
            lowerBound = tempInt;
        }
        if (tempInt > upperBound) {
            upperBound = tempInt;
        }
    }
    
    lowerBound = Math.floor((lowerBound - 1) / 5) * 5; 
    upperBound = Math.ceil((upperBound + 1) / 5) * 5; 
    
    var resp = simpleEncode(weather, lowerBound, upperBound);
    var imageSrc = "http://chart.apis.google.com/chart?cht=lc&chd=" + resp + "&chs=350x140&chtt=Temperature";
    imageSrc += "&chxt=x,y&chxl=0:|" + weather[0].city + "|" + weather[weather.length - 1].city + "|1:|" + lowerBound + "|" + upperBound;
    return "<img src=\"" + imageSrc + "\">";
}

var simpleEncoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
 
function simpleEncode(stationArray, minValue, maxValue) {
  var chartData = ['s:'];
  //alert(stationArray.length);
  //alert("Range: " + minValue + " to " + maxValue);
  for (var i = 0; i < stationArray.length; i++) {
    var currentValue = stationArray[i].temperature;
    if (!isNaN(currentValue)) {
      //alert(currentValue);
      chartData.push(simpleEncoding.charAt(Math.round((simpleEncoding.length-1) * (currentValue - minValue) / (maxValue - minValue))));
    }
    else {
      chartData.push('_');
    }
  }
  return chartData.join('');
}

function init() {
    startupKey = 'Wake up!';
//    alert('weathercurve is up and running: ' + startupKey);
//    alert('startup the mapping functionality');

    if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map"));
//        map.setCenter(new GLatLng(33.75, -84.38), 7);
        map.setCenter(new GLatLng(37.0625, -95.677068), 3);
    }
}

function shutdown() {
//    alert('shutting down the mapping functionality');
    GUnload();
//    alert('Going away... un' + startupKey);
}

function getDirections() {
    var startLoc = $('startLoc');
//    alert(startLoc.value);
    var endLoc = $('endLoc');
    var dirSteps = $('dir_steps');
    dirSteps.innerHTML = "";
    getDirectionsWithParams(startLoc.value, endLoc.value);
    return false;
}

//var simpleEncoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var map;
var startupKey;
//var statusBox = $('statusBox');

window.onload= init;
window.onunload = shutdown;

© Copyright 2007-2009 AppJet Inc.