/**
 * GoogleMaps
 *
 */
GoogleMaps = new Class({

    /**
     * @var map
     */
    map: null,

    /**
     * @var locations
     */
    locations: new Array(),

    /**
     * @var zoom factor
     */
    zoom_factor: 7,

    /**
     * @var latitude
     */
    lat: 0,

    /**
     * @var lengtitude
     */
    lng: 0,

    /**
     * @var marker arr
     */
    marker_arr: new Array(),

    /**
     * @var icon size
     */
    icon_size: 'middle' ,

    /**
     * @var path to images folder
     */
    icon_folder_path: '/images' ,

    /**
     * Constructor
     *
     * @param string, locations lat lang
     * @param int, zoom_factor (current viewport)
     * @param int, lat (current viewport)
     * @param int, lng (current viewport)
     * @param string, icon_size
     * @param string, icon_folder_path (path to images root)
     */
    initialize: function(locations, zoom_factor, lat, lng, icon_size, icon_folder_path) {

        this.zoom_factor = zoom_factor;
        this.lat = lat;
        this.lng = lng;
        this.locations = locations;
        this.icon_size = icon_size;
        this.icon_folder_path = icon_folder_path;

        this.setupMap();
    },

    /**
     * Setup the map
     *
     * @return void
     */
    setupMap: function() {

        var thisObject = this;
        var latlng = new google.maps.LatLng(this.lat, this.lng);
        var myOptions = {
            zoom: this.zoom_factor,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        // create map
        this.map = new google.maps.Map(document.getElementById('map'), myOptions);

        // create infowindow
        infoWindow = new google.maps.InfoWindow();

        // Close InfoWindow when clicking anywhere on the map.
        google.maps.event.addListener(this.map, "click", function() {
            infoWindow.close();
            thisObject.resetMarkers();
        });
        google.maps.event.addListener(infoWindow, "click", function() {
            thisObject.resetMarkers();
        });
        google.maps.event.addListener(this.map, 'zoom_changed', function(){
            infoWindow.close();
            // replaces markers on map to reset the number of markers on zoomlevel change
            // is related to the code in createMarkerArr()
            thisObject.replaceMarkers();
        });

        this.createMarkerArr();
    },

    /**
     * replace the markers
     *
     * @return void
     */
    replaceMarkers: function() {

        this.clearMarkers();
        this.createMarkerArr();
    },

    /**
     * Reset the markers
     *
     * @return void
     */
    resetMarkers: function() {
        for (var i = 0; i < this.marker_arr.length; i++) {
            if (this.marker_arr[i] == null) {
                continue;
            }

            this.marker_arr[i].setIcon(this.getMarkerIcon("blue"));
        }
    },

    /**
     * Clear the markers
     *
     * @return void
     */
    clearMarkers: function() {
        for (var i = 0; i < this.marker_arr.length; i++) {

            // guard
            if (this.marker_arr[i] == null) {
                continue;
            }

            this.marker_arr[i].setMap(null);
            this.marker_arr[i] = null;
        }
    },

    /**
     * get marker icon
     *
     * @return void
     */
    getMarkerIcon: function(color) {

        // color switch
        if (color == 'yellow') {
            var small_image = this.icon_folder_path + "location_small_yellow.png";
            var middle_image = this.icon_folder_path + "location_middle_yellow.png";
            var large_image = this.icon_folder_path + "location_yellow.png";
        } else {
            var small_image = this.icon_folder_path + "location_small.png";
            var middle_image = this.icon_folder_path + "location_middle.png";
            var large_image = this.icon_folder_path + "location.png";
        }

        // get images based on icon size (small large or medium)
        if (this.icon_size == 'small') {
            var image = small_image;
            var img_icon_width  = 15;
            var img_icon_height = 20;
        } else if(this.icon_size == 'middle') {
            var image = middle_image;
            var img_icon_width  = 48;
            var img_icon_height = 41;
        } else {
            var image = large_image;
            var img_icon_width  = 86;
            var img_icon_height = 81;
        }

        // create icon
        var icon_blue = new google.maps.MarkerImage(image,
            new google.maps.Size(img_icon_width, img_icon_height),
            new google.maps.Point(0, 0),
            new google.maps.Point(Math.round(img_icon_width/2), img_icon_height));

        return icon_blue;
    },

    /**
     * get marker
     *
     * @return void
     */
    getMarker: function() {

        // get images based on icon size
        if (this.icon_size == 'small') {
            var shadow_image = this.icon_folder_path + "location_sha_small.png";
            var sha_icon_width  = 23;
            var sha_icon_height = 20;
        } else if(this.icon_size == 'middle') {
            var shadow_image = this.icon_folder_path + "location_sha_middle.png";
            var sha_icon_width  = 47;
            var sha_icon_height = 41;
        } else {
            var shadow_image = this.icon_folder_path + "locationshadow.png";
            var sha_icon_width  = 92;
            var sha_icon_height = 81;
        }

        var shadow = new google.maps.MarkerImage(shadow_image,
            new google.maps.Size(sha_icon_width, sha_icon_height),
            new google.maps.Point(0, 0),
            new google.maps.Point(Math.round(sha_icon_width/2), sha_icon_height));

        // create marker
        var marker = new google.maps.Marker({
            map: this.map,
            icon: this.getMarkerIcon("blue"),
            shadow: shadow
        });

        return marker;
    },

    /**
     * create the markers
     *
     * @return array markers
     */
    createMarkerArr: function() {

        // set maxlenght
        var maxlength = locations.length;

        //  Remove the following code block if you want to show all markers independent of zoom level
        // show all markers on map

        if (this.map.getZoom() < 9) {
            maxlength = 100;
        }
        if (this.map.getZoom() < 7) {
            maxlength = 50;
        }
        if (this.map.getZoom() < 6) {
            maxlength = 20;
        }
        if (this.map.getZoom() < 5) {
            maxlength = 5;
        }

        // guard, maxlenght cannot be greater than the number of available points
        if (maxlength > locations.length) {
            maxlength = locations.length;
        }
        /**/

        for (var i = 0; i < maxlength; i++) {
            var event_location = locations[i];

            // guard
            if (!event_location) {
                continue;
            }

            var LatLng = new google.maps.LatLng(event_location[1], event_location[2]);
            this.marker_arr[i] = this.getMarker();
            this.marker_arr[i].setIcon(this.getMarkerIcon("blue"));
            this.marker_arr[i].setTitle(event_location[0]);
            this.marker_arr[i].setPosition(LatLng);

            var windowHtml = event_location[4];

            this.openInfoWindow(this.marker_arr[i], windowHtml);
        };
    },

    /**
     * open an infowindow
     *
     * @return void
     */
    openInfoWindow: function(marker, windowHtml) {

        var thisObject = this;

        google.maps.event.addListener(marker, "click", function() {

            // close window
            infoWindow.close();

            // change icon
            thisObject.resetMarkers();
            marker.setIcon(thisObject.getMarkerIcon("yellow"));

            // set info window
            var markerLatLng = marker.getPosition();
            infoWindow.setPosition(markerLatLng);
            infoWindow.setContent(windowHtml);
            infoWindow.open(thisObject.map, marker);
        });
    }
});


