var amap;

$(document).ready(function() {
    amap = new Map();
});

var Map = function Map() {
    var map;
    var markersArray = new Array();
    var iwArray = new Array();
    var polygon;
    var geocoder = new google.maps.Geocoder();

    this.NElat = 0;
    this.NElng = 0;
    this.SWlat = 0;
    this.SWlng = 0;
    
    this.initCanvas = function(canvas, options, streetViewControl) {
        if (!options) {
            latlng = new google.maps.LatLng(51.4, 12);
            zoom = 6;

            options = new Object();
            options.zoom = zoom;
            options.center = latlng;
            options.mapTypeId = google.maps.MapTypeId.ROADMAP;
            options.scrollwheel = false;
            if(streetViewControl) {
                options.streetViewControl = true;
            } else {
                options.streetViewControl = false;
            }
        }

        map = new google.maps.Map(document.getElementById(canvas), options);

        return map;
    }

    /**
     * Triggers Event on the Object
     */
    this.triggerEvent = function(object, event) {
        google.maps.event.trigger(object, event);
    }


    /**
     * Converts lat and lng coordinates into Google Maps Point Object
     */
    this.createPoint = function(lat, lng) {
        var point = new google.maps.LatLng(lat, lng);
        return point;
    }


    /**
     * Creates Marker on the current map
     */
    this.createMarker = function(point, caption, content, icon, markerOptions, infowindowOptions) {
        if (!markerOptions) {
            markerOptions = new Object();
        }
        
        if (typeof(markerOptions.clickable) == undefined) {
            markerOptions.clickable = true;
        }
        
        if (typeof(markerOptions.draggable) == undefined) {
            markerOptions.draggable = false;
        }
        
        if (typeof(markerOptions.raiseOnDrag) == undefined) {
            markerOptions.raiseOnDrag = false;
        }
        
        if (!markerOptions.icon && icon) {
            markerOptions.icon = icon;
        }
        
        if (typeof(markerOptions.visible) == undefined) {
            markerOptions.visible = true;
        }
        
        if (!markerOptions.title && caption) {
            markerOptions.title = caption;
        }
        
        if (!markerOptions.position && point) {
            markerOptions.position = point;
        }
        
        if (!markerOptions.map && map) {
            markerOptions.map = map;
        }

        if (!infowindowOptions) {
            infowindowOptions = new Object();
            infowindowOptions.content = content;
            infowindowOptions.maxWidth = 400;
        }
        
        var marker = new google.maps.Marker(markerOptions);
        var infoWindow = new google.maps.InfoWindow();
        infoWindow.setOptions(infowindowOptions);

        if (markerOptions.clickable == true) {
            google.maps.event.addListener(marker, 'click', function() {
                // Only one infowindow at the same time
                for(var i in iwArray) {
                    var iw = iwArray[i]
                    iw.close();
                }
                infoWindow.open(map, marker);
            });
        }

        markersArray[markersArray.length] = marker;
        iwArray[iwArray.length] = infoWindow;
        return marker;
    }

    this.clearMarker = function(marker) {
        if (marker) {
            marker.setMap(null);
        }
    }


    this.drawPolygon = function(path) {
        polygon = new google.maps.Polygon({
            path: path,
            strokeColor: "#FF0000",
            strokeOpacity: 1.0,
            strokeWeight: 1,
            fillColor: "#FF0000",
            fillOpacity: 0.2
        });

        polygon.setMap(map);

        return polygon;
    }

    this.clearPolygon = function(polygon) {
        if (polygon) {
            polygon.setMap(null);
        }
    }


    /**
     * Return icon object for the given number
     */
    this.getIcon = function(number) {
        var name = (number < 10) ? "icon-" + number + ".png" : "icon-common.png";

        var icon = new google.maps.MarkerImage(
            '../img/map/' + name,
            new google.maps.Size(54,58),
            new google.maps.Point(0,0),
            new google.maps.Point(20,58)
            );

        return icon;
    }

    /**
     * Method to download and process given URL
     */
    this.downloadUrl = function(url) {

    }

    /**
     * Returns 'map' variable
     */
    this.getMap = function() {
        return map;
    }


    /**
     * Returns 'infoWindow' variable
     */
    this.getInfoWindow = function() {
        return infoWindow;
    }

    this.showStreetView = function(canvas, point) {
        var panoramaOptions = {
            position:point,
            pov: {
                heading: 165,
                pitch:0,
                zoom:1
            }
        };
        var myPano = new google.maps.StreetViewPanorama(canvas, panoramaOptions);
        myPano.setVisible(true);
    }

    this.clearOverlays = function() {
        if (markersArray) {
            for (i in markersArray) {
                markersArray[i].setMap(null);
            }
        }
        
        markersArray = new Array();
    }

    /**
     * Fixes API problems.
     */
    this.setViewport = function (bounds, callback) {
        var desiredSpan = bounds.toSpan();

        map.fitBounds(bounds);

        google.maps.event.addListenerOnce(map, "bounds_changed", function() {
            // GM bugfix
            $i = 0;
            while ($i++ < 10) {
                if (map.getBounds() == null) {
                    break;
                }
                var newSpan = map.getBounds().toSpan();
                var errorLat = Math.round(Math.abs(newSpan.lat() / desiredSpan.lat()));
                var errorLng = Math.round(Math.abs(newSpan.lng() / desiredSpan.lng()));
                var error = Math.min(errorLat, errorLng);


                if (error >= 2) { // too large
                    map.setZoom(map.getZoom() + 1); // zoom in
                } else if (error == 0) {
                    map.setZoom(map.getZoom() - 1); // zoom out
                } else {
                    break;
                }
            }

            if (typeof callback == "function") {
                callback();
            }
        });
    }


    this.setMaxZoom = function(level) {
        google.maps.event.addListener(map, 'zoom_changed', function() {
            var zoom = map.getZoom();
            if (zoom > level) {
                map.setZoom(level);
            }
        });
    }
    
    this.codeAddress = function(address, callback) {
        geocoder.geocode( {
            'address': address
        }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {

                if (results[0].geometry.bounds) {
                    var NE = results[0].geometry.bounds.getNorthEast();
                    var SW = results[0].geometry.bounds.getSouthWest();
                    bounds = new google.maps.LatLngBounds(SW, NE);
                }

                map.setCenter( bounds.getCenter() );
                map.fitBounds( bounds );
                $("#mapMessage").hide();
                
                amap.updateElements();

                if (typeof callback == "function") {
                    callback(results);
                }

            } else {
                $("#mapMessage").html("Pro zadaný vstup nebyla lokalita nalezena");
            }
        });
    }
    
    this.updateElements = function(callback) {          
        
        amap.NElat = map.getBounds().getNorthEast().lat();
        amap.NElng = map.getBounds().getNorthEast().lng();
        amap.SWlat = map.getBounds().getSouthWest().lat();
        amap.SWlng = map.getBounds().getSouthWest().lng();
 
        $("#NElat").val(amap.NElat);
        $("#NElng").val(amap.NElng);
        $("#SWlat").val(amap.SWlat);
        $("#SWlng").val(amap.SWlng);
        
        if (typeof callback == "function") {
            callback();
        }
    }
}

