//
// File : rtwgmap-ui.js
//
// Description : Javascript functions for rendering components on a RTWGMap
//               implementation. 
//
// Contents    : 
//                                       
//
//


    
    
var topZOrder;
var tooltipDiv;

//
// prototype to re-render strings that have quotes, ampersands, etc
// into their html/xml entities so they don't bugger up any
// javascript calls for tooltips/other
//
String.prototype.entityify = function () {
    return this.replace(/\'/g, "&#39;").replace(/&/g, "&amp;").replace(/</g,        "&lt;").replace(/>/g, "&gt;");
};

String.prototype.quote = function () {
    var c, i, l = this.length, o = '"';
    for (i = 0; i < l; i += 1) {
        c = this.charAt(i);
        if (c >= ' ') {
            if (c === '\\' || c === '"') {
                o += '\\';
            }
            o += c;
        } else {
            switch (c) {
            case '\b':
                o += '\\b';
                break;
            case '\f':
                o += '\\f';
                break;
            case '\n':
                o += '\\n';
                break;
            case '\r':
                o += '\\r';
                break;
            case '\t':
                o += '\\t';
                break;
            default:
                c = c.charCodeAt();
                o += '\\u00' + Math.floor(c / 16).toString(16) +
                    (c % 16).toString(16);
            }
        }
    }
    return o + '"';
};


   //
    // Resizes the map and other widgets to match the
    // current browser/screen size
    //
	var resizeMapWidgets = function() {	
	
		//map height
//		var mapDiv = document.getElementById("map");
//		var height = screen.width*0.25 + "px";
		
//		if(mapDiv.clientWidth) {
//			height = mapDiv.clientWidth*0.65 + "px";
//		}
		
//		mapDiv.style.height = height;
//			alert(height);
//		if(map)
//		   	recenterMap();   
			
		//sideListing height
//		var sideListingDiv = document.getElementById("sideListing");
//		sideListingDiv.style.height = height;			
	}

    

    //
    // Render a region into HTML for the User Interface
    //
    function renderRegion(region){
        var html = "";
        if(region != null)
        {
         //
            // render the region as a link that calls "getMarkersForRegion(region.id)" when it's selected
            //
            html += '&nbsp;&nbsp;<b><a class ="fmAppLink" onmouseover="this.className=\'fmAppLink2\';" onmouseout="this.className=\'fmAppLink\';" href ="javascript:getMarkersForRegion('+ region.id +')">' + region.label + '</a>&nbsp;&nbsp;</b>';                           
        }
        
        return (html);
    }
         
   
   	//
	// Get the label/header for the side listings
	// @see returnFilteredMarkers
	//
	function getSideListingsLabel() {
        var label = "";

		var markerTypeLabel = markerInfo.markerTypeLabel;
        
        if(isFiltering() && selectedFilters[0] != null) {
        	return selectedFilters[0].label + ' ' + markerTypeLabel;
        }
        
    	if(globalRegion && globalRegion.label && markerTypeLabel != globalRegion.label ) { 
        	label = globalRegion.label + " " + markerTypeLabel;
        } else {
            label = markerTypeLabel;
        }
		
		return label;         
    }
    
    //
    // Rendering for Markers on the sidebar
    //
    var renderMarkerForSideListing = function(marker){
        var html = "";
        if(marker != null)
        {
	        //
            // render the marker as a link that calls "myclick(marker.id)" when it's selected
            // (shows the gmap bubble - information bubble usually)
            // with the marker's icon changing colour if/when the mouse is over the link
            //
            // In this implementation the sideListing text will be : 
            //                 <marker.name> - with a href/link to call myclick() to show the info bubble
            //                 <marker.address>  
            //                 <marker.town>  
            //                	
            
            // open the marker's info bubble if the sideListing link is clicked
            html += '<a class="smallText" href="javascript:myclick(' + marker.id + ')"';

            // add js to make the marker change it's icon if/when the mouse is over the link
		    var tooltipText = marker.tooltip.entityify();
     	                  
            html += '  onmouseover="bringToFront(' + marker.id + ');  showTooltip(gmarkers['+marker.id+'], \''+tooltipText+'\');  "';
            html += '  onmouseout="hideTooltip();  "';
			
			//side listing text
			html += '  >' +marker.name + '</a><br/>'; 
            if(marker.address)
                html += '<span class="smallText">' + marker.address  + '</span>' + '</a><br/>';
            if(marker.city)
                html += '<span class="smallText">' + marker.city + '</span><br/>';
            html += '<br/>';
        }
        
        return (html);
    }   
   
   
   //
   // Initialize the side listing with some simple instructions/overview
   //
   function initSideListing() {
   	    // get the type of gmarker. eg "Restaurants" or "Sites" or "Markets"
		var markerTypeLabel = markerInfo.markerTypeLabel;
		
	    var htmlList2 = '<div class="textBoldGrey">' + markerTypeLabel + '</div><div class="smallText"><br/>';
	    htmlList2 = htmlList2 + '<b>Instructions:</b>&nbsp;Click on a region above the map to zoom in on a particular area.<br/><br/>The region\'s ' + markerTypeLabel + ' will show up in this side bar. Click on a marker to view more information.';
	    
	    document.getElementById("sideListing").innerHTML = htmlList2;
   }

   //
    // Icon declarations
    //
    var colors = new Array('blue','red','green','yellow','purple','orange','white');
    var iconsArray = [];
    
    function loadIcons() {
    if(iconsArray[colors[0]])
         return;
         
    for (var i=0;i<colors.length;i++) {
    	//icon graphic
	    eval('iconsArray[\''+colors[i] +'\'] = new GIcon(G_DEFAULT_ICON);');
    	eval('iconsArray[\''+colors[i] +'\'].image =  "/app21/rtw/icons/maps/' + colors[i] +'.png";');
    	eval('iconsArray[\''+colors[i] +'\'].url =  "/app21/rtw/icons/maps/' + colors[i] +'.png";');
	    eval('iconsArray[\''+colors[i] +'\'].shadow = "/app21/rtw/icons/maps/shadow50.png";');
    	eval('iconsArray[\''+colors[i] +'\'].iconSize = new GSize(20, 34);');
	    eval('iconsArray[\''+colors[i] +'\'].shadowSize =new GSize(37, 34);');
    	eval('iconsArray[\''+colors[i] +'\'].iconAnchor = new GPoint(6, 34);');
	    eval('iconsArray[\''+colors[i] +'\'].infoWindowAnchor = new GPoint(5, 1);');
    }
  }
  
  
   /*
    Changes the URL of the Markers IconImage on the Fly.
    Note: This does not update any other variables of the icon so it
 expects the
    new image to be same shape etc. as the original

    Parameters:
    Index -- The position in the map.overlays array
    ImageURL -- The url to the new Image
 */ 

  GMap.prototype.changeMarkerImage = function (index, imageURL) {
    var b = this;
    //If IE do this
    if (document.all) {
       this.overlays[index].images[0].style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imageURL + "', sizingMethod='crop');";
    } else  {
       this.overlays[index].images[0].src = imageURL;
    }
 }; 

  
  //
  // (re)sets a marker's color
  //
  function setGMarkerColor(markerObj, color) 
  {   
    if(iconsArray == null || !iconsArray[colors[0]])
         loadIcons();
         
  	 var gmarker = gmarkers[markerObj.id];
  	 if(gmarker && iconsArray[color])  {
		 if (document.all) {
       		this.overlays[index].images[0].style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imageURL + "', sizingMethod='crop');";
    } else  {
       this.overlays[index].images[0].src = imageURL;
    }  	 
  	     gmarker.icon = iconsArray[color];
	     //gmarker.setImage( iconsArray[color].url );	   
	 }
  }
   
    //
    // Create a gmarker for a markerObj
    //
   function createGMarker(markerObj)
    {
       if(iconsArray == null || !iconsArray[colors[0]])
         loadIcons();
         
       var point = new GLatLng( markerObj.latitude, markerObj.longitude);               
       var icontype = markerObj.color;
	   if(!icontype)
	        icontype = 'red';
	        
       var gmarker = new GMarker(point,iconsArray[icontype]);
	   
	   // hide the marker for now, see manageMarkers()
	   gmarker.hide();
	   
       // show the info tabs when the user clicks on this gmarker
       GEvent.addListener(gmarker,"click",function(){ 
         showInfoTabs(gmarker, markerObj) 
       });
       
       //show/hide tooltips as user mouses over/out this gmarker
        GEvent.addListener(gmarker,"mouseover", function() {
          showTooltip(gmarker, markerObj.tooltip);
        });        
        GEvent.addListener(gmarker,"mouseout", function() {
		  hideTooltip();
        });    
        
       return gmarker;
    }


	//
	// Bring a marker to the foreground so it's highly visible to the end user
	//
    function bringToFront(markerId) {
    	var gmarker = gmarkers[markerId];
    	
    	if(!map.getInfoWindow().isHidden()) 
    	  return;
    	
    	if(gmarker) {
    	  var z = GOverlay.getZIndex(gmarker.getPoint().lat());
    	  map.removeOverlay(gmarker);    	 
		  if(z <0) z *= -1;	
		  z *= 100;
		  if(!topZOrder)
		     topZOrder = z;
		  
		  if(z < topZOrder) {
		    topZOrder += 10000000;
		    z = topZOrder;
		  } else {
		    topZOrder = z;
		  }
		  
		  var markerObj = null;
		  for(var m = 0; m< markerObjs.length; m++) {
		    if(markerObjs[m].id == markerId) {
		      markerObj = markerObjs[m];
		      break;
		    }
		  }    
		  
       var point = new GLatLng( markerObj.latitude, markerObj.longitude);                    
	            
	  function importanceOrder (gmarker,b) {
        return z;
      }
         
      var gmarker = new GMarker(point,{zIndexProcess:importanceOrder});
      gmarker.importance = 2;
      
//TODO merge with createGMarker() !?
      
//       if(markerObj.tooltip) 
//       		gmarker = new GMarker(point, {zIndexProcess:z});//,icon:iconsArray[icontype], title:markerObj.tooltip});
//	   else
//	   		gmarker = new GMarker(point,iconsArray[icontype]);
	   		
       // show the info tabs when the user clicks on this gmarker
       GEvent.addListener(gmarker,"click",function(){ showInfoTabs(gmarker, markerObj) });
   
         //show/hide tooltips as user mouses over/out this gmarker
        GEvent.addListener(gmarker,"mouseover", function() {
          showTooltip(gmarker, markerObj.tooltip);
        });        
        GEvent.addListener(gmarker,"mouseout", function() {
		  hideTooltip();
        });  
        
    	  map.addOverlay(gmarker);
    	  gmarkers[markerId] = gmarker;
    	}
    }
   
   

    //
    // show the info tabs for a markerObj when the user clicks it's gmarker
    // see createGMarker(markerObj)
    //
    function showInfoTabs(gmarker, markerObj) {
    
       // get the marker obj's information html
       var infoHtml = markerObj.infoHtml;
       var town = "";
       
       infoHtml += "<br/>";    
       //add a zoom-in link    
       infoHtml += "<span class=\"smallTextCenter\">[<a href=\"javascript:zoomIn('" + markerObj.id + "');\">Zoom In</a>]" + "</span>&nbsp;&nbsp;<br/>";
    
       // make sure the startaddress & town are initialized
       if(startAddress == null || startAddress == "null")
          startAddress = "";
       if(startCity == null || startCity == "") {
          if(globalRegion == null || globalRegion.town == null)
             town = markerObj.town;
          else if(globalRegion && globalRegion.town)
             town = globalRegion.town; // use the 'main' town in the last picked region
       }
       else {
          town = startCity;  // use the previously entered town
       }

       if(!town) town = "";
       
       // Build the gmarker's window tabs 
       var i =0;
       var infoTabs = [];
       
       //info html
       infoTabs[i++] = new GInfoWindowTab("Info", infoHtml);
       
       // directions html
       if( showDirections ) {
           var directionsHtml = "<div id=\"dir\" style=\"border: 0px solid #aaaaaa; width: 250px; height: 200px;  padding: 3px;\">";
           directionsHtml += "<table border='0'><tr><td valign='top' >To:</td>";	      
	       directionsHtml += "<td><b>" + markerObj.name + "</b><br/>" + markerObj.address + "<br/>";
	       if(markerObj.town) 
	       	  directionsHtml += markerObj.town;
	       directionsHtml += "</td></tr>";
	       //directionsHtml += "<tr><td>&nbsp;</td><td>&nbsp;</td></tr>";
	       directionsHtml += "<tr><td valign='top'>From:</td><td>&nbsp;</td></tr>";
	       directionsHtml += "<tr><td colspan='2'>";
	       directionsHtml += "  <table cellspacing=\"2\"><tr>";
	       directionsHtml += "        <td>&nbsp;</td><td>&nbsp;<span class=\"example\">e.g. '7000 113 ST NW'</span></td></tr>";
	       directionsHtml += "        <td><span class=\"example\">Address:<span>&nbsp;&nbsp;</td>";	       
	       directionsHtml += "        <td><input id=\"startAddressTxt\" value=\"" + startAddress + "\"></td></tr>";
	       directionsHtml += "    <tr><td width=\"80px\"><span class=\"example\">Town/City:</span>&nbsp;&nbsp;</td>";	       	       
	       directionsHtml += "        <td><input id=\"startCityTxt\" value=\"" + town + "\"></td></tr>";
	       directionsHtml += "    <tr><td>&nbsp;</td><td><input id=\"directions\" onclick=\"javascript:getDirections(" + markerObj.id + ");\"  type=\"button\" value=\"Get Directions\"/>";
	       directionsHtml += "  </td></tr></table>";
	       directionsHtml += "</td></tr></table></div>";
	
           infoTabs[i++] = new GInfoWindowTab("Directions", directionsHtml);
       }
         
       map.panTo( gmarker.getPoint() ); //gmarker.getLatLng());
       var opts = {maxWidth:340}; 
       hideTooltip();
       gmarker.openInfoWindowTabs(infoTabs, opts);
    }



      // ============ custom direction panel ===============
      function renderDirections(map,mapname,dirn,div) {
        var html = "";
      
        // ===== local functions =====

        // === waypoint banner ===
        function waypoint(point, type, address) {
          var target = '"' + mapname+".showMapBlowup(new GLatLng("+point.toUrlValue(6)+"))"  +'"';
          html += '<table style="border: 1px solid silver; margin: 10px 0px; background-color: rgb(238, 238, 238); border-collapse: collapse; color: rgb(0, 0, 0);">';
          if(type != "stop") 
	          html += '  <tr style="cursor: pointer;" onclick='+target+'>';
	      else 
	          html += '  <tr>';
	           
          html += '    <td style="padding: 4px 15px 0px 5px; vertical-align: middle; width: 20px;">';
          html += '      <img src="http://www.google.com/intl/en_ALL/mapfiles/icon-dd-' +type+ '-trans.png">'
          html += '    </td>';
          html += '    <td style="vertical-align: middle; width: 100%;">';
          html +=        address;
          html += '    </td>';
          html += '  </tr>';
          html += '</table>';
        }

        // === route distance ===
        function routeDistance(dist) {
          html += '<div style="text-align: right; padding-bottom: 0.3em;">' + dist + '</div>';
        }      

        // === step detail ===
        function detail(point, num, description, dist) {
          //don't allow popup for each step
          //var target = '"' + mapname+".showMapBlowup(new GLatLng("+point.toUrlValue(6)+"))"  +'"';
          html += '<table style="margin: 0px; padding: 0px; border-collapse: collapse;">';
          html += '  <tr>'; // dont allow popup for each step : style="cursor: pointer;" onclick='+target+'>';
          html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; text-align: right;">';
          html +=        num;  // dont allow popup for each step :  <a href="javascript:void(0)"> '+num+'. </a>';
          html += '    </td>';
          html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; width: 100%;">';
          html +=        description;
          html += '    </td>';
          html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px 0.3em 0.5em; vertical-align: top; text-align: right;">';
          html +=        dist;
          html += '    </td>';
          html += '  </tr>';
          html += '</table>';
        }

        // === Copyright tag ===
        function copyright(text) {
          html += '<div style="font-size: 0.86em;">' + text + "</div>";
        }
        

        // === read through the GRoutes and GSteps ===

        for (var i=0; i<dirn.getNumRoutes(); i++) {
          if (i==0) {
            var type="play";
          } else {
            var type="pause";
          }
          var route = dirn.getRoute(i);
          var geocode = route.getStartGeocode();
          var point = route.getStep(0).getLatLng();
          // === Waypoint at the start of each GRoute
          waypoint(point, type, geocode.address);
          routeDistance(route.getDistance().html+" (about "+route.getDuration().html+")");

          for (var j=0; j<route.getNumSteps(); j++) {
            var step = route.getStep(j);
            // === detail lines for each step ===
            detail(step.getLatLng(), j+1, step.getDescriptionHtml(), step.getDistance().html);
          }
        }
        
        // === Additional directions 
		// var additionalDirections = "From Kitscoty, 5 km west on H16, then 2 km s";
		// var nextStepNum = route.getNumSteps()+1; 
		
        //   html += '<table style="margin: 0px; padding: 0px; border-collapse: collapse;">';
        //   html += '  <tr>';
        //   html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; text-align: right;">';
        //   html += '      <a href="javascript:void(0)"> '+nextStepNum+'. </a>';
        //   html += '    </td>';
        //   html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; width: 100%;">';
        //   html += '       <b>' + additionalDirections + '</b>';
        //   html += '    </td>';
        //   html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px 0.3em 0.5em; vertical-align: top; text-align: right;">';
        //   html += '       &nbsp';
        //   html += '    </td>';
        //   html += '  </tr>';
        //   html += '</table>';
          
        // === the final destination waypoint ===   
        if(route) { 
        	var geocode = route.getEndGeocode();
        	var point = route.getEndLatLng();
        	waypoint(point, "stop", geocode.address);
		}
		                 
        // === the copyright text ===
        copyright(dirn.getCopyrightsHtml());

        
        // === append the whole thing into the target div 
        // === we're counting on the controller/caller to clear/modify the target beforehand
        div.innerHTML += html;

        // hide the last marker in the directions so we can still see the orig marker        
        dirn.getMarker(dirn.getNumRoutes()).hide();
        
      } // ============ end of renderDirections function ===========


     
    
      // ====== This function displays the tooltip ======
      // it can be called from an icon mousover or a side_bar mouseover
      function showTooltip(gmarker, tooltipText) {    
      
        if(!map.getInfoWindow().isHidden()) { 
          return; // the info window is visible, don't show tool tips for markers 
        }
        
        if(tooltipDiv == null) {
          tooltipDiv = document.createElement("div")
          document.getElementById("map").appendChild(tooltipDiv);
        }       
        
        if( ! map.getBounds().contains( gmarker.getPoint() ) ){
        	return; //marker isn't on the current view
        }
        

        
      	tooltipDiv.innerHTML = '<div class="tooltip">'+tooltipText+'</div>';
		var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.getBounds().getSouthWest(),map.getZoom());
		var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(gmarker.getPoint(),map.getZoom());
		var anchor=gmarker.getIcon().iconAnchor;
		var width=gmarker.getIcon().iconSize.width;
		var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(offset.x - point.x - anchor.x + width,- offset.y + point.y +anchor.y)); 
		pos.apply(tooltipDiv);
		tooltipDiv.style.visibility="visible";
		
	
      }    
      
      
      function hideTooltip() {
        if(tooltipDiv != null)
        	tooltipDiv.style.visibility="hidden";
      }     
      
     //
     // Zooms out until at that at least one of the markers on the map
     // is visible in the window
     //
     function panZoomToAtLeastOneVisibleMarker() {
 		var currentZoom = map.getZoom();
 		for(var i=currentZoom; i>= 0; i--) {
			if(	isAtLeastOneMarkerVisible() ) {
				break;
			}
			map.setZoom(i);
 		} 		
 	}
     
     //
     // Pan/Zoom Out so that all the markers on the map are visible in the window
     // 
     function panZoomToVisibleMarkers() {
 	
 		var bounds = getVisibleMarkersBounds();
 		
 		// if the map bounds aren't already the enclosing envelope, reset it
 		if( bounds && !map.getBounds().containsBounds( bounds ) ) {
			var zoomLevel = map.getBoundsZoomLevel( bounds );
			if(zoomLevel >= 13) 
				zoomLevel = 10;
			map.setCenter(bounds.getCenter(), zoomLevel);
 		}
 	}
 	
 	//
 	// returns true if at least one marker is visible and within
 	// the current view on the map
 	//
	function isAtLeastOneMarkerVisible() {
 		for(m in gmarkers)  { 		
 			if( !gmarkers[m].isHidden() && map.getBounds().contains( gmarkers[m].getPoint() ) ) {
 				return true;
 			}
 		}
 		return false;
 	}
 	
 	
 	function getVisibleMarkersBounds() {
 		// get the enclosing envelope/rectangle for all the visible markers
 		var bounds = null;
 		var count = 0;
 		for(m in gmarkers)  { 		
 			if( !gmarkers[m].isHidden() ) {
 				count++;
 				if(!bounds) {
	 				bounds = new GLatLngBounds( gmarkers[m].getPoint(), gmarkers[m].getPoint() );
	 			} else {
	 				bounds.extend( gmarkers[m].getPoint() );
	 			}
 			}
 		}
 		return bounds;
 	}
 	

	function resizeMapToFitWindow() {
	alert("resizeMapToFitWindow is deprecated");
	
	//sf 20071205 doesn't work in XP IE!
//		var frameW = document.body.offsetWidth;
//	    var frameH = document.body.offsetHeight;

//    	var imgh = frameH - 70;
//	    var imgw = imgh * 0.773; //0.77292;


//		img.style.height = imgh;
//		img.style.width = imgw;
	}


function resize(img) {


	var frameW = document.body.offsetWidth;
    var frameH = document.body.offsetHeight;

    var imgh = frameH - 70;
    var imgw = imgh * 0.773; //0.77292;

    //don't enlarge above the orig size
    if( img.naturalHeight ) {
    	if(imgh > getNaturalHeight(img)) {
      		imgh = img.naturalHeight;
      		imgw = img.naturalWidth;
    	} 
    } else { 
     	var lgi = new Image();
        lgi.src = img.src;
    	if(imgh > lgi.height) {
      		imgh = lgi.height;
      		imgw = lgi.width;
    	} 
    }

	img.style.height = imgh;
	img.style.width = imgw;
	img.style.visibility = "visible"; 
}


 
 
 
 