var map;
var currentMarker;
var currentInfoWindow;
var pollMarker;
var pollInfoWindow;
var currentBounds;

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regexS = "[\\?&]" + name + "=([^&#]*)";
    var regex = new RegExp(regexS);
    var results = regex.exec(window.location.href);
    if (results == null)
        return "";
    else
        return decodeURIComponent(results[1].replace(/\+/g, " "));
}

function setMarker(geocoderResult, map) {
    if (currentMarker) currentMarker.setMap(null);

    var addressInfo = '';
    $.each(geocoderResult.address_components, function (index, value) {
        addressInfo = value.long_name + ' (' + value.types[0] + ')\n';
        //alert(addressInfo); 
    });

    currentMarker = new google.maps.Marker({
        position: geocoderResult.geometry.location,
        map: map
    });

    centerAndZoom(map, currentMarker);
    return currentMarker;
};

// Close the currentInfoWindow, if possible.
function closeCurrentInfoWindow() {
    if (currentInfoWindow) currentInfoWindow.close();
}

function clearAllMarkers() {
    closeCurrentInfoWindow();
    if (currentMarker) currentMarker.setMap(null);
    if (pollMarker) pollMarker.setMap(null);
};

/*
* Centers the map on the given marker.
*/
function centerOn(marker) {
    map.setCenter(marker.getPosition());
};

/*
* Centers the map on the given marker and sets zoom level to 15.
*/
function centerAndZoom(map, marker) {
    centerOn(marker);
    map.setZoom(15);
};

function getPointAtResult(geocoderResult, map) {
    var marker = setMarker(geocoderResult, map);

    /*
    google.maps.event.addListener(marker, "click", function() {
    if (currentInfoWindow) {
    currentInfoWindow.close();
    }
    });
    */

    return getElectedOfficialsForResult(geocoderResult, marker.getPosition());
};

/*
* Parses geocoder results and lists them in the results sidebar.
*/
function listResults(results) {
    var output = "<p>Google Maps found the following results for the address you entered:</p>";

    currentResults = results;
    $.each(results, function (index, result) {
        if (result) {
            var addressLine = "{street_number} {route}, {locality} ({administrative_area_level_2}, {administrative_area_level_1})";
            //get house number
            var skip = false;
            $.each(result.address_components, function (index, component) {
                if (component) {
                    $.each(component.types, function (index, type) {
                        if (type) {
                            if (type == 'administrative_area_level_1' && component.long_name != 'Maryland') {
                                skip = true;
                                //alert('admin level 1 = ' + component.long_name);
                            }

                            addressLine = addressLine.replace('{' + type + '}', component.long_name);
                        }
                    });
                }
            });
            addressLine = addressLine.replace(/\{.*?\}/g, '');
            if (!skip) output += '<p><a href="#" onclick="getPointAtIndex(' + index + ')">' + addressLine + '</a></p>';
        }
    });
    $('#results').html(output);
};

/*
* Geocodes the given address:
* If no results are found, an error message is shown.
* If one result is found, the elected officials/polling place for the given result are shown.
* If more than one result is found, The results are listed for the user to select one.
*/
function getPointAtAddress(address) {
    var lowerAddress = address.toLowerCase();
    if (lowerAddress.indexOf('maryland') == -1 && lowerAddress.indexOf('md') == -1) address += ', Maryland';

    geocoder.geocode({ address: address }, function (results, status) {
        if (status != google.maps.GeocoderStatus.OK || results.length == 0 || getComponentOfType(results[0], 'street_number') == undefined) {
            //alert(address);
            getElectedOfficialsByInput(address);
            //alert('Google Maps could not find the given address.');
        }
        else if (results.length > 1) {
            listResults(results);
        }
        else {
            if (!getPointAtResult(results[0], map)) {
                alert("Could not find the given address. Google Maps returned a faulty address.");
            }
        }
    });
};

/*
* Finds the address component within the given geocode result that is of the given component type. 
*/
function getComponentOfType(result, type) {
    var output = undefined;
    $.each(result.address_components, function (index, component) {
        if (component) {
            $.each(component.types, function (index, value) {
                if (value) {
                    if (value == type) {
                        output = component;
                    }
                }
            });
        }
    });
    return output;
};

function getPointAtIndex(index) {
    getPointAtResult(currentResults[index], map);
};

function showLoadingImage() {
    $('#results').html('<img src="graphics/ajax-loader.gif" alt="loading" style="width: 100px; height: 100px; margin-top: 250px; margin-left: 74px;"/>');
};

function getElectedOfficialsByInput(input) {
    showLoadingImage();

    $.ajax({
        url: 'GetElectedOfficials.aspx',
        type: 'GET',
        data: { use: 'input',
            input: input
        },
        dataType: 'html',
        success: function (data, textStatus, XMLHttpRequest) {
            $('#results').html(data);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert("An error occurred while looking for your address's election information."
                     + " use=input" + "&input=" + input
                     );
        }
    });

}

function getElectedOfficials(street_number, route, county, zip_code, location) {
    showLoadingImage();

    $.ajax({
        url: 'GetElectedOfficials.aspx',
        type: 'GET',
        data: { use: 'address',
                street_number: street_number,
                route: route,
                county: county,
                zip_code: zip_code,
                lat: location.lat(),
                lon: location.lng() },
        dataType: 'html',
        success: function (data, textStatus, XMLHttpRequest) {
            $('#results').html(data);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert("An error occurred while looking for your address's election information."
                     + " use=address" + "&street_number=" + street_number + "&route=" + route + "&county=" + county + "&zip_code=" + zip_code + "&lat=" + location.lat() + "&lon=" + location.lng()
                     );
        }
    });
};

function getElectedOfficialsForLocation(location) {
    showLoadingImage();

    $.ajax({
        url: 'GetElectedOfficials.aspx',
        type: 'GET',
        data: { use: 'location',
                lat: location.lat(),
                lon: location.lng() },
        dataType: 'html',
        success: function (data, textStatus, XMLHttpRequest) {
            $('#results').html(data);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert("An error occurred while looking for your address's election information."
                     + " use=location" + "&lat=" + location.lat() + "&lon=" + location.lng()
                     );
        }
    });
};

function getElectedOfficialsForItem(item_number, street_number) {
    showLoadingImage();

    $.ajax({
        url: 'GetElectedOfficials.aspx',
        type: 'GET',
        data: { use: 'item',
                item_number: item_number,
                street_number: street_number },
        success: function (data, textStatus, XMLHttpRequest) {
            $('#results').html(data);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert("An error occurred while looking for your address's election information."
                     + " use=item" + "&item_number=" + item_number + "&street_number=" + street_number
                     );
        }
    });
};

function getElectedOfficialsForResult(result, location) {
    try {
        var street_number = getComponentOfType(result, 'street_number').long_name;
        var route = getComponentOfType(result, 'route').long_name;

        var county;
        component = getComponentOfType(result, 'administrative_area_level_2');
        if (component)
            county = component.long_name;
        else {
            county = getComponentOfType(result, 'locality').long_name;
        }

        var zip_code = getComponentOfType(result, 'postal_code').long_name;

        getElectedOfficials(street_number, route, county, zip_code, location);

        return true;
    }
    catch (err) {
        getElectedOfficialsForLocation(location);
        return false;
    }
};


