/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*                                                                      *
*    Realogy Map Appliance Shared Library, rfgmapappliance.js, v.1.1   *
*                                                                      *
*----------------------------------------------------------------------*
* Notes: This script is automatically included in your web pages by    *
*        language specific bindings for the RFG map appliance, and     *
*        should not be manually included.  Several variables must be   *
*        declared before this script will function, it is not a        *
*        stand-alone script.                                           *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

//Constants
var g_DELTA = 69.09758507348
var g_PI180 = ( 3.141952653 / 180.0);
var g_EARTH_RADIUS = 3963.17;
var g_PI = 3.1415926535897932384626433832795;
var g_EARTH_CIR = (2 * g_PI * g_EARTH_RADIUS);
var g_MILES_PER_DEGREE_LATITUDE = (g_EARTH_CIR / 360.0);
var g_DEGREES_PER_MILE_LATITUDE = (360.0 / g_EARTH_CIR);

//Map Handlers and utilities
var g_pRfgMapContainer = new Array();
var g_pRfgWaitDlgContainer = new Array();
var g_aRfgCommandQueue = new Array();
var g_iPushPinSeq = 10000;
var g_iRadiusSeq = 0;
var g_bRfgOnLoadComplete = false;
var g_bShowErrorInformation = true;
var g_strErrorLogUrlFormat = '';
var g_strErrorLogFunction = '';
var g_RfgAjaxHandler = null;
var g_bVirtualEarthSupported = true;

//Pushpin Mouseovers
var g_iRfgSearchTipPosLeft = 0;
var g_iRfgSearchTipPosRight = 0;
var g_iRfgSearchTipPosTop = 0;
var g_iRfgSearchTipPosBottom = 0;
var g_bRfgSearchTipCancelCloseRequest = false;
var g_bRfgSearchTipTimeoutActive = false;
var g_bRfgSearchTipVisible = false;
var g_objRfgLastTooltip = new Object();

//Window event handlers
var g_pOldOnLoad = window.onload;
window.onload = RfgOnPageLoad;

/*----------------------------------------------------------------------\
| FUNCTION:    RfgQueueCommand                                          |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Command text to later execute.                           |
| PURPOSE:     Requests a command be executed after the page has fully  |        
|              loaded, or if the page is already loaded, now.           |
\----------------------------------------------------------------------*/
function RfgQueueCommand( strEncodedCommand )
{
   var strCommand = unescape(strEncodedCommand.replace(/\+/g," "));      
   if( !g_bRfgOnLoadComplete ) {         
      g_aRfgCommandQueue.push( strCommand );
   } else {
      eval( strCommand );
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgJsErrorHandler                                        |
| RETURNS:     True on cancel event, error condition handled            |
| PARAMETERS:  Service error occured in, exception                      |
| PURPOSE:     Allow connected scripts to handle error conditions if    |        
|              desired before passing to AJAX server handler(s).        |
\----------------------------------------------------------------------*/
function RfgJsErrorHandler( strService, exception )
{
   var bResult = false;
   if( g_strErrorLogFunction != '' ) {
      try {
         bResult = eval( g_strErrorLogFunction + "('"+strService+"', exception);");
      } catch (e) {
         bResult = false;
      }
   }
   return bResult;
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgAjaxErrorLogger                                       |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Error text                                               |
| PURPOSE:     If an AJAX error logger has been set, logs the map error |        
|              message to the server logger, and receives an executable |
|              response for detailed error reporting to client.         |
\----------------------------------------------------------------------*/
function RfgAjaxErrorLogger( strService, strErrorMessage )
{
   if( g_strErrorLogUrlFormat == '' ) return;
   if( strService == '' ) strService == 'unknown';

   if( g_RfgAjaxHandler == null ) {
      if (window.XMLHttpRequest) { // Non-IE browsers
         g_RfgAjaxHandler = new XMLHttpRequest();
      } else if (window.ActiveXObject){ // IE
         g_RfgAjaxHandler = new ActiveXObject("Microsoft.XMLHTTP");
      }
   }
   if( g_RfgAjaxHandler ) {
      var strFullErrorUrl = String.format( g_strErrorLogUrlFormat, escape(strErrorMessage) );
      g_RfgAjaxHandler.onreadystatechange = RfgAjaxErrorReplyHandler;
      g_RfgAjaxHandler.open("GET", strFullErrorUrl, true); 
      g_RfgAjaxHandler.send(null);
   }     
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgAjaxErrorReplyHandler                                 |
| RETURNS:     N/A                                                      |
| PARAMETERS:  N/A                                                      |
| PURPOSE:     Handles AJAX reply, and executes in JavaScript the reply |        
|              from the server.                                         |
\----------------------------------------------------------------------*/
function RfgAjaxErrorReplyHandler()
{
   //Only if the response is "OK" should we continue
   if (g_RfgAjaxHandler.readyState == 4){         
      if (g_RfgAjaxHandler.status == 200) {
         if(g_RfgAjaxHandler.responseText=="") {
            return false;
         } else {
            try {
               eval(g_RfgAjaxHandler.responseText);  
            } catch ( e ) {
               //On error at this point, fail silently, the server has processed this.
            }               
         }
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgCreateMap                                             |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Unique DIV object ID to load map into, map style,        |
|              boolean true to autosize on point add, lat/long to       |
|              initially center map, and zoom level. If bDelayMapRender |
|              is set to true, the map will only be created, not loaded |
|              and a future call to RfgRenderMap must be made, and if   |
|              VE maps should be fixed view maps.                       |
| PURPOSE:     Adds a map to the page in DIV id strMapObjectId.         |
\----------------------------------------------------------------------*/
function RfgCreateMap(strMapObjectId, strMapStyle, bAutoSize, fLatitude, fLongitude, iZoomLevel, bDelayMapRender, bFixedView, callback ) 
{
   try{
      var bForcedFallback = false;
      var bNeedDelayedAutoRender = false;
      g_bVirtualEarthSupported = g_MapService.IsBrowserVECompliant();
      var strCallback = null;
      if( callback && callback != '' ) {
         strCallback = callback;
      }
      if( strMapStyle.indexOf( 'MWS' ) >= 0 ){
          bFixedView = null;
      } else if (!g_bVirtualEarthSupported) {
         //Virtual earth is NOT supported, do not do it!
         bFixedView = null;
         strMapStyle = 'RoadMWS';
         bForcedFallback = true;
         bAutoSize = false;
         if( !bDelayMapRender ){
            bNeedDelayedAutoRender = true;
            bDelayMapRender = true;
         }
      }
      var pContainerDiv = document.getElementById( strMapObjectId );
      if( pContainerDiv ) {
         pContainerDiv.innerHTML = '';
      }
      if( bDelayMapRender && bDelayMapRender == true ) {
         g_pRfgMapContainer[strMapObjectId] = g_MapService.CreateMap(strMapObjectId, new LatLong(fLatitude, fLongitude), strMapStyle, null, iZoomLevel, bFixedView, null, strCallback, null, null, null, null, false);
      } else {
         g_pRfgMapContainer[strMapObjectId] = g_MapService.CreateAndLoadMap(strMapObjectId, new LatLong(fLatitude, fLongitude), strMapStyle, null, iZoomLevel, bFixedView, null, strCallback, null, null, null, null, false);
      }
      g_pRfgMapContainer[strMapObjectId].SetAutoSizeMap( bAutoSize );
      g_pRfgMapContainer[strMapObjectId].bRfgMapForcedFallback = bForcedFallback;
      if( bNeedDelayedAutoRender ) {
         //Give Safari about a second to finish up before finishing.
         setTimeout( function(){ RfgRenderMap(strMapObjectId); }, 1000 );  
      }
   } catch( xE ) {
      if( g_bShowErrorInformation ) {
         alert( xE.message );
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgRenderMap                                             |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to load                         |
| PURPOSE:     Renders a map that has been created with RfgCreateMap    |
\----------------------------------------------------------------------*/
function RfgRenderMap( strMapObjectId, callback )
{
   var pMap = g_pRfgMapContainer[strMapObjectId];      
   if( pMap ) {
      try{
         if( callback && callback != '' ) pMap.LoadMap(callback);
         else pMap.LoadMap();
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgShowMapDashboard                                      |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to load, true to show control,  |
|              false to hide control.                                   |
| PURPOSE:     Shows or hides the map control.                          |
\----------------------------------------------------------------------*/
function RfgShowMapDashboard( strMapObjectId, bShowControl )
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      if( pMap.bRfgMapForcedFallback ) {
         //Forced fallback maps can not attach.
         return;
      }
      try{
         if( bShowControl ) pMap.ShowDashboard();
         else pMap.HideDashboard();
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgGetMapById                                            |
| RETURNS:     Map object pointer                                       |
| PARAMETERS:  Map object id of the map to retrieve.                    |
| PURPOSE:     Gets handle to specific map object by objectid.          |
\----------------------------------------------------------------------*/
function RfgGetMapById( strMapObjectId )
{
   return g_pRfgMapContainer[strMapObjectId];
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgStartRadiusDrawMode                                   |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to start radius draw mode one,  |
|              callback function.                                       |
| PURPOSE:     Starts radius draw mode on an existing map.              |
\----------------------------------------------------------------------*/
function RfgStartRadiusDrawMode( strMapObjectId, callback ) 
{      
   var pMap = g_pRfgMapContainer[strMapObjectId];      
   if( pMap ) {
      try{
         g_iRadiusSeq++;
         var edgeColor = new ElementColor( 1, 255, 0, 0 );
         var fillColor = new ElementColor( 0.2, 255, 0, 0 );
         var radius = new Radius(('' + g_iRadiusSeq), new LatLong(0,0), 4.0, 
                                  edgeColor, 
                                  fillColor, 
                                  0.4);
         pMap.SetRadiusDrawMode( radius, true, callback );
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
         RfgAjaxErrorLogger( 'rfg', exception.message );
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgAttachMapEvent                                        |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to attach event to, event enum, |
|              callback function.                                       |
| PURPOSE:     Attaches an event to a map                               |
\----------------------------------------------------------------------*/
function RfgAttachMapEvent( strMapObjectId, event, callback ) 
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      if( pMap.bRfgMapForcedFallback ) {
         //Forced fallback maps can not attach.
         return;
      }
      try{
         pMap.AttachEvent( event, callback );
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
         RfgAjaxErrorLogger( 'rfg', exception.message );
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgDetachMapEvent                                        |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to detach event from, event enum|
|              function to detach.                                      |
| PURPOSE:     Detaches an event from a map                             |
| KNOWN BUGS:  DOESN'T WORK.                                            |
\----------------------------------------------------------------------*/
function RfgDetachMapEvent( strMapObjectId, event, callback ) 
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      if( pMap.bRfgMapForcedFallback ) {
         //Forced fallback maps can not detach.
         return;
      }
      try{
         pMap.DetachEvent( event, callback );
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
         RfgAjaxErrorLogger( 'rfg', exception.message );
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgAddGeoRssFeed                                         |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to add a push pins to,          |
|              URL of the GeoRSS feed to place on the map.              |
| PURPOSE:     Adds a pushpin to a map.                                 |
\----------------------------------------------------------------------*/
function RfgAddGeoRssFeed(strMapObjectId, strGeoRssUrl)
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      //We do not support even the most basic feeds on MWS fallback maps.
      if( pMap.bRfgMapForcedFallback ) return;
      try{
         pMap.ShowLocations( [ strGeoRssUrl ] );
         document.attachEvent( 'onmouseover', RfgMoveSearchToolTip );
         document.attachEvent( 'onmouseout', RfgMoveSearchToolTip );
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgAddPushPin                                            |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to add a push pin to,           |
|              lat/long of this pushpin, size of this push pin, HTML    |
|              to show for pushpin, and icon image to show.             |
| PURPOSE:     Adds a pushpin to a map.                                 |
\----------------------------------------------------------------------*/
function RfgAddPushPin(strMapObjectId, fLatitude, fLongitude, strEncodedTitle, strEncodedDetails, strIcon) 
{
   var strTitle =  unescape(strEncodedTitle.replace(/\+/g," "));
   var strDetails =  unescape(strEncodedDetails.replace(/\+/g," "));
   if( fLatitude == 0 && fLongitude == 0 ) return;
   if( strIcon == '' ) strIcon = null;
   var pMap = g_pRfgMapContainer[strMapObjectId];
   
   if( pMap ) {
      try{
         if( pMap.bRfgMapForcedFallback ) {
            strIcon = 'MapPoint.Icons:29';
            strDetails = '';
            strTitle = '';
         }
         g_iPushPinSeq++;
         var location = new LatLong( fLatitude, fLongitude );
         var dm = new DataMarker( strDetails, strIcon, null, null, true, false);
         var loc = new PushPin( ("" + g_iPushPinSeq), strTitle, location, dm );
         if( pMap.bRfgMapForcedFallback ) {
            //Safari does not serialize string properly, force to int.
            loc.id = parseInt( loc.id );
            loc.name = parseInt( g_iPushPinSeq );
         }
         pMap.AddSingleLocation( loc );
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
      }
   }
}

function RfgGetCurrentMapView( strMapObjectId )
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      return pMap.GetCurrentMapView();
   }
   return null;
}

function RfgSetCurrentMapView( strMapObjectId, mapView)
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      return pMap.SetCurrentMapView(mapView);
   }
   return null;
}


/*----------------------------------------------------------------------\
| FUNCTION:    RfgResizeMapToPoints                                     |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to resize, array of LatLong     |
|              points [new VeLatLong(fLat,fLon)] to resize this map to. |
| PURPOSE:     Resizes a map to a set of locations                      |
\----------------------------------------------------------------------*/
function RfgResizeMapToPoints(strMapObjectId, aVeLatLongPoints)
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      if( pMap.bRfgMapForcedFallback ) {
         //Forced fallback maps can not resize map points.
         return;
      }
      try{
         pMap.SetMapView(aVeLatLongPoints);
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgShowRadius                                            |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to add a push pin to,           |
|              lat/long of this pushpin, size of this push pin, HTML    |
|              to show for pushpin, and icon image to show.             |
| PURPOSE:     Adds a pushpin to a map.                                 |
\----------------------------------------------------------------------*/
function RfgShowRadius(strMapObjectId, fLatitude, fLongitude, fDistance, bAutoSize, strEdgeColor, strFillColor ) 
{      
   if( fLatitude == 0 && fLongitude == 0 ) return;
   if( fDistance <= 0 ) return;
   var pMap = g_pRfgMapContainer[strMapObjectId];
   
   if( pMap ) {
      try{
         g_iRadiusSeq++;
         var edgeColor = new ElementColor( 1, parseInt( '0x'+ strEdgeColor.substring( 0, 2)), 
                                              parseInt( '0x'+ strEdgeColor.substring( 2, 4)),
                                              parseInt( '0x'+ strEdgeColor.substring( 4, 6)));
         var fillColor = new ElementColor( 0.2, parseInt( '0x'+ strFillColor.substring( 0, 2)), 
                                                parseInt( '0x'+ strFillColor.substring( 2, 4)),
                                                parseInt( '0x'+ strFillColor.substring( 4, 6)));
         var rad = new Radius( ("" + g_iRadiusSeq), 
                               new LatLong(fLatitude, fLongitude),
                               fDistance,
                               edgeColor,
                               fillColor,
                               0.4 );            
         pMap.ShowRadius( rad );
         if( bAutoSize ){
            RfgAutoSizeMapToRadius( pMap, rad );
         }
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgOnPageLoad                                            |
| RETURNS:     N/A                                                      |
| PARAMETERS:  N/A                                                      |
| PURPOSE:     Internal document.onload handler -- saves previous       |
|              onload events and fires them after our onload events are |
|              complete.                                                |
\----------------------------------------------------------------------*/
function RfgOnPageLoad() 
{
   g_bRfgOnLoadComplete = true;
   while( g_aRfgCommandQueue.length > 0 ) {
      var strCmd = g_aRfgCommandQueue.shift();
      try{
         eval(strCmd);
      } catch( xE ) {            
         //Do not error on user defined code.
      }
   }
   
   if( g_pOldOnLoad ) g_pOldOnLoad();
}

/*----------------------------------------------------------------------\
| FUNCTION:   RfgAddMilesToLatitude                                     |
| RETURNS:    Calculated latitude                                       |
| PARAMETERS: latitude of the start point, # of miles to latitudally add|
|             to the starting latitude point                            |
| PURPOSE:    Calculates the latitudinal position of a point given the  |
|             starting latitude and latitudinal distance (in miles) from|
|             the starting latitude.                                    |
\----------------------------------------------------------------------*/
function RfgAddMilesToLatitude( dLatitude, dMiles){
   return dLatitude + (dMiles * g_DEGREES_PER_MILE_LATITUDE);
}

/*----------------------------------------------------------------------\
| FUNCTION:   RfgAddMilesToLongitude                                    |
| RETURNS:    Calculated longitude                                      |
| PARAMETERS: longitude and latitude of the start point, # of miles to  |
|             longitudinally add to the start point                     |
| PURPOSE:    Calculates the longitudinal position of a point given the |
|             start position and longitudinal distance (in miles) from  |
|             the start point.                                          |
\----------------------------------------------------------------------*/
function RfgAddMilesToLongitude( dLongitude, dLatitude, dMiles){
   return dMiles * (360 / (2 * g_PI * g_EARTH_RADIUS * Math.cos(g_PI180*Math.abs(dLatitude)))) + dLongitude;
}

/*----------------------------------------------------------------------\
| FUNCTION:   RfgAutoSizeMapToRadius                                    |
| RETURNS:    --                                                        |
| PARAMETERS: fRadius - the radius/distance of a circle/Radius object   |
| PURPOSE:    Calculates a map zoom level from a given radius.  This    |
|             provides the ability to 'autosize' a map based on a       |
|             Radius object being displayed.                            |
\----------------------------------------------------------------------*/
function RfgAutoSizeMapToRadius( pMap, eRadius ){
    try{
       //build latlon array to set map view.
       var aLocs = new Array();
       var latitude  = eRadius.centerPoint.latitude;
       var longitude = eRadius.centerPoint.longitude;
       var distance  = eRadius.distance;
       NorthLoc = new LatLong( RfgAddMilesToLatitude( latitude, eRadius.distance), longitude );
       SouthLoc = new LatLong( RfgAddMilesToLatitude( latitude, (-1*distance)), longitude );
       EastLoc  = new LatLong( latitude, RfgAddMilesToLongitude( longitude, latitude, distance) );
       WestLoc  = new LatLong( latitude, RfgAddMilesToLongitude( longitude, latitude, (-1*distance)) );
       aLocs.push(NorthLoc);
       aLocs.push(SouthLoc);
       aLocs.push(EastLoc);
       aLocs.push(WestLoc);
       pMap.SetMapView( aLocs );
    } catch( xE ){
       if( g_bShowErrorInformation ) {
          alert( xE.message );
       }
    }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgShowWaitDialog                                        |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to show dialog on, boolean true |
|              to grey map out while the dialog is showing (grabs input)|
|              optional additional text to show in the wait dialog above|
|              the progress bar, and (optional) HTML dialog override    |
|              which displays INSTEAD of the standard dialog and the    |
|              strAdditionalText parameter.                             |
| PURPOSE:     Overlays "wait" dialog on locations w/ cycling progress  |
\----------------------------------------------------------------------*/
function RfgShowWaitDialog( strMapObjectId, bGreyMap, strAdditionalText, strHtmlOverride )
{
   if( strAdditionalText == null ) strAdditionalText = '';
   var strWaitDlgDefaultHtml = '<table cellpadding=2 cellspacing=0 width="100%" height="100%">' + 
                               '<tr><td style="background-color: #B8B898; height: 19px;"><img src="'+g_strRfgClientSupportUrl+'/wait.gif" alt="Please Wait..."></td>' +
                               '<td align=right style="background-color: #B8B898;"><img src="'+g_strRfgClientSupportUrl+'/close.gif" alt="X" border=0 onClick="RfgHideWaitDialog(\''+strMapObjectId+'\');"></td></tr>' +
                               '<tr><td colspan=2 style="font-family: arial,helvetica;font-size:10px;">' + strAdditionalText + '</td></tr>' +
                               '<tr><td colspan=2><img src="'+g_strRfgClientSupportUrl+'/progressbar.gif"></td></tr>' +
                               '</table>';
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      try{
         if( g_pRfgWaitDlgContainer[strMapObjectId] ) {
            g_pRfgWaitDlgContainer[strMapObjectId].dlg.style.visibility = 'visible';
            if( bGreyMap ) g_pRfgWaitDlgContainer[strMapObjectId].mask.style.visibility = 'visible';

            if( strHtmlOverride ) g_pRfgWaitDlgContainer[strMapObjectId].dlg.innerHTML = strHtmlOverride;
            else g_pRfgWaitDlgContainer[strMapObjectId].dlg.innerHTML = strWaitDlgDefaultHtml;
         } else {
            var pMapContainerDiv = document.getElementById(strMapObjectId);
            var iMapWidth = parseInt(pMapContainerDiv.offsetWidth);
            var iMapHeight = parseInt(pMapContainerDiv.offsetHeight);

            g_pRfgWaitDlgContainer[strMapObjectId] = new Object();
            g_pRfgWaitDlgContainer[strMapObjectId].mask = document.createElement('div');
            g_pRfgWaitDlgContainer[strMapObjectId].mask.id = 'waitdlgmask_' + strMapObjectId;
            g_pRfgWaitDlgContainer[strMapObjectId].mask.style.top = '0px';
            g_pRfgWaitDlgContainer[strMapObjectId].mask.style.left = '0px';
            g_pRfgWaitDlgContainer[strMapObjectId].mask.style.width = iMapWidth + 'px';
            g_pRfgWaitDlgContainer[strMapObjectId].mask.style.height = iMapHeight + 'px';
            g_pRfgWaitDlgContainer[strMapObjectId].mask.style.opacity = .69;
            g_pRfgWaitDlgContainer[strMapObjectId].mask.style.MozOpacity = .69;
            g_pRfgWaitDlgContainer[strMapObjectId].mask.style.filter = 'alpha(opacity=69)';
            g_pRfgWaitDlgContainer[strMapObjectId].mask.style.background = 'White';
            if( bGreyMap ) g_pRfgWaitDlgContainer[strMapObjectId].mask.style.visibility = 'visible';
            else g_pRfgWaitDlgContainer[strMapObjectId].mask.style.visibility = 'hidden';

            var iChildWidth = 289;
            var iChildHeight = 87
            var iChildLeft = parseInt((iMapWidth-iChildWidth) / 2.0);
            var iChildTop = parseInt((iMapHeight-iChildHeight) / 2.0);

            g_pRfgWaitDlgContainer[strMapObjectId].dlg = document.createElement('div');
            g_pRfgWaitDlgContainer[strMapObjectId].dlg.id = 'waitdlgdlg_' + strMapObjectId;
            g_pRfgWaitDlgContainer[strMapObjectId].dlg.style.top = iChildTop + 'px';
            g_pRfgWaitDlgContainer[strMapObjectId].dlg.style.left = iChildLeft + 'px';
            g_pRfgWaitDlgContainer[strMapObjectId].dlg.style.width = iChildWidth + 'px';
            g_pRfgWaitDlgContainer[strMapObjectId].dlg.style.height = iChildHeight + 'px';
            g_pRfgWaitDlgContainer[strMapObjectId].dlg.style.background = '#F0F0E4';
            g_pRfgWaitDlgContainer[strMapObjectId].dlg.style.border = '1px solid #989890';

            if( strHtmlOverride ) g_pRfgWaitDlgContainer[strMapObjectId].dlg.innerHTML = strHtmlOverride;
            else g_pRfgWaitDlgContainer[strMapObjectId].dlg.innerHTML = strWaitDlgDefaultHtml;

            if( pMap.GetMapStyle().indexOf( 'MWS' ) >= 0 ) {
               g_pRfgWaitDlgContainer[strMapObjectId].mask.style.zIndex = 9999999998;
               g_pRfgWaitDlgContainer[strMapObjectId].dlg.style.zIndex = 9999999999;
               g_pRfgWaitDlgContainer[strMapObjectId].dlg.style.position = 'absolute';
               pMapContainerDiv.appendChild( g_pRfgWaitDlgContainer[strMapObjectId].mask );
               pMapContainerDiv.appendChild( g_pRfgWaitDlgContainer[strMapObjectId].dlg );
            } else {
               pMap.AddControl(g_pRfgWaitDlgContainer[strMapObjectId].mask, null);
               pMap.AddControl(g_pRfgWaitDlgContainer[strMapObjectId].dlg, null);
            }
         }
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgHideWaitDialog                                        |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to hide dialog on               |
| PURPOSE:     Hides wait (or custom) dialog on specified map           |
\----------------------------------------------------------------------*/
function RfgHideWaitDialog( strMapObjectId )
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      try{
         if( g_pRfgWaitDlgContainer[strMapObjectId] ) {
            g_pRfgWaitDlgContainer[strMapObjectId].dlg.style.visibility = 'hidden';
            g_pRfgWaitDlgContainer[strMapObjectId].mask.style.visibility = 'hidden';
         }
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgStartPanMap                                           |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id, horizontal %, vertical %, callback func.  |
| PURPOSE:     Starts map continuous panning                            |
\----------------------------------------------------------------------*/
function RfgStartPanMap(strMapObjectId, fHorizontal, fVertical, pCallback)
{
   var pMap = RfgGetMapById(strMapObjectId);
   if( pMap ) {
      try {
         pMap.StartContinuousPan(fHorizontal, fVertical);
      } catch ( e ) {
         //Do nothing
      }
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgStopPanMap                                            |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id, callback func.                            |
| PURPOSE:     Stops map continuous panning                             |
\----------------------------------------------------------------------*/
function RfgStopPanMap(strMapObjectId, pCallback)
{
   var pMap = RfgGetMapById(strMapObjectId);
   if( pMap ) {
      try {
         pMap.EndContinuousPan();
      } catch ( e ) {
         //Do nothing
      }
   }
}


/*----------------------------------------------------------------------\
| FUNCTION:    RfgShowMicroDashboard                                    |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to show micro dashboard on.     |
| PURPOSE:     Shows micro dashboard on given map.                      |
\----------------------------------------------------------------------*/
function RfgAddMapMicroDashboard(strMapObjectId)
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      if (pMap.GetMapType() != mapType.VE) {
         //This is an MWS map, we can't do the micro dashboard like this.
         return;
      }

      var strPanEastCmd = "RfgStartPanMap('"+strMapObjectId+"', 15, 0);";
      var strPanWestCmd = "RfgStartPanMap('"+strMapObjectId+"', -15, 0);";
      var strPanNorthCmd = "RfgStartPanMap('"+strMapObjectId+"', 0, -15);";
      var strPanSouthCmd = "RfgStartPanMap('"+strMapObjectId+"', 0, 15);";
      var strStopPanCmd = "RfgStopPanMap('"+strMapObjectId+"');";


      var strZoomInCmd = "RfgGetMapById('"+strMapObjectId+"').SetZoomLevel(RfgGetMapById('"+strMapObjectId+"').GetZoomLevel() + 1);";
      var strZoomOutCmd = "RfgGetMapById('"+strMapObjectId+"').SetZoomLevel(RfgGetMapById('"+strMapObjectId+"').GetZoomLevel() - 1);";
      var strModeRoadCmd = "RfgGetMapById('"+strMapObjectId+"').SetMapStyle('RoadVE');";
      var strModeHybridCmd = "RfgGetMapById('"+strMapObjectId+"').SetMapStyle('HybridVE');";

      var objControl = document.createElement('div');
      objControl.id = 'rfgmicrocontrol_' + strMapObjectId;
      objControl.style.top = '4px';
      objControl.style.left = '4px';
      objControl.style.width =  '51px';
      objControl.style.height =  '112px';
      objControl.style.opacity = .90;
      objControl.style.MozOpacity = .90;
      objControl.style.filter = 'alpha(opacity=90)';
      objControl.style.background = 'White';
      objControl.style.border = '2px solid #C0C0C0';
      objControl.innerHTML = '<table cellpadding=0 cellspacing=0 width=51 heigt=112>' +
                             '<tr><td align="center" valign="middle" bgcolor="#C8C8C8"><img src="'+g_strRfgClientSupportUrl+'/scheader.gif" width=49 height=10 border=0></td></tr>' +
                             '</table>' +
                             '<table cellpadding=2 cellspacing=0 width=51 heigt=71><tr><td align="center" valign="middle">' +
                             '<table cellpadding=0 cellspacing=0>' +
                             '<tr><td></td><td><img src="'+g_strRfgClientSupportUrl+'/scnorth.gif" onMouseDown="'+strPanNorthCmd+'" onMouseUp="'+strStopPanCmd+'" onMouseOut="'+strStopPanCmd+'" width=16 height=15 border=0></td><td></td></tr>' +
                             '<tr><td><img src="'+g_strRfgClientSupportUrl+'/scwest.gif" onMouseDown="'+strPanWestCmd+'" onMouseUp="'+strStopPanCmd+'" onMouseOut="'+strStopPanCmd+'" width=15 height=16 border=0></td><td><img src="'+g_strRfgClientSupportUrl+'/sccenter.gif" width=16 height=16 border=0></td><td><img src="'+g_strRfgClientSupportUrl+'/sceast.gif" onMouseDown="'+ strPanEastCmd +'" onMouseUp="'+ strStopPanCmd +'" onMouseOut="'+strStopPanCmd+'" width=15 height=16 border=0></td></tr>' +
                             '<tr><td></td><td><img src="'+g_strRfgClientSupportUrl+'/scsouth.gif" onMouseDown="'+strPanSouthCmd+'" onMouseUp="'+strStopPanCmd+'" onMouseOut="'+strStopPanCmd+'" width=16 height=15 border=0></td><td></td></tr>' +
                             '</table><table cellpadding=0 cellspacing=0>' +
                             '<tr><td colspan=2><img src="'+g_strRfgClientSupportUrl+'/spacer.gif" width=2 height=2 border=0></td></tr>' +
                             '<tr><td><a href="Javascript:'+strZoomOutCmd+'"><img src="'+g_strRfgClientSupportUrl+'/sczoomout.gif" width=18 height=16 border=0></a></td><td><img src="'+g_strRfgClientSupportUrl+'/spacer.gif" width=2 height=2 border=0></td><td><a href="Javascript:'+strZoomInCmd+'"><img src="'+g_strRfgClientSupportUrl+'/sczoomin.gif" width=18 height=16 border=0></a></td></tr>' +
                             '<tr><td colspan=2><img src="'+g_strRfgClientSupportUrl+'/spacer.gif" width=2 height=2 border=0></td></tr>' +
                             '</table><table cellpadding=0 cellspacing=0 width=47>' +
                             '<tr><td style="border-top: 1px solid #C0C0C0;" align="center"><a href="Javascript:'+strModeRoadCmd+'" style="font-family:arial,helvetica;font-size:9px;text-decoration:none;color:black;">Road</a></td></tr>' +
                             '<tr><td style="border-top: 1px solid #C0C0C0;" align="center"><a href="Javascript:'+strModeHybridCmd+'" style="font-family:arial,helvetica;font-size:9px;text-decoration:none;color:black;">Hybrid</a></td></tr>' +
                             '</td></tr></table>';

      pMap.AddControl(objControl, null);
   }
}

/*----------------------------------------------------------------------\ 
| FUNCTION:    RfgSetObjectPosition                                     |
| PARAMETERS:  X, Y position                                            |
| RETURNS:     N/A                                                      |
| PURPOSE:     Moves an object to specified location                    |
\----------------------------------------------------------------------*/
function RfgSetObjectPosition(obj, xPos, yPos)
{
   var pStyle = obj.style || obj;
   pStyle.left = xPos + 'px';
   pStyle.top = yPos + 'px';
}

/*----------------------------------------------------------------------\ 
| FUNCTION:    RfgGetMouseXPosition                                     |
| PARAMETERS:  mouse event                                              |
|              the listing div id for use with this function.           |
| RETURNS:     mouse position relative to document in pixels            |
| PURPOSE:     Gets the X position of the mouse cursor                  |
\----------------------------------------------------------------------*/
function RfgGetMouseXPosition(objMouseEvent, iDefault)
{
   var iPosition = iDefault;
   if( objMouseEvent ) {
      if ( objMouseEvent.pageX ) {
         iPosition = objMouseEvent.pageX;
      } else {
         if ( objMouseEvent.clientX ) {
            iPosition = objMouseEvent.clientX + (document.body.scrollLeft?document.body.scrollLeft:0);
         }
      }
   }

   return iPosition;
}

/*----------------------------------------------------------------------\ 
| FUNCTION:    RfgGetMouseYPosition                                     |
| PARAMETERS:  mouse event                                              |
|              the listing div id for use with this function.           |
| RETURNS:     mouse position relative to document in pixels            |
| PURPOSE:     Gets the Y position of the mouse cursor                  |
\----------------------------------------------------------------------*/
function RfgGetMouseYPosition(objMouseEvent, iDefault)
{
   var iPosition = iDefault;
   if( objMouseEvent ) {
      if ( objMouseEvent.pageY ) {
         iPosition = objMouseEvent.pageY;
      } else {
         if ( objMouseEvent.clientY ) {
            iPosition = objMouseEvent.clientY + (document.body.scrollTop?document.body.scrollTop:0);
         }
      }
   }

   return iPosition;
}

//---------------------------------------------------------------------||
// FUNCTION:    RfgFindWidth                                           ||
// PARAMETERS:  Object to query                                        ||
// RETURNS:     Width of object in pixels                              ||
// PURPOSE:     Determines the width of an object                      ||
//---------------------------------------------------------------------||
function RfgFindWidth(obj)
{
   var cursize = 0;
   if (document.getElementById || document.all) {
      cursize = obj.offsetWidth;
   } else if (document.layers)
      obj.width;

   return cursize;
}

//---------------------------------------------------------------------||
// FUNCTION:    RfgFindHeight                                          ||
// PARAMETERS:  Object to query                                        ||
// RETURNS:     Height of object in pixels                             ||
// PURPOSE:     Determines the height of an object                     ||
//---------------------------------------------------------------------||
function RfgFindHeight(obj)
{
   var cursize = 0;
   if (document.getElementById || document.all) {
      cursize = obj.offsetHeight;
   } else if (document.layers)
      obj.height;

   return cursize;
}

//---------------------------------------------------------------------||
// FUNCTION:    RfgFindPosX                                            ||
// PARAMETERS:  Object to query                                        ||
// RETURNS:     X position in pixels                                   ||
// PURPOSE:     Determines the X-axis position of an object            ||
//---------------------------------------------------------------------||
function RfgFindPosX(obj)
{
   var curleft = 0;
   if (document.getElementById || document.all) {
      while (obj.offsetParent) {
         curleft += obj.offsetLeft;
         obj = obj.offsetParent;
      }
   } else if (document.layers)
      curleft += obj.x;

   return curleft;
}

//---------------------------------------------------------------------||
// FUNCTION:    RfgFindPosY                                            ||
// PARAMETERS:  Object to query                                        ||
// RETURNS:     Y position in pixels                                   ||
// PURPOSE:     Determines the Y-axis position of an object            ||
//---------------------------------------------------------------------||
function RfgFindPosY(obj)
{
   var curtop = 0;
   if (document.getElementById || document.all) {
      if( !obj.offsetParent ){
         curtop += obj.offsetTop;
      }
      while (obj.offsetParent) {
         curtop += obj.offsetTop;
         obj = obj.offsetParent;
      }
   } else if (document.layers)
      curtop += obj.y;

   return curtop;
}

/*----------------------------------------------------------------------\ 
| FUNCTION:    RfgShowSearchTooltip                                     |
| PARAMETERS:  Pushpin X, Y, title, details -- we stuff the title with  |
|              the listing div id for use with this function.           |
| RETURNS:     N/A                                                      |
| PURPOSE:     Handle mouseover event on pushpin instead of internal    |
|              buggy VE method.                                         |
\----------------------------------------------------------------------*/
function RfgShowSearchTooltip( iWrongXPos, iWrongYPos, strEncodedTitle, strEncodedDetails )
{
   var strTitle = unescape(strEncodedTitle);
   var strDetails = unescape(strEncodedDetails);

   if ( g_bRfgSearchTipVisible ) {
      if( g_objRfgLastTooltip ) {
         if( g_objRfgLastTooltip.iXPos == iWrongXPos &&
             g_objRfgLastTooltip.iYPos == iWrongYPos &&
             g_objRfgLastTooltip.strTitle == strEncodedTitle &&
             g_objRfgLastTooltip.strDetails == strEncodedDetails ) {
            //This is the same as last time, do NOTHING
            return;
         }
      }
      RfgHideSearchToolTip();
   }

   g_bRfgSearchTipVisible = true;
   g_bRfgSearchTipCancelCloseRequest = true;
   g_bRfgSearchTipTimeoutActive = true;
   g_bRfgSearchTipNeedsRepositioned = false;

   if( g_objRfgLastTooltip ) {
      g_objRfgLastTooltip.iXPos = iWrongXPos;
      g_objRfgLastTooltip.iYPos = iWrongYPos;
      g_objRfgLastTooltip.strTitle = strEncodedTitle;
      g_objRfgLastTooltip.strDetails = strEncodedDetails;
   }

   var intX = RfgGetMouseXPosition(window.event, iWrongXPos);
   var intY = RfgGetMouseYPosition(window.event, iWrongYPos);

   var pSearchToolTip = document.getElementById( 'RfgMapHoverDiv' );
   if ( pSearchToolTip == null ) {
      pSearchToolTip = document.createElement("div");
      pSearchToolTip.id = 'RfgMapHoverDiv';
      pSearchToolTip.style.position= 'absolute';
      pSearchToolTip.style.display = 'none';
      pSearchToolTip.style.border = "1px solid windowframe";
      pSearchToolTip.style.background = '#FFFFEA';
      pSearchToolTip.style.zIndex = 99;
      document.body.appendChild(pSearchToolTip);
   }

   pSearchToolTip.innerHTML = '<table border=0><tr><td><b>' + strTitle + '</b><br>'+strDetails+'</td></tr></table>';

   RfgSetObjectPosition(pSearchToolTip, intX+5, intY - 20);
   pSearchToolTip.style.display = 'block';

   if( !window.event ) {
      //We did not get a proper location!
      if( document.addEventListener ) {
         document.addEventListener('mousemove', RfgMoveSearchToolTip, true );
      } else {
         document.attachEvent( 'onmousemove', RfgMoveSearchToolTip );
         document.attachEvent( 'onmouseover', RfgMoveSearchToolTip );
         document.attachEvent( 'onmouseout', RfgMoveSearchToolTip );
      }
   } else {
      setTimeout( RfgBeginShowSearchTip, 400 );  
   }
}


/*----------------------------------------------------------------------\ 
| FUNCTION:   RfgTrackSearchToolTip                                     |
| PARAMETERS:                                                           |
| RETURNS:                                                              |
| PURPOSE:    Tracks mouse movement for determining mouse position      |
\----------------------------------------------------------------------*/
function RfgTrackSearchToolTip( event )
{
   var pSearchToolTip = document.getElementById( 'RfgMapHoverDiv' );
   if ( pSearchToolTip != null ) {

      var tempX = RfgGetMouseXPosition(event, 0);
      var tempY = RfgGetMouseYPosition(event, 0);

      if( tempX < g_iRfgSearchTipPosLeft || tempX > g_iRfgSearchTipPosRight ){            
         if( ! g_bRfgSearchTipTimeoutActive ) {
            g_bRfgSearchTipCancelCloseRequest = false;
            setTimeout( RfgRequestHideSearchToolTip, 400 );
            g_bRfgSearchTipTimeoutActive = true;
         }            
         return;
      }

      if( tempY < g_iRfgSearchTipPosTop || tempY > g_iRfgSearchTipPosBottom ){            
         if( ! g_bRfgSearchTipTimeoutActive ) {
            g_bRfgSearchTipCancelCloseRequest = false;
            setTimeout( RfgRequestHideSearchToolTip, 400 );
            g_bRfgSearchTipTimeoutActive = true;
         }
         return;
      }

      g_bRfgSearchTipCancelCloseRequest = true;
   }
}


/*----------------------------------------------------------------------\ 
| FUNCTION:   RfgRequestHideSearchToolTip                               |
| PARAMETERS:                                                           |
| RETURNS:                                                              |
| PURPOSE:    Requests the interruptable menu hide timer be started     |
\----------------------------------------------------------------------*/
function RfgRequestHideSearchToolTip()
{  
   var pSearchToolTip = document.getElementById( 'RfgMapHoverDiv' );
   if ( pSearchToolTip != null ) {     
      g_bRfgSearchTipTimeoutActive = false;
      if( ! g_bRfgSearchTipCancelCloseRequest ) {
         RfgHideSearchToolTip();
      }
   }
}

/*----------------------------------------------------------------------\ 
| FUNCTION:   RfgHideSearchToolTip                                      |
| PARAMETERS:                                                           |
| RETURNS:                                                              |
| PURPOSE:    Hides the search tool tip                                 |
\----------------------------------------------------------------------*/
function RfgHideSearchToolTip()
{  
   var pSearchToolTip = document.getElementById( 'RfgMapHoverDiv' );
   if ( pSearchToolTip != null ) {
      if( document.removeEventListener ) {
         document.removeEventListener('mousemove', RfgTrackSearchToolTip, true );         
      } else {
         document.detachEvent('onmousemove', RfgTrackSearchToolTip );
         document.detachEvent('onmouseover', RfgTrackSearchToolTip );
         document.detachEvent('onmouseout', RfgTrackSearchToolTip );
      }
      pSearchToolTip.style.display = 'none';
      g_bRfgSearchTipVisible = false;
      g_bRfgSearchTipCurrentId = "";
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:   RfgMoveSearchToolTip                                      |
| PARAMETERS:                                                           |
| RETURNS:                                                              |
| PURPOSE:    Moves the search tip, once, to mouse location. Work around|
|             for VE that does not pass the mouse object, and instead   |
|             passes invalid X/Y position.                              |
\----------------------------------------------------------------------*/
function RfgMoveSearchToolTip( e ) 
{
   if( document.removeEventListener ) {
      document.removeEventListener('mousemove', RfgMoveSearchToolTip, true );
      document.removeEventListener('mousemove', RfgMoveSearchToolTip, true );
      document.removeEventListener('mousemove', RfgMoveSearchToolTip, true );
   } else {
      document.detachEvent('onmousemove', RfgMoveSearchToolTip );
   }

   if( !e ) e = window.event;
   var intX = RfgGetMouseXPosition(e, 0);
   var intY = RfgGetMouseYPosition(e, 0);
   var pSearchToolTip = document.getElementById( 'RfgMapHoverDiv' );
   if ( pSearchToolTip != null ) {
      RfgSetObjectPosition(pSearchToolTip, intX+5, intY - 20);
   }

   setTimeout( RfgBeginShowSearchTip, 400 );
}

/*----------------------------------------------------------------------\ 
| FUNCTION:   RfgBeginShowSearchTip                                     |
| PARAMETERS:                                                           |
| RETURNS:                                                              |
| PURPOSE:    Begins display of search tip, after block has been set    |
\----------------------------------------------------------------------*/
function RfgBeginShowSearchTip()
{
   // this function ensures enough time has passed for the block to render before reading the size
   var pSearchToolTip = document.getElementById( 'RfgMapHoverDiv' );
   if ( pSearchToolTip != null ) {
      g_iRfgSearchTipPosLeft = RfgFindPosX(pSearchToolTip);
      g_iRfgSearchTipPosRight = g_iRfgSearchTipPosLeft + RfgFindWidth(pSearchToolTip);
      g_iRfgSearchTipPosTop = RfgFindPosY(pSearchToolTip) - 30;
      g_iRfgSearchTipPosBottom = g_iRfgSearchTipPosTop + RfgFindHeight(pSearchToolTip) + 30;
   
      if( document.addEventListener ) {
         document.addEventListener('mousemove', RfgTrackSearchToolTip, true );
      } else {
         document.attachEvent( 'onmousemove', RfgTrackSearchToolTip );
      }
      setTimeout( RfgRequestHideSearchToolTip, 400 );
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgClearMap                                              |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to remove all objects from.     |
| PURPOSE:     Removes all polygons, pushpins, etc from a map           |
\----------------------------------------------------------------------*/
function RfgClearMap(strMapObjectId)
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      pMap.DeleteAllPushpins();
      pMap.DeleteAllPolygons();
      pMap.DeleteAllPolylines();
      pMap.Clear();
   }
}

/*----------------------------------------------------------------------\
| FUNCTION:    RfgStartPolygonDrawMode                                  |
| RETURNS:     N/A                                                      |
| PARAMETERS:  Map object id of the map to start polygon draw mode on,  |
|              ElementColor edgeColor, ElementColor fillColor, callback |
|              function.                                                |
| PURPOSE:     Starts polygon draw mode on an existing map.             |
\----------------------------------------------------------------------*/
function RfgStartPolygonDrawMode( strMapObjectId, edgeColor, fillColor, callback )
{
   var pMap = g_pRfgMapContainer[strMapObjectId];
   if( pMap ) {
      try{
         g_iRadiusSeq++;
         var radius = new Radius(('' + g_iRadiusSeq), new LatLong(0,0), 4.0, edgeColor, fillColor, 0.4);
         pMap.DrawPolygonOnTheFly( null, true, null, null, fillColor, new VELatLong(0,0), edgeColor, 4, "", "", "", callback);
      } catch( xE ){
         if( g_bShowErrorInformation ) {
            alert( xE.message );
         }
         RfgAjaxErrorLogger( 'rfg', exception.message );
      }
   }
}


/*----------------------------------------------------------------------\
| FUNCTION(S): Service Error Handlers                                   |
| PURPOSE:     Handle RFG Map Appliance service errors using AJAX       |
|              callback where appropriate.                              |
\----------------------------------------------------------------------*/
function RenderServiceException(exception)
{
   if( !RfgJsErrorHandler( 'render', exception ) ) {
      if( g_bShowErrorInformation ) {
         alert( exception.message + " (Render Service)" );
      }
   
      RfgAjaxErrorLogger( 'render', exception.message );
   }
}

function FindServiceException(exception)
{
   if( !RfgJsErrorHandler( 'find', exception ) ) {
      if( g_bShowErrorInformation ) {
         alert( exception.message + " (Find Service)" );
      }
   
      RfgAjaxErrorLogger( 'find', exception.message );
   }
}

function MapServiceException(exception)
{
   if( !RfgJsErrorHandler( 'map', exception ) ) {
      if( g_bShowErrorInformation ) {
         alert( exception.message + " (Map Service)" );
      }
   
      RfgAjaxErrorLogger( 'map', exception.message );
   }
}

function RouteServiceException(exception)
{
   if( !RfgJsErrorHandler( 'route', exception ) ) {
      if( g_bShowErrorInformation ) {
         alert( exception.message + " (Route Service)" );
      }
   
      RfgAjaxErrorLogger( 'route', exception.message );
   }
}

function CommonServiceException(exception)
{
   if( !RfgJsErrorHandler( 'common', exception ) ) {
      if( g_bShowErrorInformation ) {
         alert( exception.message + " (Common Service)" );
      }
   
      RfgAjaxErrorLogger( 'common', exception.message );
   }
}

function CommunicationServerException(exception)
{
   if( !RfgJsErrorHandler( 'communication', exception ) ) {
      if( g_bShowErrorInformation ) {
         alert( exception.message + " (Communication Server)" );
      }
      RfgAjaxErrorLogger( 'communication', exception.message );
   }
}

