﻿google.load("jquery", "1.3.2");
google.load('jqueryui', '1.5.3');
google.load("maps", "2.x", { "other_params": "sensor=false" });

google.setOnLoadCallback(function() {
	$(document).ready(function() {
		initializeDealerLocator();
	});
});

var map;
var that = this;
var selectedCountry;
var json;
var allmarkers = [];
var foundmarkers = []

function tick() {
    // console.log(what);
} 

function initializeDealerLocator() {
	map = new GMap2(document.getElementById("map"));
	/*if (google.loader.ClientLocation) {
		var cl = google.loader.ClientLocation;
		showAddress(cl.address.country);
	}
	else {*/
		map.setCenter(new GLatLng(20, 0), 2);
	//}
	//map.setUIToDefault();
	plotStores();
	moveListeners();
	maxZoomLevel();
	viewOptions();

	//Add click event to submit button
	$("#dealerLocatorSubmit").click(function() { findAddress(); });
	$("#ddcountry").change(function() { findAddress(); });
}

function viewOptions() {
	//remove unwanted view options
	//map.removeMapType(G_PHYSICAL_MAP);
	//add wanted views
	//map.addMapType(G_HYBRID_MAP);

	//add controls
	map.addControl(new GLargeMapControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10, 10)));
	map.addControl(new GMapTypeControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(80, 25)));

	map.enableScrollWheelZoom();

}

function maxZoomLevel() {
	G_NORMAL_MAP.getMinimumResolution = function() { return 2 };
	G_SATELLITE_MAP.getMinimumResolution = function() { return 2 };
	G_HYBRID_MAP.getMinimumResolution = function() { return 2 };
}

function moveListeners() {
	GEvent.addListener(map, "zoomend", function(oldZoom, newZoom) {
		//do something when zooming
		visibleDealers();
	});
	GEvent.addListener(map, "moveend", function() {
		//do something when moving
		visibleDealers();
	});
}

function visibleDealers() {
	//Find all dealers visible on map.
	var bounds = map.getBounds();
	lngsw = bounds.getSouthWest().lng();
	lngne = bounds.getNorthEast().lng();
	latsw = bounds.getSouthWest().lat();
	latne = bounds.getNorthEast().lat();

	$.ajax({
		type: "POST",
		url: "/dealers/list",
		data: { latne: bounds.getNorthEast().lat(), latsw: bounds.getSouthWest().lat(), lngne: bounds.getNorthEast().lng(), lngsw: bounds.getSouthWest().lng() },
		success: function(theResponse) {
			var $holder = theResponse;
			$("#DealerList").html($($holder).html());
			initContactDealer();
			//$(".CountryContainer h1:contains('" + selectedCountry + "')").parent().insertBefore('.CountryContainer:first');
		}
    });
}

function createMarker(point, id, level, name) {

    var marker = new GMarker(point, createIcon(level));

    marker.location = point;
    marker.name = name;
    marker.level = level;
    
    GEvent.addListener(marker, 'click', function() {
        marker.openExtInfoWindow(
          map,
          "dealer_window",
          "Loading dealer information...",
          { ajaxUrl: "/dealers/bubble/" + id, beakOffset: 3 }
        );

    });
	
	that.clusterPoints.push(marker);
	allmarkers.push(marker);
	return marker;
}

function createIcon(level) {
	var iceIcon = new GIcon();
	iceIcon.iconSize = new GSize(52, 44);
	
	if (level == 1) {
	    iceIcon.image = "/Content/skin/dealerLocator/dealer_icon_gold.png";
	}
	else if (level == 2) {
	    iceIcon.image = "/Content/skin/dealerLocator/dealer_icon_bronze.png";
	}
	else if (level == 3) {
	    iceIcon.image = "/Content/skin/dealerLocator/dealer_icon_silver.png";
	}
	else {
	    iceIcon.image = "/Content/skin/dealerLocator/dealer_icon.png";
	}

	iceIcon.iconAnchor = new GPoint(26.0, 41.0);
	iceIcon.infoWindowAnchor = new GPoint(9, 2);
	iceIcon.shadow = "/Content/skin/dealerLocator/dealer_icon_shadow.png";
	iceIcon.shadowSize = new GSize(75.0, 44.0);
	markerOptions = { icon: iceIcon };
	return markerOptions;
}

function plotStores() {
    $.ajax({
        type: "POST",
        url: "/dealers/mapping",
        data: { latne: 180, latsw: -180, lngne: 180, lngsw: -180 },
        success: function(theResponse) {
            var object = theResponse;
            json = eval(object);
            var jsonLen = json.length;
            if (jsonLen > 0) {
                clusterPoints = [];
                for (var i = 0; i < jsonLen; i++) {

                    var point = new GLatLng(json[i].spot_lat, json[i].spot_long);
                    var storeId = json[i].id;
                    var storeLevel = json[i].level;
                    var name = json[i].name;
                    var marker = createMarker(point, storeId, storeLevel, name);
                    //map.addOverlay(marker);

                }
                if (!that.cluster) {
                    that.cluster = new ClusterMarker(map, { fitMapToMarkers: false });
                }

                that.cluster.removeMarkers();
                that.cluster.addMarkers(that.clusterPoints);
                that.cluster.refresh();
            }
            initContactDealer();
        }
    });
}

function findAddress() {
	map.closeExtInfoWindow();
	
	var countryString = document.getElementById("ddcountry").value;
	var postcodeString = document.getElementById("postcode").value;
	var search = countryString + ", " + postcodeString;
	if (countryString == "Select Country") {
		search = postcodeString;
	}
	//var search = document.getElementById("ddcountry").value + ", " + document.getElementById("postcode").value;
	showAddress(countryString, postcodeString);
}

function showAddress(country, postcode) {
    var geo = new GClientGeocoder();
    var search;
    if (country == "Select Country") {
        search = postcode;
    }
    else {
        search = country + ", " + postcode;
    }
	//var search = document.getElementById("search").value;
    geo.getLocations(search, function(result) {
        if (result.Status.code == G_GEO_SUCCESS) {
            // Loop through the results, placing markers
            for (var i = 0; i < result.Placemark.length; i++) {
                var p = result.Placemark[i].Point.coordinates;
                //Add a marker on map
                // PA: reinstated for easier debugging
                var marker = new GMarker(new GLatLng(p[1], p[0]));
                map.addOverlay(marker);
            }

            // centre the map on the first result
            var p = result.Placemark[0].Point.coordinates;

            if (postcode != "") {
                nearestDealer(result.Placemark[0].Point.coordinates[0], result.Placemark[0].Point.coordinates[1]);
            }
            else {
                //console.log(result.Placemark[0].Point.coordinates[0]);
                // ===== Look for the bounding box of the first result =====
                var N = result.Placemark[0].ExtendedData.LatLonBox.north;
                var S = result.Placemark[0].ExtendedData.LatLonBox.south;
                var E = result.Placemark[0].ExtendedData.LatLonBox.east;
                var W = result.Placemark[0].ExtendedData.LatLonBox.west;
                var bounds = new GLatLngBounds(new GLatLng(S, W), new GLatLng(N, E));
                // Choose a zoom level that fits
                var zoom = map.getBoundsZoomLevel(bounds);
                map.setCenter(bounds.getCenter(), zoom);

                //Draw a bounding box around found area
                //var points = [new GLatLng(N, W), new GLatLng(N, E), new GLatLng(S, E), new GLatLng(S, W), new GLatLng(N, W)];
                //map.addOverlay(new GPolyline(points));
            }
            //Move country dealers to top
            selectedCountry = document.getElementById("ddcountry").value;

        }
    });
}

function showNearestDealer(lat1, lon1) {
    var markerBounds = new GLatLngBounds();
    markerBounds.extend(new GLatLng(lon1, lat1));
    markerBounds.extend(new GLatLng(foundmarkers[0].location.y, foundmarkers[0].location.x));
    // Choose a zoom level that fits

    map.setCenter(markerBounds.getCenter(), map.getBoundsZoomLevel(markerBounds)-1);
}

function nearestDealer(lat1, lon1) {
    foundmarkers.length = 0;
    for (var i = 0; i < allmarkers.length; i++) {
        var marker = allmarkers[i];
        marker.distance = calcDistance(lat1, lon1, marker.location.x, marker.location.y);
        foundmarkers.push(marker);
    }
    foundmarkers.sort(sortDistance);

    // Debug
    //for (var i = 0; i < foundmarkers.length; i++) {
    //    console.log(foundmarkers[i].name + ":" + foundmarkers[i].distance);
    //}

    showNearestDealer(lat1, lon1);
}

function sortDistance(a, b) {
    if (a.distance < b.distance)
        return -1;
    if (a.distance > b.distance)
        return 1;
    return 0;
}

function calcDistance(lat1, lon1, lat2, lon2) {
    var R = 6371; // km
    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
        Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
        Math.sin(dLon / 2) * Math.sin(dLon / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    return R * c;
}

Number.prototype.toRad = function() { return this * Math.PI / 180; }  // convert degrees to radians
Number.prototype.toDeg = function() { return this * 180 / Math.PI; }  // convert radians to degrees (signed)
