/**
 * Class for representing a borough -- handles the KML loading and its parsing for finding out all neighborhoods in one borough
 */
function Boroughs(myMap)
{
    this.myMap = myMap;
    this.map = this.myMap.map;
    this.boroughs = new Array();
    this.neighborhoods = new Array();

    this.documents = new Array();
    this.getCount = 0;
}

Boroughs.prototype = new Object();

/**
 * Fetches all KMLs
 */
Boroughs.prototype.loadAll = function()
{
    this.getBoroughKml("/kml/brooklynneighborhoods.kml", "Brooklyn");
    this.getBoroughKml("/kml/queensneighborhoods.kml", "Queens");
    this.getBoroughKml("/kml/manhattanneighborhoods.kml", "Manhatten");
    this.getBoroughKml("/kml/bronxneighborhoods.kml", "Bronx");
    this.getBoroughKml("/kml/statenislandneighborhoods.kml", "Staten Island");
}

Boroughs.prototype.onAllLoaded = function()
{
    this.myMap.updateClosestNeighborhood(true);
}

/**
 * Based on the current map center, tries to determine the neighborhood/borough the map is showing
 */
Boroughs.prototype.findClosestNeighborhood = function()
{
    var coordinates = this.map.getCenter();
    var minSqrDist = 1000000;
    var closest = false;
    for (var i in this.neighborhoods)
    {
        var neighborhood = this.neighborhoods[i];
        if (!neighborhood.neigborhoodName)
            continue;

        // direct match (see the polygon contains function in Neighborhood)
        if (neighborhood.contains(coordinates))
        {
            return neighborhood;
        }

        // tries to figure closes neighborhood from the map center
        var sqrDist = (coordinates.lat() - neighborhood.center.lat()) *
                      (coordinates.lat() - neighborhood.center.lat()) +
                      (coordinates.lng() - neighborhood.center.lng()) *
                      (coordinates.lng() - neighborhood.center.lng());
        if (minSqrDist > sqrDist)
        {
            minSqrDist = sqrDist;
            closest = neighborhood;
        }
    }

    return closest;
}

/**
 * Downloads the borough's KML and calls the parsing method for building the neighborhoods array
 */
Boroughs.prototype.getBoroughKml = function(kml, boroughName)
{
    this.getCount += 1;
    var xmlDocument;
    var self = this;
    if (window.ActiveXObject) // IE
    {
        xmlDocument = new ActiveXObject("Microsoft.XMLDOM");
        this.documents[boroughName] = xmlDocument;
        xmlDocument.async = false;
        xmlDocument.load(kml);
        this.parseBoroughKml(xmlDocument, boroughName);
    }
    else if (XMLHttpRequest) // Safari
    {
        xmlDocument = new XMLHttpRequest();
        this.documents[boroughName] = xmlDocument;
        xmlDocument.onreadystatechange = function(){
                if( xmlDocument.readyState == 4 && xmlDocument.status < 300 ) {
                    self.parseBoroughKml(xmlDocument.responseXML, boroughName);
                }
            };
        xmlDocument.open("GET", kml, true);
        xmlDocument.send(null);
    }
    else if (document.implementation && document.implementation.createDocument) // Mozilla
    {
        xmlDocument = document.implementation.createDocument("", "", null);
        this.documents[boroughName] = xmlDocument;
        xmlDocument.onload = function() {
            self.parseBoroughKml(xmlDocument, boroughName);
        };
        xmlDocument.load(kml);
    }
    else
    {
        alert('Your browser cannot handle this script');
    }
}

/**
 * Creates a Neighborhood instance and adds it to the borough's neighborhoods array
 */
Boroughs.prototype.addNeighborhood = function(boroughName, neigborhoodName, polygonArray)
{
    var neighborhood = new Neighborhood(this.map, boroughName, neigborhoodName, polygonArray);
    this.boroughs[boroughName].push(neighborhood);
    this.neighborhoods[neigborhoodName] = neighborhood;
}

/**
 * Kml document parsing for finding all neighborhoods
 */
Boroughs.prototype.parseBoroughKml = function(element, boroughName)
{
    this.getCount -= 1;

    this.boroughs[boroughName] = new Array();

    // var tagName = "New_York_City__" + boroughName.replace(" ", "_") + "_Neighborhood_boundaries";
    // var neigborhoodElements = element.getElementsByTagName(tagName);
    var neigborhoodElements = element.getElementsByTagName("Placemark");
    for (var n = 0; n < neigborhoodElements.length; n++)
    {
        var neigborhoodElement = neigborhoodElements[n];
        var neigborhoodName = neigborhoodElement.getElementsByTagName("name")[0].childNodes[0].nodeValue;
        // neigborhoodName = neigborhoodName.replace("NBH-US-NY-New York-", "");

        var coordinatesElements = neigborhoodElement.getElementsByTagName("coordinates");
        var polygons = new Array();
        for (var c = 0; c < coordinatesElements.length; c++)
        {
            var latLngArray = new Array();

            var coordinatesElement = coordinatesElements[c];
            var coordinatesRaw = '';
            if (window.ActiveXObject) {
              // IE way
              var coordinatesRaw = coordinatesElement.childNodes[0].nodeValue;              
            } else if (coordinatesElement.textContent){
              var coordinatesRaw = coordinatesElement.textContent;
            }
            //var coordinatesRaw = coordinatesElement.innerText || coordinatesElement.textContent;
            var coordinates = coordinatesRaw.split(/\s+/); //childNodes[0].nodeValue.split(/\s+/);
            for (var l = 0; l < coordinates.length; l++)
            {
                var coordinate = coordinates[l];
                if (coordinate == "")
                    continue;

                var latLng = coordinate.split(",");
                latLngArray.push(new GLatLng(parseFloat(latLng[1]), parseFloat(latLng[0])));
            }

            var polygon = new Polygon(latLngArray);
            /*
            if (polygon.centroid == false)
                alert(neigborhoodName + " " + c);
            */
            polygons.push(polygon);
        }
        this.addNeighborhood(boroughName, neigborhoodName, polygons);
    }

    if (this.getCount == 0) {
        this.onAllLoaded();
    }
}
