var geoExec = new MQExec(geoServerName,mqServerPath,mqServerPort,proxyServerName,proxyServerPath,proxyServerPort);
var sonicIcon = new MQA.Icon(iconLogoUrl, 30, 31);
var sonicIconNew = new MQA.Icon(iconNewLogoUrl, 30, 31);
var sonicIconUpcoming = new MQA.Icon(iconUpcomingLogoUrl, 30, 31);
/*
* Helper function to take an MQAddress and create a string from that address and add it to the node provided.
* Pre-Condtion: The node must exist
* Post-Condition: The MQAddress is converted to a string and appended to the node provided.
*
* @param        loc - an MQAddress object
* @param        node - a node element
* @author       Seisan Consulting   2-16-2006
* Modified      Barkley 8-14-2008
*/
function addressToString(loc, node){
    var b;
    if(loc.getStreet() != ""){
        node.appendChild(document.createTextNode(loc.getStreet()));
        node.appendChild(document.createTextNode(", "));
    }
    addSp = false;
    if(loc.getCity() != ""){
        node.appendChild(document.createTextNode(loc.getCity()));
        addSp = true;
    }
    if(loc.getState() != ""){
        if(addSp)
            node.appendChild(document.createTextNode(", "));
        node.appendChild(document.createTextNode(loc.getState()));
        addSp = true;
    }
    if(loc.getPostalCode() != ""){
        if(addSp)
            node.appendChild(document.createTextNode(" "));
        node.appendChild(document.createTextNode(loc.getPostalCode()));
        addSp = true;
    }
}


/*
*Revised:   10-24-2007
*By:        MapQuest - D.Weakley
*Details:   Revised for initial FUJAX compatibility
*/

/*
* Function to format a floating point distance value to 2 decimals
* Pre-Condtion: The dist value must be > 0
* Post-Condition: The distance is returned as a floating point number formatted to 2 decimal places.
*
* @param        dist - floating point number containing a distance value
* @return   Formated distance value to 2 decimals
* @author       Seisan Consulting   2-16-2006
*/
function formatDistance(dist){
    dist = parseFloat(dist);
    if(dist < .01 && dist > 0)
        return .01;
    else {
        var d = parseInt(parseFloat(dist) * 100);
        return parseFloat(d)/ 100;
    }
}


function getResultsAsArray(recordSet, featureCollection){
        // An array of data manager records
        var results = new Array();
        var dmRecord;
        
        var resultsHash = new Array();
        recordSet.moveFirst();
        while(!recordSet.isEOF())
        {
            dmRecord = new DataManagerRecord(recordSet);
            resultsHash[dmRecord.getId()] = dmRecord;
            
            recordSet.moveNext();
        }
        
        // featureCollection is in the order we want.  Build results to match
        if(featureCollection)
        {
            for(var i=0; i < featureCollection.getSize(); i++)
            {
                dmRecord = resultsHash[featureCollection.getAt(i).getKey()];
                dmRecord.setDistance(featureCollection.getAt(i).getDistance()); 
                results.push(dmRecord);                       
            }
        }
        return results;
}

function getEventCurrentTarget(e){
        var targ
        if (!e)
        {
            var e = window.event;
        }
        if (e.currentTarget) 
        {
            targ = e.currentTarget;
        }
        else if (e.srcElement)
        {
             targ = e.srcElement;
        }
        
        /** Because Microsoft uses event bubbling instead of event capture 
           we might have to work back through elements to find one with our id.
           NOTE: This implies you can't have an inner element with an id and have this WORK!
           **/
        while ( !targ.id )
        {
            targ = targ.parentNode;
        }
        return targ;
}

/*
* Function to break down and validate a MapQuest Result code from a Geocode.
* Pre-Condtion: The resultcode must exist.
* Post-Condition: A boolean value is returned containing the evaluation of the resultcode based on level of acceptance.
*
* @param        rCode - a MapQuest Geocode Result Code
* @return       A boolean value containing the evaluation of the result code. True is acceptable, false is not.
* @author       Seisan Consulting   2-16-2006
* Modified      Barkley 08-21-2008
*/
function validateResultCode(rCode){
    var granularity = "", streetConfidence = "", adminAreaConfidence = "", postalCodeConfidence = "";
    //Invalid Result Code - garbage data
    if(rCode.length < 5)
        return false;
    //Breakdown of result code
    //First 2 digits of result code is granularity
    granularity = rCode.substring(0,2);
    //Breakdown of Quality Code
    streetConfidence = rCode.charAt(2);
    adminAreaConfidence = rCode.charAt(3);
    postalCodeConfidence = rCode.charAt(4);

    //Granularitys Accepted
    if(granularity.indexOf("L") >= 0
        || granularity.indexOf("I") >= 0
        || granularity.indexOf("B") >= 0
        || granularity.indexOf("Z") >= 0
        || granularity.indexOf("A5") >= 0){

        //Two possibilities of quality codes accepted
        // SFD: Modified to allow just ZIP
        //if((adminAreaConfidence == "A" && postalCodeConfidence == "A")
        if((postalCodeConfidence == "A")
            || (adminAreaConfidence == "A" && postalCodeConfidence == "X")){
                return true;
        }
    }

    return false;
}

    function geocodeAddress(address, gaCollection)
    {   
        // Try to geocode the address        
        geoExec.geocode(address, gaCollection);
        
        // See if geocode was successful
        if ( gaCollection.getSize() == 0 )
        {
            return "LOCATION_NOT_FOUND";
        }
        else if ( gaCollection.getSize() == 1 )
        {
            var geoAddr = gaCollection.getAt(0);
            if ( validateResultCode(geoAddr.getResultCode()))
            {
                return geoAddr;
            }
            else
            {              
                return "LOCATION_NOT_EXACT";
            }
        }
        else
        {
            return "LOCATION_AMBIGUOUS";
        }        
    }
    
    function poiEvents(map)
    {
        this.map = map;
        
        this.onPoiMouseover = function(e)
        {    
            var poiid = false;
            var poi = null;
            //If the key is defined then a Poi has triggered this event
            var infowindow = map.getInfoWindow();
    
            
            if(this.getKey)
            {
                if(this != infowindow.getOpener())
                {
                    if(!infowindow.isHidden())
                    {
                        infowindow.hide();
                    }
                }
                poiid = this.getKey();
            }
            else 
            {
            
                //The result on the result table has triggered the event
                if (infowindow != null) 
                {
                    if(!infowindow.isHidden())
                    {
                        infowindow.hide();
                    }
                }

                var obj = getEventCurrentTarget(e);
                poiid =  obj.id;
                poiid = poiid.substring(poiid.lastIndexOf("_")+1);       
            }
        
            //retrieve the correct element entry from the results based on the key of the poi that triggered the event
            var matchingElement = document.getElementById("addrElement_" + poiid);
            
            //Switch the class names of the table rows to the class for the highlighted table row
            if(matchingElement.className.indexOf("Over") == -1){
                matchingElement.className = "roundCorner sonicLocationListItemOver";
            }
    
            //Retrieve the poi based on the key read from the list entry that triggered the event
            poi = map.getShapeByKey(poiid);
    
            if(poi != null)
            {
                poi.showInfoWindow();
            }

        }
    
        this.onPoiMouseout = function(e)
        {
            var poiid = false;
            var poi = null;
            
            if(this.getKey)
            {
                poiid = this.getKey();
    
                //retrieve the correct list entry from the results based on the key of the poi that triggered the event
                var li = document.getElementById("addrElement_" + poiid);
            
                //Switch the class names of the table rows to the class for the highlighted table row
                if(li.className.indexOf("Over") > -1){
                    li.className = "roundCorner";
                }
    
            }
            else 
            {
                //The result on the result table has triggered the event
                var obj = getEventCurrentTarget(e);
                poiid =  obj.id;
                poiid = poiid.substring(poiid.lastIndexOf("_")+1);
                
    
                 //retrieve the correct list entry from the results based on the key of the poi that triggered the event
                var li = document.getElementById("addrElement_" + poiid);
            
                //Switch the class names of the table rows to the class for the highlighted table row
                if(li.className.indexOf("Over") > -1){
                    li.className = "roundCorner";
                }
    
                //Retrieve the poi based on the key read from the table row that triggered the event
                if (map != null) {
                    poi = map.getShapeByKey(poiid);
                }
                
                if(poi != null){
                    map.getRolloverWindow().hide();
                    map.getInfoWindow().hide();
                }
            }
        }
        
        this.onPoiClick = function(e)
        {
            var poiid = false;
            var poi = null;
        
            //If the key is defined then a Poi has triggered this event
            if(this.getKey)
            {         
                poiid = this.getKey();
            }
            else 
            {
                //The result on the address list has triggered the event
                var obj = getEventCurrentTarget(e);
                poiid =  obj.id;
                poiid = poiid.substring(poiid.lastIndexOf("_")+1); 
            }
             
    
            // get the poi and show the info window
            poi = map.getShapeByKey(poiid);
    
            if(poi != null)
            {
                poi.showInfoWindow();
            }
        }
    }
    
    /*
    *  create a map and add a controls
    */
    function startMap(mapDivId){

        document.getElementById(mapDivId).style.visibility="visible";
        document.getElementById(mapDivId).style.width=570;
        document.getElementById(mapDivId).style.height=300;  

        mapRef = new MQA.TileMap(document.getElementById(mapDivId));
        mapRef.setSize(new MQA.Size(570,300));
        mapRef.addControl(new MQA.LargeZoomControl(), new MQA.MapCornerPlacement(MQA.CORNER_TOPLEFT, new MQA.Size(-50, 0))); 
        mapRef.addControl(new MQA.ViewControl(), new MQA.MapCornerPlacement(MQA.CORNER_BOTTOMRIGHT, new MQA.Size(80, -21)));
        mapRef.addControl(new MQA.TrafficControl(), new MQA.MapCornerPlacement(MQA.CORNER_BOTTOMRIGHT, new MQA.Size(0, 23)));
        mapRef.setMapShadowState(true);
        
        return mapRef;
    }

   function buildNewStoreLocationsDivList(sdiLocs)
   {
   		var sdiLocsDiv = document.createElement("div");
   		sdiLocsDiv.id="ld1";      
        sdiLocsDiv.className = "newLocationList";
        
        for( var i=0; i < sdiLocs.length; i++)
        {            
            // Build out address list of SONIC locations:
            var sdiLocsRowDiv =  document.createElement("div");
            sdiLocsRowDiv.style.background="#999999";
                        
            var sdiLocsRowContentDiv = document.createElement("div");
            sdiLocsRowContentDiv.className = "roundCornerContent";
            
            var sdiLocsRowDivLeft =  document.createElement("div");
            sdiLocsRowDivLeft.className = "firstColumn";
            sdiLocsRowDivLeft.appendChild(document.createTextNode( sdiLocs[i].getState() ));  
            
            var sdiLocsRowDivCenter =  document.createElement("div");
            sdiLocsRowDivCenter.className = "secondColumn";
            sdiLocsRowDivCenter.appendChild(document.createTextNode( sdiLocs[i].getCity() ));
                
            // search by lat long to ensure our result shows up first on the list. add .0001 to the latitude so that it doesn't bug the distance value:
            var searchQueryString = "?street="+sdiLocs[i].getStreet()
            					   +"&city="+sdiLocs[i].getCity()
            					   +"&state="+sdiLocs[i].getState()
            					   +"&zip="+sdiLocs[i].getPostalCode()
            					   +"&country="+sdiLocs[i].getCountry()
            					   +"&lat="+(sdiLocs[i].getMQLatLng().getLatitude() + 0.0001)
            					   +"&lng="+sdiLocs[i].getMQLatLng().getLongitude();
            
            var sdiLocsRowDivRight =  document.createElement("div");
            sdiLocsRowDivRight.className = "thirdColumn";
            sdiLocsRowDivRight.innerHTML = "<a href='"+newSearchUrl+searchQueryString+"'>"+sdiLocs[i].getStreet()+"</a>";

            sdiLocsRowContentDiv.appendChild(sdiLocsRowDivLeft);
            sdiLocsRowContentDiv.appendChild(sdiLocsRowDivCenter);
            sdiLocsRowContentDiv.appendChild(sdiLocsRowDivRight);
            
            sdiLocsRowDiv.appendChild(sdiLocsRowContentDiv);
            
            sdiLocsRowDiv.className = "roundCorner";
            sdiLocsRowDiv.id = 'addrElement_' + sdiLocs[i].getId(); 
            
            sdiLocsRowDiv.onmouseover = function(e) { this.className = "roundCorner sonicLocationListItemOver"; };
            sdiLocsRowDiv.onmouseout = function(e) { this.className = "roundCorner"; };
            
            sdiLocsDiv.appendChild(sdiLocsRowDiv);     
        }
  
        return sdiLocsDiv;
   }
   
   function buildStoreLocationsDivList(sdiLocs, poiEvnt, originAddr)
    {

        var divWrapper = document.createElement("div");
        
        var sdiLocsDiv = document.createElement("div");
        sdiLocsDiv.id="ld1";

        var sdiLocsPrint = document.createElement("ul");
        sdiLocsPrint.id = 'lul1';
        
        sdiLocsDiv.className = "sonicLocationList";
        sdiLocsPrint.className = "sonicLocationList";
        
        var sdiLocsHeaderDiv =  document.createElement("div");
        sdiLocsHeaderDiv.className = "roundCorner";
        sdiLocsHeaderDiv.style.background="#000000";
        
        var sdiLocsHeaderContentDiv = document.createElement("div");
        sdiLocsHeaderContentDiv.className = "roundCornerContent";
        
        var sdiLocsPrintHeader = document.createElement("li");
        
        var sdiLocsHeaderDivLeft =  document.createElement("div");
        sdiLocsHeaderDivLeft.className = "locFirstColumnHead white";
        
        var sdiLocsHeaderDivCenter =  document.createElement("div");
        sdiLocsHeaderDivCenter.className = "locMiddleColumnLocations white";
        sdiLocsHeaderDivCenter.appendChild(document.createTextNode("SONIC Drive-In Store Address"));
                
        var sdiLocsHeaderDivRight =  document.createElement("div");
        sdiLocsHeaderDivRight.className = "locLastColumnHead white";
        sdiLocsHeaderDivRight.appendChild(document.createTextNode("Distance"));
        
        sdiLocsHeaderContentDiv.appendChild(sdiLocsHeaderDivLeft);
        sdiLocsHeaderContentDiv.appendChild(sdiLocsHeaderDivCenter);
        sdiLocsHeaderContentDiv.appendChild(sdiLocsHeaderDivRight);
 
 		sdiLocsHeaderDiv.appendChild(sdiLocsHeaderContentDiv);
 		
        sdiLocsPrintHeader.innerHTML = sdiLocsHeaderDiv.innerHTML;
                   
        sdiLocsDiv.appendChild(sdiLocsHeaderDiv);
        sdiLocsPrint.appendChild(sdiLocsPrintHeader);       
               
        for( var i=0; i < sdiLocs.length; i++)
        {
        	// build driving directions links if an origin address was provide
        	var dd = null;
    	    if ( originAddr != null )
    	    {
    	    	dd = getDrivingDirectionsLink(originAddr, sdiLocs[i]);
    	    }
    	    
    	    // determine what icon to use:
			var storeStatus = sdiLocs[i].getField("OPENSTATUS");
			var iconToUse = sonicIcon;
			if(storeStatus == "New")
				iconToUse = sonicIconNew;
			else if(storeStatus == "Coming Soon")
				iconToUse = sonicIconUpcoming;
				
            poi = new MQA.Poi(sdiLocs[i].getMQLatLng(), iconToUse);
            
            poi.setValue('infoTitleHTML',sdiLocs[i].getInfoTitleHTML());
            poi.setValue('infoContentHTML', sdiLocs[i].getInfoHTML(dd) );
            poi.setKey(sdiLocs[i].getId());
            poi.setRolloverEnabled(true);
            MQA.EventManager.addListener(poi,"mouseover",poiEvnt.onPoiMouseover);
            MQA.EventManager.addListener(poi,"mouseout",poiEvnt.onPoiMouseout);
            MQA.EventManager.addListener(poi,"click",poiEvnt.onPoiClick);
            
            myMap.addShape(poi);
            
            // Build out address list of SONIC locations:
            var sdiLocsRowDiv =  document.createElement("div");
            sdiLocsRowDiv.style.background="#999999";
            if(storeStatus == "New")
            {
            	sdiLocsRowDiv.style.background="#5E82C1";
            }
            else if(storeStatus == "Coming Soon")
            {
            	sdiLocsRowDiv.style.background="#FF0400";
            }
            
            var sdiLocsRowContentDiv = document.createElement("div");
            sdiLocsRowContentDiv.className = "roundCornerContent";
            
            var sdiLocsPrintRow = document.createElement("li");
            sdiLocsPrintRow.className = "locatorPrintRow";
            
            var sdiLocsRowDivLeft =  document.createElement("div");
            sdiLocsRowDivLeft.className = "locFirstColumnNumber";
            sdiLocsRowDivLeft.appendChild(document.createTextNode( i+1 + ". "));  
            
            var sdiLocsRowDivCenter =  document.createElement("div");
            sdiLocsRowDivCenter.className = "locFirstColumn";
            addressToString(sdiLocs[i], sdiLocsRowDivCenter);
                
            var sdiLocsRowDivRight =  document.createElement("div");
            sdiLocsRowDivRight.className = "locLastColumn";
            if(storeStatus == "New" || storeStatus == "Coming Soon")
            	sdiLocsRowDivRight.className += " newUpcomingLocation";
            	
            if ( dd != null ) { sdiLocsRowDivRight.innerHTML += dd + "&nbsp;&nbsp;&nbsp;"; }
            sdiLocsRowDivRight.appendChild(document.createTextNode(formatDistance(sdiLocs[i].getDistance()) + " Miles"));
           
            sdiLocsRowContentDiv.appendChild(sdiLocsRowDivLeft);
            sdiLocsRowContentDiv.appendChild(sdiLocsRowDivCenter);
            sdiLocsRowContentDiv.appendChild(sdiLocsRowDivRight);

			sdiLocsRowDiv.appendChild(sdiLocsRowContentDiv);
			
            sdiLocsPrintRow.innerHTML = sdiLocsRowDiv.innerHTML;
            
            sdiLocsRowDiv.onmouseover = poiEvnt.onPoiMouseover;
            sdiLocsRowDiv.onmouseout = poiEvnt.onPoiMouseout;
            sdiLocsRowDiv.onclick = poiEvnt.onPoiClick;
                      
            sdiLocsRowDiv.className = "roundCorner";
            sdiLocsRowDiv.id = 'addrElement_' + sdiLocs[i].getId(); 
            
            sdiLocsDiv.appendChild(sdiLocsRowDiv);
            sdiLocsPrint.appendChild(sdiLocsPrintRow);       
 
        }
  
        divWrapper.appendChild(sdiLocsDiv);
        divWrapper.appendChild(sdiLocsPrint);
        return divWrapper;

    }    
    
    function getDrivingDirectionsLink(oAddr, dAddr)
    {
    	var dirLink = "<a class='drivingDirections' href='" + newTripSearchUrl + "?";
    	var firstParam=true;
    	if (oAddr.getStreet() != null && oAddr.getStreet().length > 0 )
    	{
    		if ( firstParam == false ) { dirLink += "&"; } else { firstParam = false; }
    		dirLink += "ostr=" + escape(oAddr.getStreet());
    	}
    	if (oAddr.getCity() != null && oAddr.getCity().length > 0 )
    	{
    		if ( firstParam == false ) { dirLink += "&"; } else { firstParam = false; }
    		dirLink += "oci=" + escape(oAddr.getCity());
    	}
    	if (oAddr.getState() != null && oAddr.getState().length > 0 )
    	{
    		if ( firstParam == false ) { dirLink += "&"; } else { firstParam = false; }
    		dirLink += "osta=" + escape(oAddr.getState());
    	}
    	if (oAddr.getPostalCode() != null && oAddr.getPostalCode().length > 0 )
    	{
    		if ( firstParam == false ) { dirLink += "&"; } else { firstParam = false; }
    		dirLink += "oz=" + escape(oAddr.getPostalCode());
    	}
    	if (oAddr.getCountry() != null && oAddr.getCountry().length > 0 )
    	{
    		if ( firstParam == false ) { dirLink += "&"; } else { firstParam = false; }
    		dirLink += "oco=" + escape(oAddr.getCountry());
    	}
    	if (dAddr.getStreet() != null && dAddr.getStreet().length > 0 )
    	{
    		if ( firstParam == false ) { dirLink += "&"; } else { firstParam = false; }
    		dirLink += "dstr=" + escape(dAddr.getStreet());
    	}
    	if (dAddr.getCity() != null && dAddr.getCity().length > 0 )
    	{
    		if ( firstParam == false ) { dirLink += "&"; } else { firstParam = false; }
    		dirLink += "dci=" + escape(dAddr.getCity());
    	}
    	if (dAddr.getState() != null && dAddr.getState().length > 0 )
    	{
    		if ( firstParam == false ) { dirLink += "&"; } else { firstParam = false; }
    		dirLink += "dsta=" + escape(dAddr.getState());
    	}
    	if (dAddr.getPostalCode() != null && dAddr.getPostalCode().length > 0 )
    	{
    		if ( firstParam == false ) { dirLink += "&"; } else { firstParam = false; }
    		dirLink += "dz=" + escape(dAddr.getPostalCode());
    	}
    	if (dAddr.getCountry() != null && dAddr.getCountry().length > 0 )
    	{
    		if ( firstParam == false ) { dirLink += "&"; } else { firstParam = false; }
    		dirLink += "dco=" + escape(dAddr.getCountry());
    	}
    	dirLink += "'/>(Directions)</a>";
    	return dirLink;
    }
    
    function formatTimeFromSeconds(timeInSeconds)
    {
        var d = Math.floor(timeInSeconds/86400);
        var h = (Math.floor(timeInSeconds/3600) - d*24)+'';        
        var m = (Math.floor(timeInSeconds/60) - h*60 - d*24*60)+'';
        var s = (timeInSeconds % 60)+'';  
              
        var ft = '';
        if ( d > 0 )
        {
            ft += d;
            if ( d > 1 ) { ft += " days, "; } else { ft += " day, "; }
        }       
        
        if ( h.length == 1 ) { h = '0' + h; }
        if ( m.length == 1 ) { m = '0' + m; }
        if ( s.length == 1 ) { s = '0' + s; }
                       
        ft += h + ":" + m + ":" + s;
        
        return  ft;
    }    
