/* ------------------------------------------------------------------------------
 *
 *  # Showing coordinates
 *
 *  Specific JS code additions for maps_google_basic.html page
 *
 * ---------------------------------------------------------------------------- */


// Setup module
// ------------------------------

var GoogleMapCoordinates = function() {


    //
    // Setup module components
    //

    // Line chart
    var _googleMapCoordinates = function() {
        if (typeof google == 'undefined') {
            console.warn('Warning - Google Maps library is not loaded.');
            return;
        }

        // Variables
        var map;
        var TILE_SIZE = 256;
        var chicago = new google.maps.LatLng(41.850033,-87.6500523);

        // Minimum and maximum values
        function bound(value, opt_min, opt_max) {
            if (opt_min != null) value = Math.max(value, opt_min);
            if (opt_max != null) value = Math.min(value, opt_max);
            return value;
        }

        // Degrees to radians
        function degreesToRadians(deg) {
            return deg * (Math.PI / 180);
        }

        // Radians to degrees
        function radiansToDegrees(rad) {
            return rad / (Math.PI / 180);
        }

        // Constructor
        function MercatorProjection() {
            this.pixelOrigin_ = new google.maps.Point(TILE_SIZE / 2, TILE_SIZE / 2);
            this.pixelsPerLonDegree_ = TILE_SIZE / 360;
            this.pixelsPerLonRadian_ = TILE_SIZE / (2 * Math.PI);
        }

        // From latitude to longitude
        MercatorProjection.prototype.fromLatLngToPoint = function(latLng, opt_point) {
            var me = this;
            var point = opt_point || new google.maps.Point(0, 0);
            var origin = me.pixelOrigin_;

            point.x = origin.x + latLng.lng() * me.pixelsPerLonDegree_;

            // Truncating to 0.9999 effectively limits latitude to 89.189. This is
            // about a third of a tile past the edge of the world tile.
            var siny = bound(Math.sin(degreesToRadians(latLng.lat())), -0.9999, 0.9999);
            point.y = origin.y + 0.5 * Math.log((1 + siny) / (1 - siny)) * -me.pixelsPerLonRadian_;
            return point;
        };

        // From longitude to latitude
        MercatorProjection.prototype.fromPointToLatLng = function(point) {
            var me = this;
            var origin = me.pixelOrigin_;
            var lng = (point.x - origin.x) / me.pixelsPerLonDegree_;
            var latRadians = (point.y - origin.y) / -me.pixelsPerLonRadian_;
            var lat = radiansToDegrees(2 * Math.atan(Math.exp(latRadians)) - Math.PI / 2);
            return new google.maps.LatLng(lat, lng);
        };

        // Create content
        function createInfoWindowContent() {
            var numTiles = 1 << map.getZoom();
            var projection = new MercatorProjection();
            var worldCoordinate = projection.fromLatLngToPoint(chicago);
            var pixelCoordinate = new google.maps.Point(worldCoordinate.x * numTiles, worldCoordinate.y * numTiles);
            var tileCoordinate = new google.maps.Point(
            Math.floor(pixelCoordinate.x / TILE_SIZE),
            Math.floor(pixelCoordinate.y / TILE_SIZE));

            return [
                'Chicago, IL',
                'LatLng: ' + chicago.lat() + ' , ' + chicago.lng(),
                'World Coordinate: ' + worldCoordinate.x + ' , ' + worldCoordinate.y,
                'Pixel Coordinate: ' + Math.floor(pixelCoordinate.x) + ' , ' + Math.floor(pixelCoordinate.y),
                'Tile Coordinate: ' + tileCoordinate.x + ' , ' + tileCoordinate.y + ' at Zoom Level: ' + map.getZoom()
            ].join('<br>');
        }

        // Initialize
        function initialize() {

            // Define map element
            var map_coordinates_element = document.getElementById('map_coordinates');

            // Options
            var mapOptions = {
                zoom: 10,
                center: chicago
            };

            // Apply options
            map = new google.maps.Map(map_coordinates_element, mapOptions);

            // Info window
            var coordInfoWindow = new google.maps.InfoWindow();
            coordInfoWindow.setContent(createInfoWindowContent());
            coordInfoWindow.setPosition(chicago);
            coordInfoWindow.open(map);

            // Add "Change" event
            google.maps.event.addListener(map, 'zoom_changed', function() {
                coordInfoWindow.setContent(createInfoWindowContent());
                coordInfoWindow.open(map);
            });
        }

        // Load map
        google.maps.event.addDomListener(window, 'load', initialize);
    };


    //
    // Return objects assigned to module
    //

    return {
        init: function() {
            _googleMapCoordinates();
        }
    }
}();


// Initialize module
// ------------------------------

document.addEventListener('DOMContentLoaded', function() {
    GoogleMapCoordinates.init();
});
