var polyline = {};

/*
 * Based off of [the offical Google document](https://developers.google.com/maps/documentation/utilities/polylinealgorithm)
 *
 * Some parts from [this implementation](http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/PolylineEncoder.js)
 * by [Mark McClure](http://facstaff.unca.edu/mcmcclur/)
 */

/*
 * Encoding coordinates
 *
 * @param {Number} coordinate a single coordinate number
 * @return {String} an encoded point
 *
 * > Note that the backslash is interpreted as an escape character within string literals.
 * Any output of this utility should convert backslash characters to
 * double-backslashes within string literals.
 */
polyline.encodeCoordinate = function(coordinate) {
    // step 2
    coordinate = Math.round(coordinate * 1e5);
    // step 4
    coordinate <<= 1;
    // step 5
    if (coordinate < 0) {
        coordinate = ~coordinate;
    }
    var output = '';
    // step 6
    // TODO: understand
    while (coordinate >= 0x20) {
        output += String.fromCharCode((0x20 | (coordinate & 0x1f)) + 63);
        coordinate >>= 5;
    }
    output += String.fromCharCode(coordinate + 63);
    return output;
};

/*
 * Simple encoding of a point, simply encoding two coordinates
 */
polyline.encodePoint = function(x, y) {
    return this.encodeCoordinate(x) + this.encodeCoordinate(y);
};

/*
 * Currently failing tests.
 *
 * @param {Array} coordinates a two-dimensional array of coordinates in latitude and longitude
 * @return {String} an encoded polyline
 */
polyline.encodeLine = function(coordinates) {
    var previous_point,
        output = '';
    for (var i = 0; i < coordinates.length; i++) {
        var pt = [coordinates[i][0], coordinates[i][1]];
        if (previous_point) {
             pt[i] = [
                  previous_point[0]-pt[0],
                  previous_point[1]-pt[1]];
        }
        output += this.encodePoint(pt[0], pt[1]);
        previous_point = coordinates[i];
    }
    return output;
};

if (typeof module !== undefined) module.exports = polyline;

@@ -1053,24 +1053,65 @@
 1f)) + 63);%0A
+        // Read the next chunk of 5 bits%0A
         coor
@@ -1126,24 +1126,51 @@
 %3E= 5;%0A    %7D%0A
+    // Read the last chunk%0A
     output +
@@ -1228,24 +1228,309 @@
 output;%0A%7D;%0A%0A
+/*%0A * See http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/decode.js%0A */%0Apolyline.decodeCoordinate = function(str) %7B%0A    for (var i = 0; i %3C str.length; i++) %7B%0A        var binary = str.charCodeAt(i) - 63;%0A        result %7C= (b & 0x1f) %3C%3C shift;%0A        shift += 5;%0A    %7D%0A%7D;%0A%0A
 /*%0A * Simple

Add decode stub