    var ISDEBUG = false;
    
    var map; // the map object
    var geocoder; // geocoder object
    var debug; // the debug div    
    var rb_data_url;
    var rb_data_params = ""; // the GET params
    var rb_cbaction = ""; // the callback action
    var rb_w; var rb_h; var rb_lat; var rb_lon; var rb_zoom;
    var rb_bounds; var rb_l; var rb_b; var rb_r; var rb_t; // boundary
    var rb_zoomLevel;
    var rb_cMapType; // current map type  
    var rb_isInfoWOpen = false; //tracks if any info window is open, no callback while it is
    var request = GXmlHttp.create();
    var htScale = new Hashtable(); 
    
    var WMS_URL_HZD='http://www.hazardmaps.gov/ogc/wms?';
     
    function initMap( w, h, lat, lon, zoom ) {
	
		// setup hashtable for scale mapping
		htScale.put(19,10);
		htScale.put(18,20);
		htScale.put(17,30);
		htScale.put(16,40);
		htScale.put(15,50);
		htScale.put(14,60);
		htScale.put(13,70);
		htScale.put(12,80);
		htScale.put(11,90);
		htScale.put(10,100);
		htScale.put(9,110);
		htScale.put(8,120);
		htScale.put(7,130);
		htScale.put(6,140);
		htScale.put(5,150);
		htScale.put(4,160);
		htScale.put(3,170);
		htScale.put(2,180);
		htScale.put(1,190);
		htScale.put(0,200);
		
		
		
		if ( GBrowserIsCompatible() ) {
					
	
			
			map = new GMap2( xGetElementById("map") );		
			geocoder = new GClientGeocoder();

			
			if ( map != null) {
			       
/*
				var tileTopo= new GTileLayer(new GCopyrightCollection("2007 - RealBird.com"),1,17);
				tileTopo.myLayers='DRG';
				tileTopo.myFormat='image/jpeg';
				tileTopo.myBaseURL='http://terraserver.microsoft.com/ogcmap6.ashx?'
				tileTopo.getTileUrl = CustomGetTileUrl;

				var layer1=[tileTopo];

				var custommap1 = new GMapType(layer1, G_SATELLITE_MAP.getProjection(), "Topo", G_SATELLITE_MAP);
				map.addMapType(custommap1);
*/
				map.addMapType(G_PHYSICAL_MAP); 			       
				var mt = map.getMapTypes();
				
				// Overwrite the getMinimumResolution() and getMaximumResolution() methods
				for (var i=0; i<mt.length; i++) {
					mt[i].getMinimumResolution = function() {return 4;}
					//mt[i].getMaximumResolution = function() {return 0;}
				}
		
				this.map.addControl(new GLargeMapControl(), new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(10, 40)));
				this.map.addControl(new GMapTypeControl(), new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(10, 10)));				
				
				map.setCenter( new GLatLng(lat , lon), zoom );
							
				//map.setMapType(G_HYBRID_MAP);
				
				// Set div width, height
				resizeMap( w );						
				
				// Add event listeners
				
				GEvent.addListener(map, "moveend", function() {
						map_moveEnd();
					});
 
				GEvent.addListener(map, "click", function() {
						map_click();
					}); 
					
				GEvent.addListener(map, "maptypechanged", function() {
						map_maptypechanged();
					}); 
					
				GEvent.addListener(map, "dragstart", function() {
					map_dragstart();
				});

				rb_cbaction = "ps"; // pan and zoom
				commonCalls();
				loadData();			
				
			}
			else { //T
			}
		}	
		else { //T
		}	
	}
	
	// Event listeners
	function map_dragstart(){ 
		clearPOI();
	
	}
	
	function map_moveEnd(){ // this covers, pan, zoom change view
		
		rb_cbaction = "ps"; // pan and zoom
		commonCalls();
		loadData();
	}
	
	// map is clicked
	function map_click() {
		
		commonCalls();
	}	
	
	// marker is clicked
	function marker_click() {
		
		commonCalls();
	}	
	
	function map_maptypechanged() {
		setCookie( "GMap_Type", map.getCurrentMapType() );
	}

	// Called with every event including map init
	function commonCalls(){
		
		// get boundary 
		getBoundary( );	
		
		// get scale
		getScale( );
		
		// reset permalink
		setPLink( );
		
		// set hidden var of new lat, lon, scale
		var hd = xGetElementById('MyRealBird1__ctl0_hiddenLatLon');
		hd.value = this.map.getCenter()+'|'+ (20-rb_zoomLevel)*10;
		hd.value = hd.value.replace('/,/','|').replace("/(/","").replace("/)/","");
		
		// debug
		if (ISDEBUG) debugWrite (hd.value);	
		
	}
	
	function loadData(){
		// query for data only if no info window is shown	
		if (!rb_isInfoWOpen){
		
			// set data URL
			setDataUrl();
			
			// request data
			getData( );
		}
		
	}

	// Sets the params for the async data request URL
	function setDataUrl(){
		this.rb_data_url = this.rb_data_url_root;
		this.rb_data_url += setDataParams();
	}
	
	// Sets the params for the async data request URL - TODO
	function setDataParams(){
		rb_data_params = '';
		rb_data_params += 'g_id=' + rb_publicID;
		rb_data_params += '&g_a=' + rb_cbaction; 
		rb_data_params += '&g_s=' + (20-rb_zoomLevel)*10; 
		rb_data_params += '&g_e=' + rb_bounds; 
		rb_data_params += '&g_ms=' + rb_isMapSearchMode; 
		rb_data_params += '&g_sid=' + rb_subAccountID; 
		rb_data_params += '&g_acb=' + rb_useAutoCallbackLink; 
		//rb_data_params += '&g_address=' + rb_fullAddress;
		rb_data_params += '&g_acba=' + rb_autoCallbackByAddress;
		rb_data_params += '&g_rnd=' + ((new Date()).getTime() % 2147483648) + Math.random();
		rb_data_params += '&g_search=' + rb_search;
		rb_data_params += '&g_ex=' + rb_params;
		rb_data_params += '&g_msc=' + rb_msc;
		
		
		return rb_data_params;
	}
	
	
	// Refreshes session keep alive - T
	function keepSessionAlive( ){
	
	}
	
	function getData(){
	
	    
	    
	    
		showLoadingMsgGMaps2("Loading icons...&nbsp");
		
		
		clearPOI();
		msgPanel = xGetElementById('hotspotMessaging');
		if (msgPanel) msgPanel.innerHTML = "&nbsp;";
	    GDownloadUrl(rb_data_url, function(rText, rStatus) {
					
					if(rStatus == 200 ){
									
						
						
						var tmpPos;
						var markerAr = [];

						hideLoadingMsgGMaps2();
						
						eval(rText);	
						InitPOI();				
						if (rb_msg_Result && msgPanel) msgPanel.innerHTML = rb_msg_Result;
						else if (msgPanel) msgPanel.innerHTML = "&nbsp;";
					}
					else hideLoadingMsgGMaps2();				
				}
		 );
				

	}		
	
	// Function to show infoWindow
	function makeFunctionInstance(i, content, markerAr) { 

		return function() { 			
			if (content != '' && content != '<br>')
				markerAr[i].openInfoWindowHtml(content); 
				
		}; 
	} 
	
	// flag that infoWindow is open
	function infoWindowOpenEventHandler(){
		return function() { 			
			rb_isInfoWOpen = true;			
				
		}; 	
	}
	
	// flag that infoWindow is NOT open
	function infoWindowCloseEventHandler(){
		return function() { 			
			rb_isInfoWOpen = false;
			map_moveEnd(); // refresh data
				
		}; 	
	}	
	
	
	// Gets the current boundary
	
	function getBoundary( ){
		var latLngBounds = this.map.getBounds();
		this.rb_bounds = latLngBounds.getSouthWest() + latLngBounds.getNorthEast();
	}
	
	// Gets the current scale
	
	function getScale( ){
		this.rb_zoomLevel = this.map.getZoom();
	}	
	
	// Resizes the map Div 
	
	function resizeMap( w ){
		this.map.width = w;		
	}
	
	// Writes debug text
	
	function debugWrite ( text ){
		GLog.write(text);
	}
	
	function setPLink( )
	{

		if (rb_pLink)
		{
			
			// replace lat
			var re = new RegExp("&lat=[0-9]+\.[0-9]+&", "g");
			rb_pLink = rb_pLink.replace(re, "&lat=" + this.map.getCenter().y + "&");
			
			// replace lon
			re = new RegExp("&lon=-[0-9]+\.[0-9]+&", "g");
			rb_pLink = rb_pLink.replace(re, "&lon=" + this.map.getCenter().x + "&");
			
			// replace scale
			//rb_cScale
			re = new RegExp("&scale=[0-9]+&", "g");
			rb_pLink = rb_pLink.replace(re, "&scale=" + htScale.get(this.map.getZoom()) + "&");
			
		
		}
			
	}
	
	/**
	* Sets a Cookie with the given name and value.
	*
	* name       Name of the cookie
	* value      Value of the cookie
	* [expires]  Expiration date of the cookie (default: end of current session)
	* [path]     Path where the cookie is valid (default: path of calling document)
	* [domain]   Domain where the cookie is valid
	*              (default: domain of calling document)
	* [secure]   Boolean value indicating if the cookie transmission requires a
	*              secure transmission
	*/
	function setCookie(name, value, expires, path, domain, secure)
	{
		document.cookie= name + "=" + escape(value) +
			((expires) ? "; expires=" + expires.toGMTString() : "") +
			((path) ? "; path=" + path : "") +
			((domain) ? "; domain=" + domain : "") +
			((secure) ? "; secure" : "");
	}

	/**
	* Gets the value of the specified cookie.
	*
	* name  Name of the desired cookie.
	*
	* Returns a string containing value of specified cookie,
	*   or null if cookie does not exist.
	*/
	function getCookie(name)
	{
		var dc = document.cookie;
		var prefix = name + "=";
		var begin = dc.indexOf("; " + prefix);
		if (begin == -1)
		{
			begin = dc.indexOf(prefix);
			if (begin != 0) return null;
		}
		else
		{
			begin += 2;
		}
		var end = document.cookie.indexOf(";", begin);
		if (end == -1)
		{
			end = dc.length;
		}
		return unescape(dc.substring(begin + prefix.length, end));
	}
	
function hideLoadingMsgGMaps2()
{
	
	var msgLoading = xGetElementById('msgLoading');
	var cover = xGetElementById('cover');
	var container = xGetElementById('map');

		
	if (msgLoading && cover) { 
		cover.removeChild(msgLoading);	
	}
	if (cover && container) { 
		container.removeChild(cover);
		
	}
}

function showLoadingMsgGMaps2( t ){

	var container = xGetElementById('map');
	
	cover = document.createElement("div");
	cover.style.width = rb_mapWidth + "px";
	cover.style.height = rb_mapHeight + "px";
	cover.className = "cover";
	cover.id = "cover";
	container.appendChild(cover);
	
	msgLoading = document.createElement("div");
	msgLoading.style.position = "absolute";	
	msgLoading.style.left = rb_mapWidth/2 - 100;
	msgLoading.style.top = rb_mapHeight/2 - 20;
	msgLoading.style.width = "200px";
	msgLoading.innerHTML = "<br>" + t + "<img src=images/spinner.gif border=0 ><br><br>";
	msgLoading.id = "msgLoading";
	msgLoading.className = "divMapLoading";
	cover.appendChild(msgLoading);
	
	

}

function gotoAddress(address) {
  geocoder.getLatLng(
    address,
    function(point) {
      if (!point) {
        alert(address + " could not be found !");        
      } else {
        map.setCenter(point, map.getZoom());
        
      }
    }
  );
}

function Hashtable(){
    this.hashtable = new Array();
}

/* privileged functions */

Hashtable.prototype.clear = function(){
    this.hashtable = new Array();
}              
Hashtable.prototype.containsKey = function(key){
    var exists = false;
    for (var i in this.hashtable) {
        if (i == key && this.hashtable[i] != null) {
            exists = true;
            break;
        }       
    }
    return exists;
}
Hashtable.prototype.containsValue = function(value){
    var contains = false;
    if (value != null) {
        for (var i in this.hashtable) {
            if (this.hashtable[i] == value) {
                contains = true;
                break;
            }
        }
    }        
    return contains;
}
Hashtable.prototype.get = function(key){
    return this.hashtable[key];
}
Hashtable.prototype.isEmpty = function(){
    return (parseInt(this.size()) == 0) ? true : false;
}
Hashtable.prototype.keys = function(){
    var keys = new Array();
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null)
            keys.push(i);
    }
    return keys;
}
Hashtable.prototype.put = function(key, value){
    if (key == null || value == null) {
        throw "NullPointerException {" + key + "},{" + value + "}";
    }else{
        this.hashtable[key] = value;
    }
}
Hashtable.prototype.remove = function(key){
    var rtn = this.hashtable[key];
    this.hashtable[key] = null;
    return rtn;
}    
Hashtable.prototype.size = function(){
    var size = 0;
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null)
            size ++;
    }
    return size;
}
Hashtable.prototype.toString = function(){
    var result = "";
    for (var i in this.hashtable)
    {     
        if (this.hashtable[i] != null)
            result += "{" + i + "},{" + this.hashtable[i] + "}\n";  
    }
    return result;
}                                  
Hashtable.prototype.values = function(){
    var values = new Array();
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null)
            values.push(this.hashtable[i]);
    }
    return values;
}                                  
Hashtable.prototype.entrySet = function(){
    return this.hashtable;
}
