
var Cagi_GMap = {

    objects: {},

    map: {},

    markers: [],

    windows: [],

    currentObject: '',

    userLocationMarker: {},

    userLocationWindow: {},

    country: 'Sweden',

    init: function(lat, lng, objects) {
        this.objects = objects;
        this.latlng = new google.maps.LatLng(lat, lng);
        this.mapOptions = {
            zoom: 6,
            center: this.latlng,
            scaleControl: true,
            navigationControl: true,
            navigationControlOptions: {
                style: google.maps.NavigationControlStyle.ZOOM_PAN,
                position: google.maps.ControlPosition.TOP_LEFT
            },
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        this.map = new google.maps.Map(document.getElementById("map_canvas"), this.mapOptions);
        this.map.setCenter(this.latlng);
        this.geocoder = new google.maps.Geocoder();
        
        // bind events
        this.bindEvents();

    },

    setMapOptions: function(options) {
        // change some default settings
        for (k in options) {
            this.mapOptions[k] = options[k];
        }

        this.map = new google.maps.Map(document.getElementById("map_canvas"), this.mapOptions);
        this.map.setCenter(this.latlng);
    },

    bindEvents: function() {
        var counter = 0;
        for (var c in this.objects) {
            this.markers[c] = new google.maps.Marker({
                draggable: true,
                id: this.objects[c].id,
                icon: "/images/gmap/" + this.objects[c].icon + ".png"
            });
            this.windows[c] = new google.maps.InfoWindow({
                content: '',
                size: new google.maps.Size(30,30)
            });
            this.objects[c].index = counter;

            google.maps.event.addListener(this.markers[c], 'dragend', function(e) {
                Cagi_GMap.currentObject = this.id;
                Cagi_GMap.findByCoordinates(e.latLng);
            });

            google.maps.event.addListener(this.markers[c], 'drag', function(e) {
                Cagi_GMap.windows[this.id].close();
            });

            $(this.objects[c].addressInput).bind('blur', {c: c} , function(e){
                var city = $(Cagi_GMap.objects[e.data.c].locationInput).val();
                if ($(Cagi_GMap.objects[e.data.c].locationIdInput).val() == 0) {
                    alert('Invalid city');
                    $(this).val('');
                    $(Cagi_GMap.objects[e.data.c].locationInput).focus();
                    return;
                }
                Cagi_GMap.currentObject = Cagi_GMap.objects[e.data.c].id;
                if ($(this).val() == "") {
                    return;
                }
                Cagi_GMap.findByAddress($(this).val() + ', ' + city + ', ' + Cagi_GMap.country);
            });

            $(this.objects[c].locationInput).bind('blur', {c: c} , function(e){
                var city = $(Cagi_GMap.objects[e.data.c].locationInput).val();
                var address = $(Cagi_GMap.objects[e.data.c].addressInput).val();
                if (address == '') {
                    return;
                };
                Cagi_GMap.currentObject = Cagi_GMap.objects[e.data.c].id;
                Cagi_GMap.findByAddress(address + ', ' + city + ', ' + Cagi_GMap.country);
            });

            $(this.objects[c].addressInput).bind('loadsaved', {c: c} , function(e){
                var city = $(Cagi_GMap.objects[e.data.c].locationInput).val();
                Cagi_GMap.currentObject = Cagi_GMap.objects[e.data.c].id;
                Cagi_GMap.loadByAddress();
            });

            $(this.objects[c].locationInput).bind('focus', {c: c} , function(e){
                Cagi_GMap.currentObject = Cagi_GMap.objects[e.data.c].id;
            });
            $(this.objects[c].addressInput).bind('focus', {c: c} , function(e){
                Cagi_GMap.currentObject = Cagi_GMap.objects[e.data.c].id;
            });
            
            if (counter == 0) {
                Cagi_GMap.currentObject = Cagi_GMap.objects[c].id;
                google.maps.event.addListener(Cagi_GMap.map, 'click', function(event) {
                    Cagi_GMap.findByCoordinates(event.latLng);
                });
            }
            counter++;
        }
    },
    loadByAddress: function(address) {
        var c = Cagi_GMap.currentObject;
        var location = new google.maps.LatLng($(Cagi_GMap.objects[c].lat).val(), $(Cagi_GMap.objects[c].lng).val());
        Cagi_GMap.map.setCenter(location);
        Cagi_GMap.markers[c].setMap(Cagi_GMap.map);
        Cagi_GMap.markers[c].setPosition(location);
        Cagi_GMap.windows[c].open(Cagi_GMap.map, Cagi_GMap.markers[c]);
    },

    findByAddress: function(address) {
        var c = Cagi_GMap.currentObject;
        Cagi_GMap.geocoder.geocode({'address': address}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (!Cagi_GMap.isValidResult(results[0].formatted_address)) {
                    Cagi_GMap.deleteObject(c);
                    $(Cagi_GMap.objects[c].addressInput).val('');
                    alert('Invalid address');
                    return false;
                }

                Cagi_GMap.map.setCenter(results[0].geometry.location);

                Cagi_GMap.markers[c].setMap(Cagi_GMap.map);
                Cagi_GMap.markers[c].setPosition(results[0].geometry.location);

                var address = results[0].formatted_address.split(',');
                
                Cagi_GMap.windows[c].setContent(Cagi_GMap.objects[c].prefix +  address[0]);
                Cagi_GMap.windows[c].open(Cagi_GMap.map, Cagi_GMap.markers[c]);

                $(Cagi_GMap.objects[c].addressInput).val(address[0]);

                $(Cagi_GMap.objects[c].lat).val(results[0].geometry.location.lat());
                $(Cagi_GMap.objects[c].lng).val(results[0].geometry.location.lng());
            } else {
                alert('Invalid address');
                $(Cagi_GMap.objects[c].addressInput).val('');
                $(Cagi_GMap.objects[c].locationInput).val('');
            }
        });
    },

    findByCoordinates: function(latLng) {
        var c = Cagi_GMap.currentObject;
        Cagi_GMap.geocoder.geocode({'latLng': latLng}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (!Cagi_GMap.isValidResult(results[0].formatted_address)) {
                    Cagi_GMap.deleteObject(c);

                    alert('Invalid address. Please choose another address.');
                    $(Cagi_GMap.objects[c].addressInput).val('');
                    return false;
                }

                Cagi_GMap.map.setCenter(results[0].geometry.location);
                $.ajax({
                    async: false,
                    url: '/ajax/find-location/',
                    dataType: 'json',
                    data: {lat: results[0].geometry.location.lat(), lng: results[0].geometry.location.lng()},
                    success: function(response){
                        $(Cagi_GMap.objects[c].locationInput).val(response[0].name);
                        $(Cagi_GMap.objects[c].locationIdInput).val(response[0].id);
                    }
                });

                Cagi_GMap.markers[c].setMap(Cagi_GMap.map);
                Cagi_GMap.markers[c].setPosition(results[0].geometry.location);

                var address = results[0].formatted_address.split(',');

                Cagi_GMap.windows[c].setContent(Cagi_GMap.objects[c].prefix + address[0]);
                Cagi_GMap.windows[c].open(Cagi_GMap.map, Cagi_GMap.markers[c]);
                $(Cagi_GMap.objects[c].addressInput).val(address[0]);

                $(Cagi_GMap.objects[c].lat).val(results[0].geometry.location.lat());
                $(Cagi_GMap.objects[c].lng).val(results[0].geometry.location.lng());

            } else {
                alert('Invalild coords');
            }
        });
    },

    deleteObject: function(id) {
        if (Cagi_GMap.markers[id] instanceof google.maps.Marker) {
            Cagi_GMap.markers[id].setMap(null);
        }
        if (Cagi_GMap.windows[id] instanceof google.maps.InfoWindow) {
            Cagi_GMap.windows[id].close();
        }
    },

    isValidResult: function(result) {
        var location = result.split(',');
        if (location.length == 3) {
            return true;
        }
        return false;
    },

    setCenter: function(lat, lng) {
        var latLng = this.latlng = new google.maps.LatLng(lat, lng);
        this.map.setCenter(latLng);
    },

    showItems: function(data) {
        for (i = 0; i < data.length; i++) {
            var latLng = new google.maps.LatLng(data[i].lat, data[i].lng);
            var marker = [];
            marker[i] = new google.maps.Marker({
                map: Cagi_GMap.map,
                title: data[i].title,
                text: data[i].link,
                position: latLng,
                icon: "/images/gmap/item.png"
            });
            google.maps.event.addListener(marker[i], 'click', function(e) {
                var infoWindow = new google.maps.InfoWindow({
                    content: "<a href='" + this.text + "'/>" + this.title + "</a>",
                    size: new google.maps.Size(30,30)
                });
                infoWindow.open(Cagi_GMap.map, this);
            });
        }
    },

    setUserLocation: function(lat, lng) {
        var latLng = new google.maps.LatLng(Cagi_Cookie.findByName('user_lat', lat), Cagi_Cookie.findByName('user_lng', lng));
        this.userLocationMarker = new google.maps.Marker({
            draggable: true,
            id: 'userMarker',
            icon: "/images/gmap/user.png"
        });
        this.userLocationWindow = new google.maps.InfoWindow({
            content: '',
            size: new google.maps.Size(30,30)
        });
        
        this.userLocationMarker.setMap(Cagi_GMap.map);
        this.userLocationMarker.setPosition(latLng);
        
        // bind events
        google.maps.event.addListener(this.userLocationMarker, 'dragend', function(e) {
            Cagi_GMap.fundUserLocationByCoordinates(e.latLng);
        });
        google.maps.event.addListener(Cagi_GMap.map, 'click', function(e) {
            Cagi_GMap.fundUserLocationByCoordinates(e.latLng);
        });

    },

    fundUserLocationByCoordinates: function(latLng) {
        Cagi_GMap.geocoder.geocode({'latLng': latLng}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (!Cagi_GMap.isValidResult(results[0].formatted_address)) {
                    alert('Invalid address. Please choose another address.');
                    return false;
                }
                Cagi_GMap.userLocationMarker.setPosition(results[0].geometry.location);
                Cagi_GMap.userLocationWindow.setContent('Your location');
                Cagi_GMap.userLocationWindow.open(Cagi_GMap.map, Cagi_GMap.userLocationMarker);
                $.ajax({
                    async: false,
                    url: '/ajax/find-location/',
                    dataType: 'json',
                    data: {lat: results[0].geometry.location.lat(), lng: results[0].geometry.location.lng()},
                    success: function(response){
                        // XXX use Cagi_Cookie for cookies
                        document.cookie = "user_lat=" + results[0].geometry.location.lat() + "; expires=21/12/2012 00:00:00; path=/;";
                        document.cookie = "user_lng=" + results[0].geometry.location.lng() + "; expires=21/12/2012 00:00:00; path=/;";
                        document.cookie = "user_location_id=" + response[0].id + "; expires=21/12/2012 00:00:00; path=/;";
                        $("#top-search-form").submit();
                    }
                });

            } else {
                alert('Invalild location by coords');
            }
        });
    }

}

