

/**
 * Handles creating a Google Map marker when the marker's info text and the marker's
 * location are both separately returned asynchronously and in arbitrary order.
 * If no search results are returned, then this instance can be invalidated and reset
 * for continued reuse.
 */
function MarkerFuture(gmap){
  this.gmap = gmap;  
  this.point = null;
  this.setPointCalled = false;  
  this.xmlDocument = null;
  this.setXmlDocumentCalled = false;  
}
MarkerFuture.prototype.setPoint = function(point){
  this.setPointCalled = true;
  this.point = point;
  this.createPoint();
}
MarkerFuture.prototype.setXmlDocument = function(xmlDocument){
  	this.setXmlDocumentCalled = true;
  	this.xmlDocument = xmlDocument;  
  	this.createPoint();
}
MarkerFuture.prototype.createPoint = function(){
  	if (this.setXmlDocumentCalled && this.setPointCalled) {
  		this.setXmlDocumentCalled = false;
  		this.setPointCalled = false;
    	this.plotPoint();
	}
}
MarkerFuture.prototype.setCenter = function(center, zoomLevel) {
	this.gmap.setCenter(center, zoomLevel);
}

MarkerFuture.prototype.plotPoint = function()
{
	var serviceStationElements = this.xmlDocument.getElementsByTagName("ServiceStation");
	for (var i = 0; i < serviceStationElements.length; i++) {
		var companyNameElement = serviceStationElements[i].getElementsByTagName("CompanyName")[0];
		var plantTypeElement = serviceStationElements[i].getElementsByTagName("PlantType")[0];
		var plantStatusElement = serviceStationElements[i].getElementsByTagName("PlantStatus")[0];
		var addressElement = serviceStationElements[i].getElementsByTagName("Address")[0];
		var cityNameElement = addressElement.getElementsByTagName("City")[0];
		var streetElement = addressElement.getElementsByTagName("Street")[0];
		var phoneNumberElement = addressElement.getElementsByTagName("PhoneNumber")[0];
		var stateElement = addressElement.getElementsByTagName("State")[0];
		var zipCodeElement = addressElement.getElementsByTagName("ZipCode")[0];
		var point = null;
						
		var latElements = serviceStationElements[i].getElementsByTagName("Latitude");
		var lngElements = serviceStationElements[i].getElementsByTagName("Longitude");
		var lat =  0;
        if(latElements[0].firstChild != null)
            lat = latElements[0].firstChild.data;
		var lng = 0;
        if(lngElements[0].firstChild != null)
            lng = lngElements[0].firstChild.data;
        
        point = new GLatLng(lat,lng);
		var tinyIcon = new GIcon();

		if(plantTypeElement.firstChild != null && plantTypeElement.firstChild.data == 'Processor Preferred Processor Plant')
		{
			tinyIcon.image = "images/processors.png" ;
		}
		else if(plantTypeElement.firstChild != null && plantTypeElement.firstChild.data == 'Ethanol Service Station')
        {
            tinyIcon.image = "images/ethanol.png";
        }
        else
        {
            tinyIcon.image = "images/generic.png";
        }

		tinyIcon.iconSize = new GSize(24, 16);
		tinyIcon.iconAnchor = new GPoint(8, 16);
		tinyIcon.infoWindowAnchor = new GPoint(5, 1);
		var streetData = "";
		if(streetElement.firstChild != null)
			streetData = streetElement.firstChild.data +", ";
			
	    var phoneNumber = "";
		if(phoneNumberElement.firstChild != null)
			phoneNumber = phoneNumberElement.firstChild.data;
		var plantType = "";
        if(plantTypeElement.firstChild != null)
            plantType = plantTypeElement.firstChild.data;	
		var plantStatus = "";
		if(plantStatusElement.firstChild != null)
			plantStatus = " (" + plantStatusElement.firstChild.data +")";
		var html = "<font color='AA3300'><B>" + plantType + plantStatus + "</B></font><br/> <font color='green'> " + companyNameElement.firstChild.data + "</font><br/> "  + streetData  +   cityNameElement.firstChild.data + ", " + stateElement.firstChild.data +"<br/> " + phoneNumber ;
		var label = "";
		var marker = this.getMarker(point,label,html, tinyIcon);

        var bookMarkHtml =  "<img src='images/processors.png'/>" + " Processor Preferred Processor Plants  <br/> ";
        bookMarkHtml += "<img src='images/generic.png'/>"  + " Ethanol Plants     &nbsp;     &nbsp;    ";
        bookMarkHtml += "<img src='images/ethanol.png'/>"  + " Ethanol Service Stations   ";
        var bookMarkElement = $('bookmark');
		bookMarkElement.innerHTML = bookMarkHtml;
	}
	
}
MarkerFuture.prototype.getMarker = function(point,label,html, tinyIcon) 
{
	var markerOptions = { icon:tinyIcon };
	        var marker = new GMarker(point, tinyIcon);	
			 GEvent.addListener(marker, "click", function() {
				marker.openInfoWindowHtml(html);
			 });
			
	this.gmap.addOverlay(marker);   		
	 
}


//Handles Google zipcode callback, recenters map
function GeocodeCallbackHandler(gmap, markerFuture){
  this.gmap = gmap;
  this.markerFuture = markerFuture;
}
GeocodeCallbackHandler.prototype.callback = function(point){

		if($('zip').value.length == 0){
			this.gmap.setCenter(center, UNITED_STATES_ZOOM_LEVEL);
		}
		else{
			var center = null; 
			geocoder = new GClientGeocoder(); 
			geocoder.getLatLng($('zip').value , function(point) { 
				if (!point) { 
				} else { 
				
				center = point; 
				} 
				this.gmap.setCenter(center, DEFAULT_ZOOM_LEVEL);
			}); 
		}
		this.markerFuture.setPoint(point);
}

//Handles map service callback
function MapServiceCallbackHandler(xmlHTTP, xmlHandler){
  this.xmlHTTP = xmlHTTP;
  this.xmlHandler = xmlHandler;
}
MapServiceCallbackHandler.prototype.clear = function(){
	if (this.xmlHandler.clear) {
		this.xmlHandler.clear();
	}
}
MapServiceCallbackHandler.prototype.callback = function(){
  if (this.xmlHTTP.readyState == 4) {
    var xmlDocument = GXml.parse(this.xmlHTTP.responseText);
    this.xmlHandler.handleXML(xmlDocument);
  }
}

// Interface of all XMLHandlers
function XMLHandler(){
}
XMLHandler.prototype.handleXML = function(xmlDocument) {
	
}
XMLHandler.prototype.clear = function() {
}

//Composite XMLHandler contains an array of XMLHandlers
function CompositeXMLHandler(xmlHandlerArray){
  this.xmlHandlerArray = xmlHandlerArray;
}
CompositeXMLHandler.prototype = new XMLHandler();
CompositeXMLHandler.prototype.handleXML = function(xmlDocument) {
  for (var i=0; i<this.xmlHandlerArray.length; i++){
    var xmlHandler = this.xmlHandlerArray[i];
    xmlHandler.handleXML(xmlDocument);
  }
}
CompositeXMLHandler.prototype.clear = function() {
  for (var i=0; i<this.xmlHandlerArray.length; i++){
    var xmlHandler = this.xmlHandlerArray[i];
    if (xmlHandler.clear) {
    	xmlHandler.clear();
    }
  }
}

function MapUpdater(gmap, markerFuture){
  this.gmap = gmap;
  this.markerFuture = markerFuture;
}
MapUpdater.prototype = new XMLHandler();
MapUpdater.prototype.clear = function() {
	this.gmap.clearOverlays();
}
MapUpdater.prototype.handleXML = function(xmlDocument) {

	this.markerFuture.setXmlDocument(xmlDocument);

}

//Makes call to Google to Geocode zipcode returned in XML
function MapGeocoder(geocoder, geocodeCallbackHandler){
  this.geocoder = geocoder;
  this.geocodeCallbackHandler = geocodeCallbackHandler;
}
MapGeocoder.prototype = new XMLHandler();
MapGeocoder.prototype.clear = function() {
}
MapGeocoder.prototype.handleXML = function(xmlDocument) {
    var zipCode = $('zip').value;
    var callbackHandler = this.geocodeCallbackHandler;
    this.geocoder.getLatLng(zipCode, function(point){callbackHandler.callback(point);});
 
}


