﻿var map;
var coordsList;
var mapModel = {
    map: null,
    mapContainer: null,
    mapCenter: null,
    locationsList: [],
    coordinatesList: null,
    markers: [],
    visibleInfoWindow: null,
    searchKey: null,

    generateTriggerCallback: function(object, eventType) {
        return function() {
            google.maps.event.trigger(object, eventType);
        };
    },

    openInfoWindow: function(infoWindow, marker) {
        return function() {
            if (mapModel.visibleInfoWindow) {
                mapModel.visibleInfoWindow.close();
            }
            infoWindow.open(mapModel.map, marker);
            mapModel.visibleInfoWindow = infoWindow;
        };
    },

    clearMarkers: function() {
        for (var n = 0, marker; marker = mapModel.markers[n]; n++) {
            marker.setVisible(false);
        }
    },

    init: function(canvas_name, location) {
        mapModel.mapCenter = new google.maps.LatLng(0, 0);
        mapModel.coordinatesList = new google.maps.LatLngBounds();
        if (typeof location != 'undefined') {
            if (typeof location.Description != 'undefined') {
                mapModel.searchKey = location.Description;
            }
            if (typeof (location.Latitude) != 'undefined' && typeof (location.Longitude) != 'undefined') {
                mapModel.mapCenter = new google.maps.LatLng(location.Latitude, location.Longitude);
                mapModel.coordinatesList.extend(mapModel.mapCenter);
            }
        }

        var myOptions = {
            zoom: 8,
            center: mapModel.mapCenter,
            mapTypeControl: true,
            mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU },
            navigationControl: true,
            navigationControlOptions: { style: google.maps.NavigationControlStyle.SMALL },
            mapTypeId: google.maps.MapTypeId.ROADMAP
        }
        mapModel.mapContainer = document.getElementById(canvas_name);
        if (mapModel.mapContainer != null) {
            mapModel.map = new google.maps.Map(mapModel.mapContainer, myOptions);
        }
        if (mapModel.mapCenter.toUrlValue() != '0,0') {
            var marker = new google.maps.Marker({
                map: mapModel.map,
                position: mapModel.mapCenter,
                icon: '/Content/images/tracking_icons/map/delivery_origin.png'
            });
        }
    },

    goGetPinpoints: function(containerSelector) {
        $(containerSelector).each(
            function(i) {
                var location = mapModel.extractLocation(this);
                mapModel.locationsList.push(location);
                if (location.coords == null) {
                    var geocoder = new google.maps.Geocoder();

                    SubmitGeocodingRequest(geocoder, location, this);

                } else {
                    var marker = mapModel.addLocationToMap(location);
                    $(this).bind("click", mapModel.generateTriggerCallback(marker, "click"));
                }
            }
        );
    },

    extractLocation: function(locationBlock) {
        var location = new Object();
        location.entityId = $.trim($(locationBlock).attr("id")).split("_")[1];
        location.entityName = $.trim($(locationBlock).find(".FilterResultsHeader").text());
        location.addressid = $.trim($(locationBlock).find(".address").attr("id")).split("_")[1];
        location.address1 = $.trim($(locationBlock).find(".address-line1").text());
        location.address2 = $.trim($(locationBlock).find(".address-line2").text());
        location.city = $.trim($(locationBlock).find(".address-city").text());
        location.region = $.trim($(locationBlock).find(".address-region").text());
        location.postalcode = $.trim($(locationBlock).find(".address-postalcode").text());
        location.coords = mapModel.extractAddressCoords($(locationBlock).find(".address")); // eval($.trim($(locationBlock).find(".address").attr("coords")).toLowerCase());
        location.logo = $.trim($(locationBlock).find(".logo").attr("src"));
        return location;
    },

    extractAddressCoords: function(address) {
        var rawCoords = $.trim($(address).attr("coords")).toLowerCase();
        var parsedCoords = rawCoords.split(",");
        if (parsedCoords.length == 2) {
            return new google.maps.LatLng(parseFloat(parsedCoords[0]), parseFloat(parsedCoords[1]));
        }
        else {
            return null;
        }
    },

    addLocationToMap: function(location) {
        mapModel.coordinatesList.extend(location.coords);
        var marker = new google.maps.Marker({
            map: mapModel.map,
            position: location.coords,
            icon: location.logo
        });
        mapModel.markers.push(marker);

        var infoWindow = mapModel.createInfoWindow(location);

        google.maps.event.addListener(infoWindow, 'closeclick', function() { mapModel.recenterMap(); /*.map.panTo(mapModel.coordinatesList.getCenter())*/ });
        google.maps.event.addListener(marker, 'click', mapModel.openInfoWindow(infoWindow, marker));   //Demo.openInfoWindow(infoWindow, marker));
        mapModel.recenterMap(); //.map.setCenter(mapModel.coordinatesList.getCenter());
        mapModel.map.fitBounds(mapModel.coordinatesList);
        return marker;
    },

    createInfoWindow: function(location) {
        return new google.maps.InfoWindow({
            content: [
              '<h3 style="">',
              location.entityName,
              '</h3>',
              '<div style="font-size: 0.8em;">',
              location.address1 + (location.address2 != '' ? '<br />' + location.address2 : ''),
              '<br />',
              location.city + ' ' + location.region + ' ' + location.postalcode,
              '<br />',
              '<form method="get" action="http://maps.google.com/maps" target="_blank">',
                '<input type="hidden" name="daddr" value="' + location.address1 + ' ' + location.city + ' ' + location.region + ' ' + location.postalcode + '">',
                '<input type="text" name="saddr" style="width: 110px;" value="' + (mapModel.searchKey != null ? mapModel.searchKey : '') + '">',
            	'<input type="submit" value="Directions">',
            '</form>',
              '</div>'
            ].join('')
        });
    },

    recenterMap: function() {
        mapModel.map.panTo(mapModel.coordinatesList.getCenter());
    }
};



function SubmitGeocodingRequest(geocoder, location, elementToBind) {
    var request = CreateGeocodeRequest(location);
    geocoder.geocode(request,
        function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                result = GetBestGeocodedResult(results);
                PushGeocodedData(result, location);
                location.coords = result.geometry.location;
                var marker = mapModel.addLocationToMap(location);
                $(elementToBind).bind("click", mapModel.generateTriggerCallback(marker, "click"));
            } else {
                //alert("Geocode was not successful for the following reason: " + status);
            }
        });
}

function CreateGeocodeRequest(locationToGeocode) {
    return {
        'address': locationToGeocode.address1 + '\n' + locationToGeocode.address2 + '\n' + locationToGeocode.city + ' ' + locationToGeocode.region + ' ' + locationToGeocode.postalcode
    };
}

function GetBestGeocodedResult(results) {
    if (results.length == 0) {
        return null;
    }
    else if (results.length == 1) {
        return results[0];
    }
    else {
        return results.sort(SortResults)[0];
    }
}

function PushGeocodedData(result, locationToGeocode) {
    result.__RequestVerificationToken = document.getElementsByName('__RequestVerificationToken')[0].value;
    result.providerid = locationToGeocode.entityId;
    result.addressid = locationToGeocode.addressid;
    var data = GetGeocodedPostObject(result);
    $.post('/Address/Geocode', data);
}

function SortResults(result1, result2) {
    return MappedResultPriority(result1) - MappedResultPriority(result2);
}

function MappedResultPriority(result) {
    switch (result.geometry.location_type) {
        case "ROOFTOP": return 0;
        case "RANGE_INTERPOLATED": return 1;
        case "GEOMETRIC_CENTER": return 2;
        case "APPROXIMATE": return 3;
        default: return 999;
    }
}

function GetGeocodedPostObject(result) {
    return {
        "providerid": result.providerid,
        "addressid": result.addressid,
        "latitude": result.geometry.location.lat(),
        "longitude": result.geometry.location.lng(),
        "__RequestVerificationToken": document.getElementsByName('__RequestVerificationToken')[0].value,
        "address1": GetAddress1(result.address_components),
        "city": GetCity(result.address_components),
        "region": GetRegion(result.address_components),
        "country": GetCountry(result.address_components),
        "postalcode": GetPostalCode(result.address_components)
    }
}

function GetAddress1(address_components) {
    //$.each(address_components, function
    return GetAddressPart(address_components, "street_number") + GetAddressPart(address_components, "route");
}

function GetCity(address_components) {
    return GetAddressPart(address_components, "locality");
}

function GetRegion(address_components) {
    return GetAddressPart(address_components, "administrative_area_level_1");
}

function GetCountry(address_components) {
    return GetAddressPart(address_components, "country");
}

function GetPostalCode(address_components) {
    return GetAddressPart(address_components, "postal_code");
}

function GetAddressPart(address_components, descriptor) {
    var result = "";
    $.each(address_components, function() {
        if (this.types[0] == descriptor) {
            result = this.short_name;
        }
    });
    return result;
}