// Utah Legislative district lookup tool. Copyright 2009 Scott Riding, All Rights Reserved.
// Used by the Utah Senate with permission -- attribution requested.

// Global variables from data.js:
// -------------------------------------------
// senators (array of senator info)
// reps (array of house rep info)
// senDistricts (array of senate district info)

// Global variables from polygons.js:
// -------------------------------------------
// senPolyData (array of encoded data for senate district polygons)
// housePolyData (array of encoded data for house district polygons) 

// Global variables
var geocoder;
var map;
var senatePolys;


// Does the grey text replacement on the input field. 
// Props to Jason at http://greengeckodesign.com/blog/2007/08/input-text-replace-in-javascript.html
var clearInputValue = [];
function clearInput(thisObj){
    if (!clearInputValue[thisObj]){
        clearInputValue[thisObj] = thisObj.value;
        thisObj.value = "";
        thisObj.style.color = "black";
   }
}


function replaceInput(thisObj){
    if (thisObj.value == ""){
        thisObj.value = clearInputValue[thisObj];
        thisObj.style.color = "#999999";
        clearInputValue[thisObj]= false;
    }
}
 

// Add a city to the given drop down menu
function addCity(selectbox,text,value) {
    var optn = document.createElement("option");
    optn.text = text;
    optn.value = value;
    selectbox.options.add(optn);
}


// Populate the cities drop down menu
function populateCities(selectbox) {
    var cityArray = [];
    var index = 0;
    for (var i = 0; i < senDistricts.length; i++) {
        for (var j = 0; j < senDistricts[i].cities.length; j++) {
            cityArray[index] = senDistricts[i].cities[j];
            index++;
        }
    }

    cityArray.sort();
    cityArray = removeDuplicates(cityArray);

    for (var i = 0; i < cityArray.length; i++) {
        addCity(document.addressForm.cityList, cityArray[i], cityArray[i]);
    }
}

// Get sorted array as input and returns the same array without duplicates.
function removeDuplicates(arr) {
    var newCityArray = [];
    var index = 0;
    var compareCity = "";
    for (var i = 0; i < arr.length; i++) {
	    if (arr[i] == compareCity) {
		// If it is a duplicate, skip it   
	    } else {
		newCityArray[index] = arr[i];
		compareCity = arr[i];
		index++;
	    }
    }
    return newCityArray;
}


// Epoly code to test if the geocode point is inside the district polygons. 
// Props to Mike Williams at http://econym.googlepages.com/index.htm 
GPolygon.prototype.Contains = function(point) {
    var j=0;
    var oddNodes = false;
    var x = point.lng();
    var y = point.lat();
    for (var i=0; i < this.getVertexCount(); i++) {
        j++;
        if (j == this.getVertexCount()) j = 0;
        if (((this.getVertex(i).lat() < y) && (this.getVertex(j).lat() >= y))
            || ((this.getVertex(j).lat() < y) && (this.getVertex(i).lat() >= y))) {
            if ( this.getVertex(i).lng() + (y - this.getVertex(i).lat())
                 /  (this.getVertex(j).lat()-this.getVertex(i).lat())
                 *  (this.getVertex(j).lng() - this.getVertex(i).lng()) < x ) {
              oddNodes = !oddNodes;
            }
        }
    }
    return oddNodes;
}

// Copies the above function to GPolyline
GPolyline.prototype.Contains = GPolygon.prototype.Contains;


// Generate the HTML for the information window
function makeInfoWindow(senateNum, houseNum) {
    var senator = senators[senateNum - 1];
    var rep = reps[houseNum - 1];
    
    return ''
    +  '<div id="mapwindow">'
    +    '<table cellpadding="0" cellspacing="0">'
    +      '<tr>'
    +        '<td style="width:15px; background: url(senbanner.jpg);"></td>'
    +        '<td><img width="105px" height="150px" '
    +          'src=' + senator.image + ' '
    +          'align="right" alt="">'
    +        '</td>'
    +        '<td style="background: url(senatebg_new.jpg); width: 222px; padding-left: 3px;">'
    +          '<a href='+ senator.url + '>'
    +          '<h3>Sen. ' + senator.name + '</h3></a>'
    +          '<br />'
    +          '<strong>' + senator.party + '</strong> - District ' + senateNum
    +          '<br />'
    +          'Click <a href="mailto:' + senator.email + '">here</a> '
    +          'to send ' + (senator.gender == "m" ? "him" : "her") + ' an email.'
    +          '<br />'
    +          '<br />'
    +          '<strong>Phone Numbers</strong>'
    +          '<br />'
    +          senator.phone
    +       '</td>'
    +     '</tr>'
    +     '<tr>'
    +       '<td style="width:15px; background: url(repbanner.jpg); border-top: 1px solid #C8C8C8"></td>'
    +       '<td style="border-top: 1px solid #C8C8C8;">'
    +         '<img height="150px" width="105px" src="' + rep.image + '" align="right" alt=""></td>'
    +       '<td style="background: url(housebg.jpg); width: 222px; border-top: 1px solid #C8C8C8; padding-left: 3px;">'
    +         '<a href="http://le.state.ut.us/house/members/bios.asp?id=' + houseNum + '">'
    +         '<h3>Rep. ' + rep.name + '</h3></a>'
    +         '<br />'
    +         '<strong>' + rep.party + '</strong> - House District ' + houseNum
    +         '<br />'
    +         'Click <a href="mailto:' + rep.email + '">here</a> '
    +         'to send ' + (rep.gender == "m" ? "him" : "her") + ' an email.'
    +         '<br />'
    +         '<br />'
    +         '<strong>Phone Numbers</strong>'
    +         '<br />'
    +         rep.phone
    +       '</td>'
    +     '</tr>'
    +   '</table>'
    + '</div>';  
}

 
function onGoButton(city) {
    if (city == "") {
        document.addressForm.goButton.disabled=true;
    }
    else { 
        document.addressForm.goButton.disabled=false;
    }
}

function hideArrow() {
    document.getElementById("helparrow").style.visibility="hidden";
}
 
function busySignalOn() {
    document.addressForm.goButton.disabled=true;
    document.getElementById("busy_signal").style.visibility="visible";
}

function busySignalOff() {
    document.getElementById("busy_signal").style.visibility="hidden";
    document.addressForm.goButton.disabled=false;
}
     
// Initialize the Google Maps API, load and restrict zooming to the Utah view, add navigation tools, and allow zooming with the scrollwheel
function initialize() { 
    if (GBrowserIsCompatible()) {
        // Restrict zooming to just the Utah view
        var mapTypes = G_DEFAULT_MAP_TYPES;
        for(var i = 0; i < mapTypes.length; i++){
            mapTypes[i].getMaximumResolution = function(latlng){ return 16;};
            mapTypes[i].getMinimumResolution = function(latlng){ return 6;};
        }
        map = new GMap2(document.getElementById("map_canvas"));
        geocoder = new GClientGeocoder();
        map.setCenter(new GLatLng(39.499708177100004, -111.54721247025), 7);
        map.addControl(new GLargeMapControl());
        map.enableContinuousZoom();
        map.enableScrollWheelZoom();
    }
} 


// Returns true if the given city overlaps with the given senate district
function containsCity(district, city) {
    for (var i = 0; i < district.cities.length; i++) {
        if (city == district.cities[i]) return true;
    }

    return false;
}


// Creates the GPolygon associated with the house district number
function makeHousePoly(houseNum) {
    var color = reps[houseNum - 1].party == "Democrat" ? "blue" : "red";

    return GPolygon.fromEncoded({
        polylines: [{
            points: housePolyData[houseNum - 1].points,
            levels: housePolyData[houseNum - 1].levels,
            color: color,
            opacity: 0.7,
            weight: 1,
            numLevels: 18,
            zoomFactor: 2
        }],
        fill: true,
        color: color, 
        opacity: 0.1,
        outline: true
    });
}


// Creates the GPolygon associated with the senate district number
function makeSenatePoly(senateNum) {
    var color = senators[senateNum - 1].party == "Democrat" ? "blue" : "red";

    return GPolygon.fromEncoded({
        polylines: [{
            points: senPolyData[senateNum - 1].points,
            levels: senPolyData[senateNum - 1].levels,
            color: color,
            opacity: 0.7,
            weight: 1,
            numLevels: 18,
            zoomFactor: 2
        }],
        fill: true,
        color: color,
        opacity: 0.1,
        outline: true
    });
}


// This is called when the Google servers respond (from the
// getLatLng call in the showAddress function) with 
// the geocoding of the address that the user gave.
function geocodeCallback(point) {
    if (!point) {
        alert(address + "-- I'm so sorry, we couldn't find that address. Would you "
                     + "mind checking the spelling for us? If it continues to give "
                     + "you problems, please tell us about it! Navigate to "
                     + "www.utahsenate.org/contactus.html to leave us a message so "
                     + "we can get back to you.");
        return;
    }

    map.setCenter(point, 13);
    var marker = new GMarker(point);
    map.addOverlay(marker);

    for (var i = 0; i < senDistricts.length; i++) {
        if (senatePolys[i].Contains(point)) {
            var overlaps = senDistricts[i].houseOverlaps;

            for (var j = 0; j < overlaps.length; j++) {
                var houseNum = overlaps[j];
                var housePoly = makeHousePoly(houseNum);

                map.addOverlay(housePoly);
                if (housePoly.Contains(point)) {
                    var senateNum = i + 1;
                    marker.openInfoWindowHtml(makeInfoWindow(senateNum, houseNum));
                    GEvent.addListener(marker, 'click', function(point) {
                        marker.openInfoWindowHtml(makeInfoWindow(senateNum, houseNum));
                    });
                    break;
                } else {
                    map.removeOverlay(housePoly);
                }
            }
        } else {
            map.removeOverlay(senatePolys[i]);
        }
    }

    busySignalOff();
}

  
// When address is inputted, show map, send geocode request to the Google servers, 
// then map their Senate and House districts and provide contact information
function showAddress(address, city) {
    initialize();
    map.clearOverlays();
    hideArrow();
    busySignalOn();

    // Populate the senate polygon array with empty polygons to avoid epoly error in final function
    senatePolys = [];
    for (var i = 0; i < senPolyData.length; i++) {
        senatePolys[i] = new GPolygon;
    }
    
    // If users leave address field blank, just use the city for the geocoding    
    if (address == "Click to type your street address here") {
        address = "";
    }
  
    // Convert form into full Utah address for geocoding
    address += " " + city + " " + "Utah";
  
    // Iterate over the senate districts and generate the polygons
    // for all the districts overlapping the selected city
    for (var i = 0; i < senDistricts.length; i++) {
        if (containsCity(senDistricts[i], city)) {
            senatePolys[i] = makeSenatePoly(i + 1);
            map.addOverlay(senatePolys[i]);
        }
    }

    if (geocoder) {
        geocoder.getLatLng(address, geocodeCallback);
    }
}
