/* AppController object
 *	-initializes and manages the database search and map interaction
 *	This serves as the entry point from the maps search page. 
 */
function AppController(language, isPopup)
{
	this.language = (language ? language : 'en');
	this.isPopup = isPopup
	// set up the web-service
	this.ws = new Locator_WS(this);
	// set up the Map Controller
	this.mc = new MapController();
	this.results = {};
	this.requestInProgress = false;
}
AppController.INIT_VALUE_EN = "Enter a location";
AppController.INIT_VALUE_FR = "Inscrire le lieu recherché";

/*
 * Initializes the AppController
 */
AppController.prototype.initialize = function(map_div, latitude, longitude, zoom)
{
    me = this;
	// set up the map
    cb = GEvent.callback(me, me.onMapMove);
    // initialize the map controller
	this.mc.initialize(map_div, latitude, longitude, zoom, cb);
    this.country_poly = [];
    this.country_bounds = [];
    setTimeout(AppController.loadCountryBorders, 500);
}

/*
 * Clears/resets all member variables.
 */
AppController.prototype.clearAll = function() {
    this.requestInProgress = false;
    this.results = {};
    this.show_offices = false;
    this.show_events = false;
    this.show_advisories = false;
    this.event_startDate = null;
    this.event_endDate = null;
    this.advisory_startDate = null;
    this.advisory_endDate = null;
    this.mc.clearMap();
}

/**
 * Displays the office locations in the map
 */
AppController.prototype.populateOfficeLocations = function(fm) {
	if (this.requestInProgress) return;
	
	// set language passed in from form submission
	var lang = document.getElementById("languagePreference").value;
	if (lang != null) {
		this.language = lang;
	}
	
	// get form values for search
	if (!fm) {
		// no arg passed in - should not happen but if it does get the 'selectEvents' element (this is the name of the submit form)
		//TODO: get rid of this functionality and fail instead?
		fm = document.getElementById("selectEvents");
	}
	
	// determine which items should be shown on the map
    this.show_offices = true;    
	
	// get the location from the form
	var loc = $("input#loc").val();
	if (loc != "" && loc != AppController.INIT_VALUE_EN && loc != AppController.INIT_VALUE_FR) {
		//this.mc.clearMap();
		this.getData(this.mc.getWorldMapBounds());
		
		this.mc.geocoder.getLocations(
			loc,
			function(result) {
				if (result.Status.code == G_GEO_SUCCESS) {
                    APP_CONTROLLER.mapMove = true;
					var point = result.Placemark[0].Point.coordinates;
					APP_CONTROLLER.mc.centreOnAddress(point[1], point[0], AppController.convertAccuracyToZoom(result.Placemark[0].AddressDetails.Accuracy));
				}
				else {
					// an error has occurred -- give a better message
					alert ("Geocoding error: " + MapController.getGeocodeErrorMsg(result.Status.code));
				}
			}
		); //END call 'getLocations'
	}
	else { 
        //this.mc.clearMap();
		// option 1: do search from current viewport - this returns results only for the area the user is viewing (eg. Canada)
        // this.getData(this.mc.map.getBounds());
        //option 2: always apply search to world view
        this.getData(this.mc.getWorldMapBounds());
	}
}

/*
 * NOTE: Method is depricated! TODO: remove?
 *
 * The 'doFind' method is called when the search form is submitted.
 * This method launches a search for the Location specified by in the search form.
 * If successful the location specified in the map will be displayed on the calling page.
 * 
 */
AppController.prototype.doFind = function(fm) {
	if (this.requestInProgress) return;

	// clean up old results--remove marker objects
	for (var i=0; i<this.results.length; i++) {
		if (this.results[i].marker) delete this.results[i].marker;
	}
	
	// get form values for search
	if (!fm) {
		// no arg passed in - should not happen but if it does get the 'selectEvents' element (this is the name of the submit form)
		//TODO: get rid of this functionality and fail instead?
		fm = document.getElementById("selectEvents");
	}
	// determine which items should be shown on the map
    this.show_offices = $("input#displayLocations").get(0).checked;
    this.show_events = $("input#displayEvents").get(0).checked;
    this.show_advisories = $("input#displayAdvisories").get(0).checked;        
	
    // retrieve date filter criteria as submitted in the form (Format: "DD/MM/YY")
	this.event_startDate = $("input#filter_startdate").val();
	this.event_endDate = $("input#filter_enddate").val();
	this.advisory_startDate = $("input#filter_startdate").val();
	this.advisory_endDate = $("input#filter_enddate").val();
	
	// get the location from the form
	var loc = $("input#loc").val();
	if (loc != "" && loc != AppController.INIT_VALUE_EN && loc != AppController.INIT_VALUE_FR) {
		this.mc.clearMap();
		this.getData(this.mc.getWorldMapBounds());
	
		this.mc.geocoder.getLocations(
			loc,
			function(result) {
				if (result.Status.code == G_GEO_SUCCESS) {
                    APP_CONTROLLER.mapMove = true;
					var point = result.Placemark[0].Point.coordinates;
					APP_CONTROLLER.mc.centreOnAddress(point[1], point[0], AppController.convertAccuracyToZoom(result.Placemark[0].AddressDetails.Accuracy));
				}
				else {
					// an error has occurred -- give a better message
					alert ("Geocoding error: " + MapController.getGeocodeErrorMsg(result.Status.code));
				}
			}
		); //END call 'getLocations'
	}
	else {
        this.mc.clearMap();
		// option 1: do search from current viewport - this returns results only for the area the user is viewing (eg. Canada)
        // this.getData(this.mc.map.getBounds());
        //option 2: always apply search to world view
        this.getData(this.mc.getWorldMapBounds());
	}
}


//	Is called when the 'searchEventsResults.html' search form is submitted
//	Code derived from 'doFind ()', which is deprecated.
//	Note: dates are represented by strings in this format: "MM/DD/YY".
AppController.prototype.doSearchEvents = function(fm) {
	if (this.requestInProgress) return;

	// clean up old results--remove marker objects
	for (var i=0; i<this.results.length; i++) {
		if (this.results[i].marker) delete this.results[i].marker;
	}
	// get form values for search
	if (!fm) fm = document.getElementById("selectEvents");
	
	
	
    //this.show_offices = $("input#showLoc").get(0).checked;	
    this.show_events = true;
    //this.show_advisories = $("input#showAdvisories").get(0).checked;
	this.event_startDate = $("input#filter_startdate").val();
	this.event_endDate = $("input#filter_enddate").val();

	var loc = $("input#loc").val();

	if (loc != "" && loc != AppController.INIT_VALUE_EN && loc != AppController.INIT_VALUE_FR) {
		this.mc.geocoder.getLocations(loc, function(result) {
				if (result.Status.code == G_GEO_SUCCESS) {
                    APP_CONTROLLER.mapMove = true;
					var point = result.Placemark[0].Point.coordinates;
					APP_CONTROLLER.mc.centreOnAddress(point[1], point[0], AppController.convertAccuracyToZoom(result.Placemark[0].AddressDetails.Accuracy));
	                this.searchLocations("OK", TESTDATA);	
				}
				else {
					// an error has occurred -- give a better message
					alert ("Geocoding error: " + MapController.getGeocodeErrorMsg(result.Status.code));
				}
			});
	}
	else { 		
        this.mc.clearMap();
		// option 1: do search from current viewport - this returns results only for the area the user is viewing (eg. Canada)
        // this.getData(this.mc.map.getBounds());
        //option 2: always apply search to world view
        this.getData(this.mc.getWorldMapBounds());
	}
}

//	Is called when the 'searchAdvisories.html' search form is submitted
//	Code derived from 'doFind ()', which is deprecated.
//	Note: dates are represented by strings in this format: "MM/DD/YY".
AppController.prototype.doSearchAdvisories = function(fm) {
	if (this.requestInProgress) return;

	// clean up old results--remove marker objects
	for (var i=0; i<this.results.length; i++) {
		if (this.results[i].marker) delete this.results[i].marker;
	}
	// get form values for search
	if (!fm) fm = document.getElementById("selectEvents");
	
    this.show_offices = false;	
    this.show_advisories = true;
	this.advisory_startDate = $("input#filter_startdate").val();
	this.advisory_endDate = $("input#filter_enddate").val();

	var loc = $("input#loc").val();

	if (loc != "" && loc != AppController.INIT_VALUE_EN && loc != AppController.INIT_VALUE_FR) {
		this.mc.geocoder.getLocations(loc, function(result) {
				if (result.Status.code == G_GEO_SUCCESS) {
                    APP_CONTROLLER.mapMove = true;
					var point = result.Placemark[0].Point.coordinates;
					APP_CONTROLLER.mc.centreOnAddress(point[1], point[0], AppController.convertAccuracyToZoom(result.Placemark[0].AddressDetails.Accuracy));
	               	

				}
				else {
					// an error has occurred -- give a better message
					alert ("Geocoding error: " + MapController.getGeocodeErrorMsg(result.Status.code));
				}
			});
	}
	else { 
        this.mc.clearMap();
		// option 1: do search from current viewport - this returns results only for the area the user is viewing (eg. Canada)
        // this.getData(this.mc.map.getBounds());
        //option 2: always apply search to world view
        this.getData(this.mc.getWorldMapBounds());
	}
}


//	Is called when the 'searchLocationsResults.html' search form is submitted
//	Code derived from 'doFind ()', which is deprecated.
//	Note: dates are represented by strings in this format: "MM/DD/YY".
AppController.prototype.doSearchLocations = function(fm) {
	if (this.requestInProgress) return;

	// clean up old results--remove marker objects
	for (var i=0; i<this.results.length; i++) {
		if (this.results[i].marker) delete this.results[i].marker;
	}

	// if the displayLocations checkbox is set this determines behaviour
	var displayLocations = $("input#displayLocations").get(0).checked;
	if (!displayLocations) {
		this.show_offices = false;
	} else {
		this.show_offices = true;
	}
	
	// get form values for search
	if (!fm) fm = document.getElementById("selectEvents");
    
    //this.show_events = $("input#showEvents").get(0).checked;
    //this.show_advisories = $("input#showAdvisories").get(0).checked;   
    
	// get the location entered in the search form
	var loc = $("input#loc").val();
	if (loc != "" && loc != AppController.INIT_VALUE_EN && loc != AppController.INIT_VALUE_FR) {
		this.mc.geocoder.getLocations(loc, function(result) {
				if (result.Status.code == G_GEO_SUCCESS) {
                    APP_CONTROLLER.mapMove = true;
					var point = result.Placemark[0].Point.coordinates;
					APP_CONTROLLER.mc.centreOnAddress(point[1], point[0], AppController.convertAccuracyToZoom(result.Placemark[0].AddressDetails.Accuracy));

				}
				else {
					// an error has occurred -- give a better message
					alert ("Geocoding error: " + MapController.getGeocodeErrorMsg(result.Status.code));
				}
			});
	}
	else { 
        this.mc.clearMap();
		// option 1: do search from current viewport - this returns results only for the area the user is viewing (eg. Canada)
        // this.getData(this.mc.map.getBounds());
        //option 2: always apply search to world view
        this.getData(this.mc.getWorldMapBounds());
	}
}

/*
 * CALLBACK METHOD: called after the map has been moved (eg. via a search for 'Canada')
 * This method will re-populate the newly positioned map based on the passed-in 'bounds'.
 * So, in order to only populate the area in the user's view pass in the currently visible bounds
 * In order to re-populate the entire world, pass in bounds encompassing the world.
 */
AppController.prototype.onMapMove = function(bounds) {
    // Store latitude/longitude/zoom in browser cookies
    document.cookie = "googleMapLatitude=" + this.mc.map.getCenter().lat() + ";";
    document.cookie = "googleMapLongitude=" + this.mc.map.getCenter().lng() + ";";
    document.cookie = "googleMapZoom=" + this.mc.map.getZoom() + ";";

    if (!this.mapMove) return;
    this.mapMove = false;
    //this.mc.clearMap();
    // TODO: refactor - replacing 'bounds' in callback with bounds of world map for DFAIT demo
    // this used to be: this.getData(bounds);
    this.getData(this.mc.map.getWorldMapBounds());
}

/*
 * Retrieves data used to populate points of interest on the map.
 * Sets all points of interest (eg. offices, events, advisories) to false and then
 * proceeds to use the 'request' method to retrieve these values.
 */
AppController.prototype.getData = function(bounds) {
    this.currentBounds = bounds;
    this.requestInProgress = true;
    this.got_offices = false;
    this.got_events = false;
    this.got_advisories = false;
    this.minLat = -72.60712040027553;
    this.minLon = -180;
    this.maxLat = 82.9403268016951;
    this.maxLon = 180;
    this.request();
}

/*
 * Sends request to get new data when parameters have changed.
 * Types of data to show are determined by the got_offices, got_events and got_advisories flags.
 */
AppController.prototype.request = function(minLat, minLon, maxLat, maxLon) {
    // send request(s) based on types of data to show
    if (this.show_events && !this.got_events) {
        this.requestInProgress = true;
        this.ws.searchLocations(AppController.EVENT_TYPE, this.minLat, this.minLon, this.maxLat, this.maxLon, this.event_startDate, this.event_endDate, this.language);
        return;
    }
    else if (this.show_offices && !this.got_offices) {
        this.requestInProgress = true;
        this.ws.searchLocations(AppController.OFFICE_TYPE, this.minLat, this.minLon, this.maxLat, this.maxLon, null, null, this.language);
        return;
    }
    else if (this.show_advisories && !this.got_advisories) {
        this.requestInProgress = true;
        this.ws.searchLocations(AppController.ADVISORY_TYPE, this.minLat, this.minLon, this.maxLat, this.maxLon, this.advisory_startDate, this.advisory_endDate, this.language);
        return;
    }
    // if all requests have been done, turn it off
    this.requestInProgress = false;
}


/*
 * CALLBACK HANDLER: searchLocations is the callback from the web-service function of the same name
 */
AppController.prototype.searchLocations = function(message, type, points) {
//	this.requestInProgress = false; // can't use this here because there are up to 3 responses
    // check message?
	if (message != "OK") {
		alert ("Search failed! Web Service returned error message: " + message + " - " + type);
		return;
	}
    if (!type) return;
	// save current results
	this.results[type] = points;

    // display the results
	this.show(type);
    // if we need more data do another request now
    if (type == AppController.OFFICE_TYPE) this.got_offices = true;
    if (type == AppController.EVENT_TYPE) this.got_events = true;
    if (type == AppController.ADVISORY_TYPE) this.got_advisories = true;
    if (this.requestInProgress) {
        var me = this;
        var req = GEvent.callback(me, me.request);
        setTimeout(req, 100);
    }
}
// PRIVATE METHODS

/*
 * Displays search results (locations, events, advisories) on the map.
 */
AppController.prototype.show = function(type) {
	// display office locations
    if (type == AppController.OFFICE_TYPE) {
        for (var i=0; i<this.results[type].length; i++) {
            var rec = this.results[type][i];
            if (rec.type != type) break;   // get out immediately
            var html = this.buildOfficeInfoWin(rec, i);            
            rec.overlay = this.mc.addOfficeMarker(rec.lat, rec.lon, html, rec.city);
        }
    }
    // display events
    else if (type == AppController.EVENT_TYPE) {
        this.bins = {};
        for (var i=0; i<this.results[type].length; i++) {
            var rec = this.results[type][i];
            if (rec.type != type) break;
            rec.infoWinHtml = this.buildEventInfoWin(rec);
            // for binning save this marker in a city bin
            if (!this.bins[rec.event_location]) this.bins[rec.event_location] = [];
            this.bins[rec.event_location].push(rec);
        }
        for (var city in this.bins) {
            var bin = this.bins[city];
            var rec = bin[0];
            var html = (bin.length == 1 ? rec.infoWinHtml : this.buildBinInfoWin(city, bin.length, rec.infoWinHtml));
            bin.overlay = this.mc.addEventBinMarker(rec.lat, rec.lon, html, bin.length, rec.event_location);
        }
    }
    //display travel advisories
    else if (type == AppController.ADVISORY_TYPE) {
        for (var i=0; i<this.results[type].length; i++) {
            var rec = this.results[type][i];
            if (rec.type != type) break;//shouldn't happen
            if (rec.advisory_level == 0) continue;
            // find the poly points for this country
            if (this.country_bounds[rec.country] && this.country_bounds[rec.country].intersects(this.currentBounds)) {
                var html = this.buildAdvisoryInfoWin(rec);
                rec.overlay = this.mc.addAdvisoryPoly(this.country_poly[rec.country], rec.advisoryLevel, html);
            }
        }
    }
    else {
        alert ("Error! AppController.show received bad type: " + type);
        return;
    }
}
AppController.convertAccuracyToZoom = function(acc) {
    var zoom = 2;
    if (acc == 1) { zoom = 4; }         // country
    else if (acc == 2) { zoom = 6; }    // state
    else if (acc == 3) { zoom = 8; }    // region   
    else if (acc >= 4) { zoom = 10; }   // city
    return zoom;
}

AppController.OFFICE_TYPE = "1";
AppController.EVENT_TYPE = "2";
AppController.ADVISORY_TYPE = "3";

/**
 * Constructs the html rendered in the bubble when an Office location is clicked
 * rec - the record containing the office information
 * index - the index of the event for lookup
 */
AppController.prototype.buildOfficeInfoWin = function(rec, index) {
	var html = "<br /> <div id='dfait_buildOfficeInfoWin'>";
	
	
	// Add link to either Country embassy site (if non-Canadian
	// or Trade Commissioner regional site (if Canadian)
	
	var tradeUrl = this.getOfficeUrl(rec.office_id);
	
	//if isPopup is false then add links in the text and if isPopup is true then don't add links (i.e., just the text).
	if (this.isPopup=="false"){
		if (tradeUrl == null || tradeUrl == '') {
			// TODO: add French language support here ... all 'rec' content should already be set properly so it's just the text being inserted that needs to be French.
			// probably cleanest to initialize variables either french or english then build the html once using the variables.
			
			// this Office is not in Canada - handling depends on whether or not it is in the USA
			if (rec.region_id == '17') {
				// office is in the USA
				if (this.language == 'fr') {
	        html += "Nos bureaux commerciaux - <a href=\"/fra/bureaux-aux-etats-unis.jsp\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\">États-Unis</a><br /><br />";
	        html += "<a href=\"/fra/bureau.jsp?cid=" + rec.country_id + "&oid=" + rec.office_id + "\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\"><b>" + rec.title + "</b></a><br />";
				}
				else {
	        html += "Doing business in the <a href=\"/eng/offices-united-states.jsp\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\">United States</a><br /><br />";
				  html += "<a href=\"/eng/office.jsp?cid=" + rec.country_id + "&oid=" + rec.office_id + "\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\"><b>" + rec.title + "</b></a><br />";
				}
			}
			else {
				// office is not in the USA
	      if (this.language == 'fr') {
	        if (rec.has_multiple_offices == 'true') {
				if ((rec.office_id == '306') || (rec.office_id == '807') || (rec.office_id == '32') || (rec.office_id == '880') || (rec.office_id == '957') || (rec.office_id == '958') || (rec.office_id == '959') || (rec.office_id == '960') || (rec.office_id == '961') || (rec.office_id == '962') ) {
	               html += "Nos bureaux commerciaux - <a href=\"/fra/bureaux-en-chine.jsp\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\">" + rec.country + "</a><br /><br />";
	            } else {               
	               html += "Nos bureaux commerciaux - <a href=\"/fra/bureaux-multiples.jsp?cid=" + rec.country_id + "\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\">" + rec.country + "</a><br /><br />";
	            }   
	        }
	        html += "<a href=\"/fra/bureau.jsp?cid=" + rec.country_id + "&oid=" + rec.office_id + "\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\"><b>" + rec.title + "</b></a><br />";
	      }
	      else {
				  if (rec.has_multiple_offices == 'true') {
				    if ((rec.office_id == '306') || (rec.office_id == '807') || (rec.office_id == '32') || (rec.office_id == '880') || (rec.office_id == '957') || (rec.office_id == '958') || (rec.office_id == '959') || (rec.office_id == '960') || (rec.office_id == '961') || (rec.office_id == '962') ) {
					   html += "Doing business in <a href=\"/eng/offices-china.jsp\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\">" + rec.country + "</a><br /><br />";			    
				    } else {
				       html += "Doing business in <a href=\"/eng/offices-multiple.jsp?cid=" + rec.country_id + "\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\">" + rec.country + "</a><br /><br />";
				    }   
				  }
	              html += "<a href=\"/eng/office.jsp?cid=" + rec.country_id + "&oid=" + rec.office_id + "\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\"><b>" + rec.title + "</b></a><br />";
				}
			}
		}
		else {
			// this Office is in Canada
	    // parse out the province Code
	    var provinceCodeSplit = tradeUrl.split('/');
	    var provinceCode = provinceCodeSplit[2];
			if (this.language == 'fr') {
	      html += "Nos bureaux commerciaux - <a href=\"/fra/" + provinceCode + "/accueil.jsp\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\">" + this.getProvinceName(rec.office_id) + "</a><br /><br />";
				html += "<a href=\"" + tradeUrl + "\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\"><b>" + rec.title + "</b></a><br />";
			}
			else {
	      html += "Trade Offices - <a href=\"/eng/" + provinceCode + "/home.jsp\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\">" + this.getProvinceName(rec.office_id) + "</a><br /><br />";
				html += "<a href=\"" + tradeUrl + "\" onclick=\"AppController.prototype.insertOfficeInfo(" + index + ");\"><b>" + rec.title + "</b></a><br />";
			}
		}
		
	
		html += rec.address1 + "<br />";
		if (rec.address2 != "") html += rec.address2 + "<br />";
			html += rec.city;
		if (rec.state && rec.state != "") html += ", " + rec.state;
		if (rec.postal && rec.postal != "") html += " " + rec.postal;
			html += "<br />" 
		if (rec.region_id == '17') {
		if (this.language == 'fr') {	  
				html += "États-Unis <br />";
			} else {
				html += "USA <br />";
				}
		} else {
				html += rec.country + "<br />";
		} 
		html += rec.phone + "<br />";
		if (this.language == 'fr') {
			html += "Courriel : " + rec.email + "<br />";
		}
		else {
			html += "Email: " + rec.email + "<br />";
		}
		if (rec.url && rec.url != "") html += "<a href='" + rec.url + "'>" + rec.url + "</a><br />";
		if (rec.office_hours && rec.office_hours != "") {
			if (this.language == 'fr') {
				html += "Heures : " + rec.office_hours + "<br />";
			}
			else {
				html += "Hours: " + rec.office_hours + "<br />";
		    }
		}
		if (rec.territory && rec.territory != "") {
			if (this.language == 'fr') {
				html += "Territoires/Responsabilités : " + rec.territory + "<br />";
			}
			else {
	    	html += "Territories/Responsibilities: " + rec.territory + "<br />";
			}
		}
	}
	else {
		if (tradeUrl == null || tradeUrl == '') {
			// TODO: add French language support here ... all 'rec' content should already be set properly so it's just the text being inserted that needs to be French.
			// probably cleanest to initialize variables either french or english then build the html once using the variables.
			
			// this Office is not in Canada - handling depends on whether or not it is in the USA
			if (rec.region_id == '17') {
				// office is in the USA
				if (this.language == 'fr') {
	        html += "Nos bureaux commerciaux - États-Unis<br /><br />";
	        html += "<b>" + rec.title + "</b><br />";
				}
				else {
	        html += "Doing business in the United States<br /><br />";
				  html += "<b>" + rec.title + "</b><br />";
				}
			}
			else {
				// office is not in the USA
	      if (this.language == 'fr') {
	        if (rec.has_multiple_offices == 'true') {
				if ((rec.office_id == '306') || (rec.office_id == '807') || (rec.office_id == '32') || (rec.office_id == '880') || (rec.office_id == '957') || (rec.office_id == '958') || (rec.office_id == '959') || (rec.office_id == '960') || (rec.office_id == '961') || (rec.office_id == '962') ) {
	               html += "Nos bureaux commerciaux - " + rec.country + "<br /><br />";
	            } else {               
	               html += "Nos bureaux commerciaux -  " + rec.country + "<br /><br />";
	            }   
	        }
	        html += "<b>" + rec.title + "</b><br />";
	      }
	      else {
				  if (rec.has_multiple_offices == 'true') {
				    if ((rec.office_id == '306') || (rec.office_id == '807') || (rec.office_id == '32') || (rec.office_id == '880') || (rec.office_id == '957') || (rec.office_id == '958') || (rec.office_id == '959') || (rec.office_id == '960') || (rec.office_id == '961') || (rec.office_id == '962') ) {
					   html += "Doing business in " + rec.country + "<br /><br />";			    
				    } else {
				       html += "Doing business in " + rec.country + "<br /><br />";
				    }   
				  }
	              html += "<b>" + rec.title + "</b></a><br />";
				}
			}
		}
		else {
			// this Office is in Canada
	    // parse out the province Code
	    var provinceCodeSplit = tradeUrl.split('/');
	    var provinceCode = provinceCodeSplit[2];
			if (this.language == 'fr') {
	      html += "Nos bureaux commerciaux - " + this.getProvinceName(rec.office_id) + "<br /><br />";
				html += rec.title + "</b><br />";
			}
			else {
	      html += "Trade Offices - " + this.getProvinceName(rec.office_id) + "<br /><br />";
				html += "<b>" + rec.title + "</b></a><br />";
			}
		}
		
	
		html += rec.address1 + "<br />";
		if (rec.address2 != "") html += rec.address2 + "<br />";
			html += rec.city;
		if (rec.state && rec.state != "") html += ", " + rec.state;
		if (rec.postal && rec.postal != "") html += " " + rec.postal;
			html += "<br />" 
		if (rec.region_id == '17') {
		if (this.language == 'fr') {	  
				html += "États-Unis <br />";
			} else {
				html += "USA <br />";
				}
		} else {
				html += rec.country + "<br />";
		} 
		html += rec.phone + "<br />";
		if (this.language == 'fr') {
			html += "Courriel : " + rec.email + "<br />";
		}
		else {
			html += "Email: " + rec.email + "<br />";
		}
		if (rec.url && rec.url != "") html += rec.url + "<br />";
		if (rec.office_hours && rec.office_hours != "") {
			if (this.language == 'fr') {
				html += "Heures : " + rec.office_hours + "<br />";
			}
			else {
				html += "Hours: " + rec.office_hours + "<br />";
		    }
		}
		if (rec.territory && rec.territory != "") {
			if (this.language == 'fr') {
				html += "Territoires/Responsabilités : " + rec.territory + "<br />";
			}
			else {
	    	html += "Territories/Responsibilities: " + rec.territory + "<br />";
			}
		}		
	}
	html += "</div>";
	return html;
}

AppController.prototype.buildEventInfoWin = function(rec) {
    var html = "<b>" + rec.title + "</b><br />" + rec.country + "<br />" + rec.event_location + "<br />" + rec.event_date;
    if (rec.url && rec.url != "") html += "<br /><a href='" + rec.url + "'>" + rec.url + "</a>";
    return html;
}
AppController.prototype.buildAdvisoryInfoWin = function(rec) {
    var html = "<b>" + rec.country + "<br />" + rec.warning + "</b><br />" + rec.description + "<br />" + rec.fromDate + " - " + rec.toDate;
    if (rec.link && rec.link != "") html += "<br /><a href='" + rec.link + "'>" + rec.link + "</a>";
    return html;
}
AppController.prototype.buildBinInfoWin = function(binId, binLength, firstHtml) {
	var html = "<div id='dfait_infowin'>";
    html += "<table width=96%><tbody><tr><td width=25% align=left><a id='prevLink' href='#' onclick='APP_CONTROLLER.getBinPrev(\"" + binId + "\");return false;'><img src='../images/maps/NextButton_rtl.gif' alt='Prev' /></a></td><td width=50% align=center><span id='currentEventNum'>1</span> / " + binLength + "</td><td width=25% align=right><a id='nextLink' class='available' href='#' onclick='APP_CONTROLLER.getBinNext(\"" + binId + "\");return false;'><img src='../images/maps/NextButton.gif' alt='Next' /></a></td></tr></tbody></table>";
    html += "<div id='binInfoWin'>" + firstHtml + "</div>";
    html += "</div>";
	return html;
}

AppController.prototype.insertOfficeInfo = function(index) {
	document.getElementById("more_information_marker").innerHTML = "testing index: " + index;
}

AppController.prototype.getBinPrev = function(binId) {
    var currNum = parseInt($('#currentEventNum').html());
    if (currNum <= 1) return;
    if (currNum == this.bins[binId].length) $('#nextLink').addClass("available");
    var html = this.bins[binId][currNum-2].infoWinHtml;
    if (--currNum <= 1) $('#prevLink').removeClass("available");
    $('#binInfoWin').html(html);
    $('#currentEventNum').html(currNum);
}

AppController.prototype.getBinNext = function(binId) {
    var currNum = parseInt($('#currentEventNum').html());
    if (currNum >= this.bins[binId].length) return;
    if (currNum == 1) $('#prevLink').addClass("available");
    var html = this.bins[binId][currNum].infoWinHtml;
    if (++currNum == this.bins[binId].length) $('#nextLink').removeClass("available");
    $('#binInfoWin').html(html);
    $('#currentEventNum').html(currNum);
}

/**
 * Unfortunately this code is required in order to load in the URL for the Office.
 * This should really be generated dynamically from database content but for some reason is not.
 * This code snippet is mostly stolen from the contact-our-team.jsp
 */
AppController.prototype.getOfficeUrl = function(officeId) {
	var officeUrl;

  if (this.language == 'fr') {
    if (officeId == '022') { //Calgary
        officeUrl = "/fra/alb/contactez-notre-equipe.jsp?oid=022";
    }   
    else if (officeId == '012') { //Edm
        officeUrl = "/fra/alb/contactez-notre-equipe.jsp?oid=012";
    }
    else if (officeId == '011') { //Van
        officeUrl = "/fra/cb/contactez-notre-equipe.jsp?oid=011";
    }
    else if (officeId == '024') { //Vic
        officeUrl = "/fra/cb/contactez-notre-equipe.jsp?oid=024";
    }
    else if (officeId == '955') { //Kelowna
        officeUrl = "/fra/cb/contactez-notre-equipe.jsp?oid=955";
    }
    else if (officeId == '015') { //Winn
        officeUrl = "/fra/man/contactez-notre-equipe.jsp?oid=015";
    }
    else if (officeId == '018') { //Moncton
        officeUrl = "/fra/nb/contactez-notre-equipe.jsp?oid=018";
    }
    else if (officeId == '021') { //St John's
        officeUrl = "/fra/tnl/contactez-notre-equipe.jsp?oid=021";
    }
    else if (officeId == '019') { //Halifax
        officeUrl = "/fra/ne/contactez-notre-equipe.jsp?oid=019";
    }
    else if (officeId == '027') { //Ott
        officeUrl = "/fra/ont/contactez-notre-equipe.jsp?oid=027";
    }
    else if (officeId == '016') { //Tor
        officeUrl = "/fra/ont/contactez-notre-equipe.jsp?oid=016";
    }
    else if (officeId == '025') { //Waterloo
        officeUrl = "/fra/ont/contactez-notre-equipe.jsp?oid=025";
    }
    else if (officeId == '026') { //Windsor
        officeUrl = "/fra/ont/contactez-notre-equipe.jsp?oid=026";
    }
    else if (officeId == '020') { //Charlottetown
        officeUrl = "/fra/ipe/contactez-notre-equipe.jsp?oid=020";
    }
    else if (officeId == '017') { //Montreal
        officeUrl = "/fra/qc/contactez-notre-equipe.jsp?oid=017";
    }
    else if (officeId == '023') { //Quebec City
        officeUrl = "/fra/qc/contactez-notre-equipe.jsp?oid=023";
    }
    else if (officeId == '014') { //Regina
        officeUrl = "/fra/sask/contactez-notre-equipe.jsp?oid=014";
    }
    else if (officeId == '013') { //Saskatoon
        officeUrl = "/fra/sask/contactez-notre-equipe.jsp?oid=013";
    }  
  }
  else { 
  	if (officeId == '022') { //Calgary
  	    officeUrl = "/eng/alta/contact-our-team.jsp?oid=022";
  	}   
  	else if (officeId == '012') { //Edm
  	    officeUrl = "/eng/alta/contact-our-team.jsp?oid=012";
  	}
  	else if (officeId == '011') { //Van
  	    officeUrl = "/eng/bc/contact-our-team.jsp?oid=011";
  	}
  	else if (officeId == '024') { //Vic
  	    officeUrl = "/eng/bc/contact-our-team.jsp?oid=024";
  	}
    else if (officeId == '955') { //Kelowna
        officeUrl = "/eng/bc/contact-our-team.jsp?oid=955";
    }
  	else if (officeId == '015') { //Winn
  	    officeUrl = "/eng/man/contact-our-team.jsp?oid=015";
  	}
  	else if (officeId == '018') { //Moncton
  	    officeUrl = "/eng/nb/contact-our-team.jsp?oid=018";
  	}
  	else if (officeId == '021') { //St John's
  	    officeUrl = "/eng/nfldlab/contact-our-team.jsp?oid=021";
  	}
  	else if (officeId == '019') { //Halifax
  	    officeUrl = "/eng/ns/contact-our-team.jsp?oid=019";
  	}
  	else if (officeId == '027') { //Ott
  	    officeUrl = "/eng/ont/contact-our-team.jsp?oid=027";
  	}
  	else if (officeId == '016') { //Tor
  	    officeUrl = "/eng/ont/contact-our-team.jsp?oid=016";
  	}
  	else if (officeId == '025') { //Waterloo
  	    officeUrl = "/eng/ont/contact-our-team.jsp?oid=025";
  	}
  	else if (officeId == '026') { //Windsor
  	    officeUrl = "/eng/ont/contact-our-team.jsp?oid=026";
  	}
  	else if (officeId == '020') { //Charlottetown
  	    officeUrl = "/eng/pei/contact-our-team.jsp?oid=020";
  	}
  	else if (officeId == '017') { //Montreal
  	    officeUrl = "/eng/que/contact-our-team.jsp?oid=017";
  	}
  	else if (officeId == '023') { //Quebec City
  	    officeUrl = "/eng/que/contact-our-team.jsp?oid=023";
  	}
  	else if (officeId == '014') { //Regina
  	    officeUrl = "/eng/sask/contact-our-team.jsp?oid=014";
  	}
  	else if (officeId == '013') { //Saskatoon
  	    officeUrl = "/eng/sask/contact-our-team.jsp?oid=013";
  	}
  }
	return officeUrl;
 }

AppController.prototype.getProvinceName = function(officeId) {
  var provinceName;

  if (this.language == 'fr') {
    if (officeId == '022') { //Calgary
        provinceName = "Alberta, Territoires du Nord-Ouest et Nunavut";
    }   
    else if (officeId == '012') { //Edm
        provinceName = "Alberta, Territoires du Nord-Ouest et Nunavut";
    }
    else if (officeId == '011') { //Van
        provinceName = "Colombie-Britannique et Yukon";
    }
    else if (officeId == '024') { //Vic
        provinceName = "Colombie-Britannique et Yukon";
    }
    else if (officeId == '955') { //Kelowna
        provinceName = "Colombie-Britannique et Yukon";
    }
    else if (officeId == '015') { //Winn
        provinceName = "Manitoba";
    }
    else if (officeId == '018') { //Moncton
        provinceName = "Nouveau-Brunswick";
    }
    else if (officeId == '021') { //St John's
        provinceName = "Terre-Neuve-et-Labrador";
    }
    else if (officeId == '019') { //Halifax
        provinceName = "Nouvelle-Écosse";
    }
    else if (officeId == '027') { //Ott
        provinceName = "Ontario";
    }
    else if (officeId == '016') { //Tor
        provinceName = "Ontario";
    }
    else if (officeId == '025') { //Waterloo
        provinceName = "Ontario";
    }
    else if (officeId == '026') { //Windsor
        provinceName = "Ontario";
    }
    else if (officeId == '020') { //Charlottetown
        provinceName = "Île-du-Prince-Édouard";
    }
    else if (officeId == '017') { //Montreal
        provinceName = "Québec";
    }
    else if (officeId == '023') { //Quebec City
        provinceName = "Québec";
    }
    else if (officeId == '014') { //Regina
        provinceName = "Saskatchewan";
    }
    else if (officeId == '013') { //Saskatoon
        provinceName = "Saskatchewan";
    }
  }
  else { 
    if (officeId == '022') { //Calgary
        provinceName = "Alberta, Northwest Territories and Nunavut";
    }   
    else if (officeId == '012') { //Edm
        provinceName = "Alberta, Northwest Territories and Nunavut";
    }
    else if (officeId == '011') { //Van
        provinceName = "British Columbia and Yukon";
    }
    else if (officeId == '024') { //Vic
        provinceName = "British Columbia and Yukon";
    }
    else if (officeId == '955') { //Kelowna
        provinceName = "British Columbia and Yukon";
    }
    else if (officeId == '015') { //Winn
        provinceName = "Manitoba";
    }
    else if (officeId == '018') { //Moncton
        provinceName = "New Brunswick";
    }
    else if (officeId == '021') { //St John's
        provinceName = "Newfoundland and Labrador";
    }
    else if (officeId == '019') { //Halifax
        provinceName = "Nova Scotia";
    }
    else if (officeId == '027') { //Ott
        provinceName = "Ontario";
    }
    else if (officeId == '016') { //Tor
        provinceName = "Ontario";
    }
    else if (officeId == '025') { //Waterloo
        provinceName = "Ontario";
    }
    else if (officeId == '026') { //Windsor
        provinceName = "Ontario";
    }
    else if (officeId == '020') { //Charlottetown
        provinceName = "Prince Edward Island";
    }
    else if (officeId == '017') { //Montreal
        provinceName = "Québec";
    }
    else if (officeId == '023') { //Quebec City
        provinceName = "Québec";
    }
    else if (officeId == '014') { //Regina
        provinceName = "Saskatchewan";
    }
    else if (officeId == '013') { //Saskatoon
        provinceName = "Saskatchewan";
    }
  }
  return provinceName;
}

AppController.loadCountryBorders = function() {
    var countries = [];
    var country_poly_xy = [];
	$.ajax({url: '/js/countries.xml',
			method: 'GET',
            dataType: 'xml',
			success: function(xmlDoc) {
				if (APP_CONTROLLER.loaded_country_borders) {
					return;
				}				
				APP_CONTROLLER.loaded_country_borders = true;

                // should fix this to jquery methods...
				var elemcountries = xmlDoc.getElementsByTagName("c");
				var count = 0;
				var i;
				for (i = 0; i < elemcountries.length; ++i) {
					var elempolys = elemcountries[i].getElementsByTagName("p");
					var country = elemcountries[i].getAttribute("n");
//					countries[i] = country;
					var poly = [];
                    var minLat = 90;
                    var maxLat = -90;
                    var minLng = 180;
                    var maxLng = -180;
					for (var k = 0; k < elempolys.length; ++k)
					{
						poly[k] = [];
						var elempoints = elempolys[k].getElementsByTagName("o");
						var j;
						for (j = 0; j < elempoints.length; ++j) {
							var latlng = elempoints[j].firstChild.nodeValue.split(",");
                            poly[k].push(new GLatLng(parseFloat(latlng[1]),parseFloat(latlng[0])));
//							poly[k][2*j] = latlng[1];
//							poly[k][2*j+1] = latlng[0];
							++count;

                            // save the min/max pts for bounds
                            if (minLat > latlng[1]) minLat = parseFloat(latlng[1]);
                            if (maxLat < latlng[1]) maxLat = parseFloat(latlng[1]);
                            if (minLng > latlng[0]) minLng = parseFloat(latlng[0]);
                            if (maxLng < latlng[0]) maxLng = parseFloat(latlng[0]);
						}						
					}
                    APP_CONTROLLER.country_poly[country] = poly;

                    // store the country bounds for lookup
                    APP_CONTROLLER.country_bounds[country] = new GLatLngBounds(new GLatLng(minLat, minLng), new GLatLng(maxLat, maxLng));
				}
			}
		}
	);
}

