﻿var map = null;
var markerManager = null;
var geocoder = null;
var fullLocationData = new Array(); // 1-dimensional
var locationData = new Array(); // 2-dimensional - type and location
var companyTypeData = new Array();
var typeListID = null;

function loadMap() {
    if (GBrowserIsCompatible()) {

        map = new GMap2(document.getElementById("customerMap"));
        map.setCenter(new GLatLng(-37.841345, 144.977417), 8);
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());
        map.enableScrollWheelZoom();

        markerManager = new GMarkerManager(map, { maxZoom: 19 });

        loadData();
    }
}

function loadData() {

    GDownloadUrl("./services/customerlist.ashx", function(data) {
        var xml = GXml.parse(data);
        var locations = xml.documentElement.getElementsByTagName("customer");
        for (var i = 0; i < locations.length; i++) {

            var location = new Location();
            location.loadFromXml(locations[i]);
            fullLocationData.push(location);
        }
        initialize();
    });
}

function initialize() {
    var markers = new Array(); // holds all location markers

    loadCompanyTypes();

    for (var i = 0; i < fullLocationData.length; i++) {
        if (fullLocationData[i].isValid()) {
            Debug.write("Adding marker for " + fullLocationData[i].name);
            fullLocationData[i].bindMarkerEvents(map);
            markers.push(fullLocationData[i].marker);
        }
    }

    markerManager.addMarkers(markers, 1); // add all location markers to map
    markerManager.refresh();
    showMarkersForType();

}

function showMarkersForType() {
    var type = getSelectedCompanyType();
    for (var i = 0; i < fullLocationData.length; i++) {
        if (fullLocationData[i].marker != null) {
            if (type == null || fullLocationData[i].type == type) {
                fullLocationData[i].marker.show();
            } else {
                fullLocationData[i].marker.hide();
            }
        }
    }
}

function geoCodeLocation(location) {

    var complete = false;

    Debug.write("Attempting to geocoding location '" + location.address + "'");

    if (location.address == null) {
        Debug.write("Aborting geocode");
        return;
    }

    getGeoCoder().getLatLng(location.address, function(latLng) {
        if (latLng != null) {
            Debug.write("Geocoded location '" + location.address + "' = " + latLng.lat() + ", " + latLng.lng());
            location.marker = new GMarker(latLng);
        }
        else {
            Debug.write("Geocoding location '" + location.address + "' failed");
            location.marker = null;
        }
        complete = true;
    });

    var i = 0;

    while (i < 500 && !complete) {
        i++;
    }

}

function geoCodeAddress(address, callback) {

    Debug.write("Attempting to geocoding address '" + address + "'");

    if (address == null) {
        Debug.write("Aborting geocode");
        return;
    }

    getGeoCoder().getLatLng(address, function(latLng) {
        if (latLng != null) {
            Debug.write("Geocoded address '" + address + "' = " + latLng.lat() + ", " + latLng.lng());
        }
        else {
            Debug.write("Geocoding address '" + address + "' failed");
        }

        callback(latLng);
    });

}

function getGeoCoder() {

    if (geocoder == null) {
        geocoder = new GClientGeocoder();
    }

    return geocoder;

}

function findNearestLocations(address, locationType, maxResults) {

    displayLoading();
    hideSearchResults();

    address = address + ", victoria, australia";

    geoCodeAddress(address, function(addressLatLng) {

        if (addressLatLng != null) {

            var locations;
            var nearestLocations = new Array();

            if (locationType == null) {
                locations = fullLocationData;
            }
            else {
                locations = locationData[locationType];
            }

            Debug.write("Calculating distances...");
            for (var i = 0; i < locations.length; i++) {
                if (locations[i].isValid()) {
                    locations[i].dist = locations[i].marker.getLatLng().distanceFrom(addressLatLng);
                }
            }

            Debug.write("sorting");
            locations.sort(function(a, b) { return (a.dist - b.dist) });
            Debug.write("sorted");

            var resultsAdded = 0;

            for (var index = 0; index < locations.length && resultsAdded < maxResults; index++) {
                if (locations[index].dist != null) {
                    Debug.write((index + 1) + " - " + locations[index].name + ", " + locations[index].dist);
                    nearestLocations.push(locations[index]);
                    resultsAdded++;
                }
            }

            map.setCenter(addressLatLng, 12);
            displaySearchResults(nearestLocations);

        }
        else {
            hideLoading();
            Debug.write("Failed to locate address");
        }

    });

}

function displaySearchResults(results) {

    var searchResultsElement = document.getElementById("searchResults");

    document.getElementById("searchResultsContainer").style.display = "";

    while (searchResultsElement.childNodes.length > 0) {
        searchResultsElement.removeChild(searchResultsElement.childNodes[0]);
    }

    for (var i = 0; i < results.length; i++) {

        var listItem = document.createElement("li");
        var link = document.createElement("a");
        //var div = document.createElement("div");

        link.setAttribute("href", "javascript:displayCompany(" + results[i].id + ");");
        link.innerHTML = results[i].name + " (" + Math.round(results[i].dist / 1000) + " km)";

        searchResultsElement.appendChild(listItem);
        listItem.appendChild(link);
        //div.appendChild(link);
    }

    hideLoading();

}

function hideSearchResults() {
    document.getElementById("searchResultsContainer").style.display = "none";
}

function displayCompany(id) {

    for (var i = 0; i < fullLocationData.length; i++) {
        if (fullLocationData[i].id == id) {
            map.panTo(fullLocationData[i].marker.getLatLng());
            fullLocationData[i].displayInfoWindow();

        }
    }
}

function getSelectedCompanyType() {

    var type = document.getElementById(typeListID).value;

    if (type == null || type.length == 0) {
        return null;
    }

    return type;
}

function loadCompanyTypes() {

    for (var i = 0; i < fullLocationData.length; i++) {

        var companyType = fullLocationData[i].type;
        var foundType = false;

        if (companyType != null && companyType.length > 0) {
            for (var j = 0; j < companyTypeData.length; j++) {
                if (companyTypeData[j] == companyType) {
                    foundType = true;
                    break;
                }
            }

            if (!foundType) {
                companyTypeData.push(companyType);
                locationData[companyType] = new Array();
            }
        }
    }

    for (var i = 0; i < fullLocationData.length; i++) {
        var entry = fullLocationData[i];
        if (entry.type != null && entry.type.length > 0 && entry.isValid()) {
            locationData[entry.type].push(entry);
        }
    }
    
    var typeListElement = document.getElementById(typeListID);

    while (typeListElement.length > 1) {
        typeListElement.remove(1);
    }

    for (var i = 0; i < companyTypeData.length; i++) {
        createListItem(companyTypeData[i], companyTypeData[i], typeListElement);
    }

}

function createListItem(text, value, listElement) {
    var listItem = document.createElement("option");
    listItem.setAttribute("value", value);
    listItem.innerHTML = text;
    listElement.appendChild(listItem);
}

function displayLoading() {
    document.getElementById("loadingImage").style.display = "";
}

function hideLoading() {
    document.getElementById("loadingImage").style.display = "none";
}