var controls, mapWrapper, table, cityDataArray, markerArray, units, scale,
minX, minY, maxX, maxY, x, y, zoom, boundsFlag, boundCount, nameValuePair,
request;

var kilometers = new Kilometers();
var miles = new Miles();
var blueIcon = new BlueIcon();
var indigoIcon = new IndigoIcon();
var purpleIcon = new PurpleIcon();
var magentaIcon = new MagentaIcon();
var redIcon = new RedIcon();
var grayIcon = new GrayIcon();

// constructor
function Main() {
	request = GXmlHttp.create();
    cityDataArray = new Array();
    markerArray = new Array();
    units = miles;
    controls = new Controls();
x=-99.052734375;y=39.63953756436671;zoom=4;scale=1;minX=-130;minY=20;maxX=-60;maxY=48.51660434886747;
    boundCount = 0;
    boundFlag = 0;
    table = new Table(document.getElementById("table"));
    paramArray = document.location.hash.substring(1).split(";");
    for (var i = 0; i < paramArray.length; i++) {
        nameValuePair = paramArray[i].split("=");
        switch (nameValuePair[0]) {
            case "searchCity":
                document.getElementById("searchCity").value = nameValuePair[1];
                break;
            case "limit":
            case "searchState":
                var selectElement = document.getElementById(nameValuePair[0]);
                for (var k = 0; k < selectElement.options.length; k++) {
                    if (selectElement.options[k].value === nameValuePair[1]) {
                        selectElement.options[k].selected = true;
                        break;
                    }
                }
                break;
            case "units":
                if (nameValuePair[1] === "km") {
                    makeUnitsKM();
                }
                break;
            case "scale":
                if (nameValuePair[1] === "0") {
                    useScaleNo();
                }
                break;
            case "x": x = nameValuePair[1]; break;
            case "y": y = nameValuePair[1]; break;
            case "zoom": zoom = parseInt(nameValuePair[1]); break;
            case "minX": minX = nameValuePair[1]; boundCount++; break;
            case "minY": minY = nameValuePair[1]; boundCount++; break;
            case "maxX": maxX = nameValuePair[1]; boundCount++; break;
            case "maxY": maxY = nameValuePair[1]; boundCount++; break;
        }
    }
    if (boundCount === 4) {
        boundFlag = 1;
    }
    mapWrapper = new MapWrapper(document.getElementById("map"), x, y, zoom);
    GEvent.addListener(mapWrapper.getMap(), "moveend", function() { setHash(); } );
    this.makeUnitsKm = makeUnitsKm;
    this.makeUnitsMi = makeUnitsMi;
    this.useScaleNo = useScaleNo;
    this.useScaleYes = useScaleYes;
    this.start = start;
    this.clearAll = clearAll;
    this.update = update;
    this.reupdate = reupdate;
    this.goSearch = goSearch;
    this.popUp = popUp;
}

// methods
function start() {
    if(GBrowserIsCompatible()) {
        if (
        document.getElementById("searchCity").value === "" && 
        document.getElementById("searchState").value === "") {
            update();
        }
        else {
            goSearch();
        }
    }
    else {
        alert("OOPS! Google Maps said that it\'s incompatible with this" +   
        "browser. Please download Mozilla Firefox @ http://www.mozilla.org");
    }
}

function reupdate() {
    clearAll();
    update();
}

function goSearch() {
    clearAll();
    var city = document.getElementById("searchCity").value;
    var state = document.getElementById("searchState").value;
    var parameters = "&limit=" + document.getElementById("limit").value + 
    "&searchCity=" + city + "&searchState=" + state;
    getResults(parameters);
}

function update() {
    var bounds = mapWrapper.getMap().getBounds();
    if (boundsFlag === 0) {
        minY = bounds.getSouthWest().y;
        minX = bounds.getSouthWest().x;
        maxY = bounds.getNorthEast().y;
        maxX = bounds.getNorthEast().x;
    }
    else {
        boundsFlag = 0;
    }
    var parameters = "&limit=" + document.getElementById("limit").value + 
    "&minX=" + minX + "&maxX=" + maxX + "&minY=" + minY + "&maxY=" + maxY;
    getResults(parameters);
}

function getResults(parameters) {
	setHash();
    request.open("GET", "data.jsp?" + parameters, true);
    request.onreadystatechange = function() {
        if (request.readyState == 4) {
            var xmlDoc = request.responseXML;
            var markers =
            xmlDoc.documentElement.getElementsByTagName("marker");
            var value;
            var size = markers.length;
            var location, city, county, state, zip, statistics, population,
            landKm, landMi, popDensityKm, popDensityMi, color, localColor, latLng,
            icon, marker, cityData;
            for (var i = 0; i < size; i++) {
                location = markers[i].getElementsByTagName("location")[0];
                city = location.getAttribute("city");
                state = location.getAttribute("state");
                zip = location.getAttribute("zip");
                county = location.getAttribute("county");
                statistics = markers[i].getElementsByTagName("statistics")[0];
                population = statistics.getAttribute("population");
                landKm = statistics.getAttribute("landKm");
                landMi = statistics.getAttribute("landMi");
                popDensityKm = statistics.getAttribute("popDensityKm");
                popDensityMi = statistics.getAttribute("popDensityMi");
                color = markers[i].getAttribute("color");
                localColor = markers[i].getAttribute("localColor");
                latLng = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                parseFloat(markers[i].getAttribute("lng")));
                cityData = new CityData(city, state, zip, county, population, 
                landKm, landMi, popDensityKm, popDensityMi, color, localColor, latLng);
                markerArray[i] = new GMarker(
                latLng, makeIcon(cityData.getColor(scale)));
                cityDataArray[i] = cityData;
                mapWrapper.addMarker(markerArray[i], cityData, units);
                table.addRow(new Array(i + 1,
                "<a target=\"_self\" href=\"#\" onclick=\"main.popUp(" + i +
                ")\"><img src=\"images\/markers\/" +
                cityData.getColor(scale) + "4.png\" width=\"14\" height=\"22\" \/><\/a>",
                city, state, zip, cityData.getPopDensity(units)));
            }
        }
    };
    request.send(null);
}

function makeUnitsKm() {
    controls.km();
    units = kilometers;
    if (cityDataArray.length !== 0) { refreshData(); }
}

function makeUnitsMi() {
    controls.mi();
    units = miles;
    if (cityDataArray.length !== 0) { refreshData(); }
}

function useScaleNo() {
    controls.scaleNo();
    scale = 0;
    if (cityDataArray.length !== 0) { refreshData(); }
}

function useScaleYes() {
    controls.scaleYes();
    scale = 1;
    if (cityDataArray.length !== 0) { refreshData(); }
}

function clearDisplay() {
    table.clearAll();
    mapWrapper.getMap().clearOverlays();
}

function clearAll() {
    clearDisplay();
    cityDataArray = new Array();
    markerArray = new Array();
}

function refreshData() {
    clearDisplay();
    var cityData, color, icon, marker;
    for (var i = 0; i < cityDataArray.length; i++) {
        cityData = cityDataArray[i];
        color = cityData.getColor(scale);
        icon = makeIcon(color);
        marker = new GMarker(cityData.getLatLng(), icon);
        table.addRow(new Array(i + 1,
        "<a href=\"#\" target=\"_self\" onclick=\"main.popUp(" + i + ")\">" +
        "<img width=\"14\" height=\"22\" " +
        "src=\"images\/markers\/" + color + 
        "4.png\" \/><\/a>", cityData.getCity(),   
        cityData.getState(), cityData.getZip(), cityData.getPopDensity(units)));
        mapWrapper.addMarker(marker, cityData, units);
    }
}

function popUp(i) {
    markerArray[i].openInfoWindowHtml(cityDataArray[i].getInfo(units));
}

function setHash() {
    var center = mapWrapper.getMap().getCenter();
    document.location.hash = "x=" + center.x + ";y=" + center.y +
    ";zoom=" + mapWrapper.getMap().getZoom() +
    ";searchCity=" + document.getElementById("searchCity").value +
    ";searchState=" + document.getElementById("searchState").value +
    ";limit=" + document.getElementById("limit").value +
    ";scale=" + scale + ";units=" + units.getAbbrev() +
    ";minX=" + minX + ";minY=" + minY + ";maxX=" + maxX + ";maxY=" + maxY;
}
