/**
	@fileOverview	
	<strong>TODO:</strong>
	<BR> - Find better way to differentiate between VE moving map and user to trigger radius search
	<BR> - Create function to display message overlay. Clears previous msgs, sets innerHTML and a timeout
	<HR>
	Created with <a href="http://code.google.com/p/jsdoc-toolkit/">jsdoc-toolkit</a>
*/


/******************************************
 * App settings:
 *   Use these to change the behavior of the map search
 */


var pxTillResultsRefresh = 100; /** this is how many pixels, squared, the user will have to move the map until the results are refreshed */

/** Main map object */
var map = null;

/** VEShapeLayer for properties */
var resultLayer = new VEShapeLayer();
/** store the mln -> VEShape reference pairs */
var ShapeIDs = new Array(); 

/** Active Widget object */
var awTable = null;
/** array of properties loaded in resultsAjaxSuccess */
var resultSet = null;

/** default zoom level used in loadDefaultMap() */
var defaultZoomLevel = 10;
/** default center point used in loadDefaultMap() */
var defaultCenterPoint = new VELatLong(45.00201,-93.21568);

/** used to determine cutoff for displaying amenities and searching for properties */
var amenityZoomLimit = 9;
/** min zoom out allowed */
var minZoomLevel = 6;
/** speed to pan */
var panDelta = 10;

/** array to store the amenity layers */
var amenityArr = new Array();

var oldMapView = null;
var currentMapView = null;
var oldCenter = null;

var mouseEventTriggered = false;

var selectedIcon = null;
var popupTimeout = null; // selected icons popup Timeout handle
var messageOverlayTimeout = null;

/** width of map = dimension of window - offset */
/** var widthOffset = 330; */
/** min width allowed for map */
/** var minWidth = 620; */
//var heightOffset = 390;
//var maxHeight = 502;
//var minHeight = 420;

/** default column to sort by (mls - descending /should/ inadvertently display newest on market houses first) */
var sortColumn = 0;
var sortDirection = "descending";

var propertyUpdater = null;
var resultsUpdater = null;

/** bound of webdigs map */
//var upperLeftBound = new Array(49.000000, -101.000000);
/** bound of webdigs map */
//var lowerRightBound = new Array(41.000000, -89.000000);
// regionBoundaries(northstar, fort myers)
var regionBoundaries = [[[43.5247, -98.305],[49.1386, -89.1541]], [[25.7207,-82.6392],[27.0396, -80.5518]]];

var outofboundsMessage = '<h6>Webdigs Has No Listings In This Area</h6><p>Or we had trouble understanding your search terms.</p><p>For the best search results, include a street addres, city, state zip, or MLS#.</p><br /><h6>Try Browsing One of Our Available Regions</h6><ul class="regionList"><li><a href="#" class="regionLink" onclick=\'centerAndRadius("45.00201","-93.21568", 10)\'>Minnesota Region</a></li><li><a href="#" class="regionLink" onclick=\'centerAndRadius("26.6408267161019","-81.8681841843361", 10)\'>Fort Myers, Florida Region</a></li></ul>';
var regionsMessage = '<br>Try browsing one of our coverage areas:<br/>&nbsp;&nbsp;<a href="#" onclick=\'centerAndRadius("45.00201","-93.21568", 10)\'>Minnesota Region</a><br>&nbsp;&nbsp;<a href="#" onclick=\'centerAndRadius("26.6408267161019","-81.8681841843361", 10)\'>Fort Myers, Florida Region</a><br>';
var multipleResultsMessage = '<h6>Webdigs Found More Than One Match For Your Location</h6><p>For the best search results, include a street addres, city, state zip, or MLS#.</p>';
var addressHelperMessage = '<p>For the best search results, include a street address, city, state, zip or MLS#.</p>';
var noResultsMessage = '<h4 class="staticSubHeader">We were unable to find any results, please try again</h4>';
var defaultMapViewMessage = 'Ready to get started on your search?<br />';
var inBoundsNoResultsMessage = 'There are no properties in this area that match your search criteria.';
var loadMessage = "<div id='loadMessage'>Searching all listings...<br /><img src='/images/newLayout/ajax-loader.gif' align='absmiddle' /></div>";

/**
*	@description Bootstraps the VEMap, AWgrid, and AJAX content
*/
function GetMap()
{
	if (map != null)
	{
		map.Dispose();
	}
	map = new VEMap('myMap');
	map.LoadMap(null, null, null, null, null, false, null);
	// MapResize();
	
//	map.HideDashboard(); // clear default control panel
	map.ClearInfoBoxStyles(); // clear default popup styling
	
	map.AddShapeLayer(resultLayer); // add the search result layer
	loadAmenityLayers(); // add the amenity layers. included in amenity.js
  
	
	
	loadGrid(); // load AW grid
	
	// Attach a series of VEmap events to distinguish
	// between a user driven map update and an AJAX driven map update
	// IF user driver, do a radiusSearch
	
	map.AttachEvent('onendpan',handleViewUpdate);
	map.AttachEvent('onendzoom',handleViewUpdate); 
	map.AttachEvent('onendzoom',handleEndZoom); // update the slider/overlay messages
	
	map.AttachEvent('ondoubleclick',handleViewUpdate);
	map.AttachEvent('onmousewheel',handleViewUpdate);
	map.AttachEvent("onerror", displayError);

	loadAjaxContent();  // Init AJAX update/request. Located in resultsSuccess
	
	oldMapView = map.GetMapView(); // set map view for later compare on map update
	oldCenter = map.GetCenter();
					var pixelOld = map.LatLongToPixel(oldCenter);
					
					
}
/**
*	@description Initialize the AWgrid.
*/
function loadGrid()
{
	/* To sort by street and not house number
	 * 	- set the second cell to the street instead of housenumber, ie: $resultList->getString(2)
	 * 	- set the cell format of indexes 1 & 2 to str, ie: awTable.setCellFormat([num, str, str, str, price, num, num, num, num, num]);
	 * AW 7/27/07
	*/
	// Create ActiveWidgets Grid javascript object
	awTable = new AW.UI.Grid;
	//awTable.setVirtualMode(false); 
	// Must match CSS definitions
	awTable.setId("webdigsGrid");
	awTable.setHeaderHeight(20);
	// Define data formats and formating
	var str = new AW.Formats.String;
	var num = new AW.Formats.Number;
	var price = new AW.Formats.Number;
	var tour = new AW.System.Format; //originally, I made this because I thought we'd have to define a sort function call for AW
	price.setTextFormat("$#,###.");
	resultColumns = ["MLN","HOUSENUMBER","ADDRESS","LOCATION","PRICE","BEDS","BATHS","SQFT", "OPEN HOUSE", "VIRTUAL TOUR", "VtUrl", "OHsort"];
	awTable.setHeaderText(resultColumns);
	awTable.setCellFormat([num, num, num, str, price, num, num, num, str, tour, str, num]);
	// choose columns to display
	awTable.setColumnIndices([2,3,4,5,6,7,8,9,10,11]);
	awTable.setHeaderTooltip("Click to sort by this column");
	awTable.setColumnCount(8); 
	//	set to select entire row, not a single cell
	awTable.setSelectionMode("single-row");
	
	//fix to get AW2.5 to work properly MG
	awTable.onRowClicked = function(event, index)
  {
    awTable.setSelectedRows([index]);
    awTable.setCurrentRow(index);
  }
	awTable.onRowSelectedChanged = function(selected,index){
		if( selected ) // this is triggered twice - on the unselect and select. we only need the selected row
		{
			mln = awTable.getCellValue(0,index);
			houseOnClick(mln);
		}
	}	
	// save user's sort order
	awTable.onHeaderClicked = function(e,col) {
		sortColumn = col;
		if( awTable.getSortDirection(sortColumn) == 'ascending' ) {
			sortDirection = 'descending';
 		} else {
			sortDirection = 'ascending';
		}
	}
	// update table div
	$('mapListResults').innerHTML = awTable;
}
/**
*	@description Updates mini-detail and selected icon. Reset previously selected icon.
*	see updateSummary().
*	see setSelectedIconAndPopup().
*	@param {Int} mln unique mln for property
*/
function houseOnClick(mln) 
{
	if( mln < 1 ) // prevent bad mln from passing through
	{
		return false;	
	}
	
	updateSummary(mln);
	// retrieve the VEShape object
	var shapeRef = ShapeIDs[mln];
	if( shapeRef == null ) // check if point has been plotted, ie has lat/long
	{
		return false;
	}
	var latlong = shapeRef.GetIconAnchor();	
	
	// show icon's popup box
	map.HideInfoBox();
	
	// (poorly) determine if popup will display on left or right side of icon
	var view = map.GetMapView();
	var rightEdgePix = map.LatLongToPixel(view.BottomRightLatLong);
	var iconPix = map.LatLongToPixel(latlong);
	if( (rightEdgePix.x-iconPix.x) < 230 )
	{
		xOffset = -20;
	}
	else
	{
		xOffset = 20;
	}
	map.ShowInfoBox(shapeRef,null,new VEPixel(xOffset,0)); // show the popup
	
	if( popupTimeout != null )
	{
		clearTimeout(popupTimeout); // stop succesive popups from closing each other
	}
	popupTimeout = window.setTimeout(function(){map.HideInfoBox();},100);
	
	if( selectedIcon != null && ShapeIDs[selectedIcon.mln] != null && selectedIcon.mln != mln )
	{
		setIconAndPopup(selectedIcon); // Reset previously selected icon
	}
	selectedIcon = shapeRef;
	setSelectedIconAndPopup(selectedIcon);
	// if birdseye view, center map on house per Greg's request. ACW 8.23.07
	if( map.GetMapStyle() == "o" )
	{
		map.SetCenter(latlong);	
	}
}
/**
*	@description Set a map point's custom icon and infobox/popup
* 	@param {VEShape} result
*/
function setIconAndPopup(result)
{
	if( result == null ){ return false; }
	// create a new icon
	var icon = new VECustomIconSpecification();
	
	icon.CustomHTML = '<img src="/images/icon_greenhouse.png" class="customHouseIcon" id="houseIcon_'+result.mln+'" onClick="updateGridSelection(\''+result.mln+'\');">';
	result.SetCustomIcon(icon);
	// set Title
	var title = '<div class="customInfoBox-title">'+result.price+'</div>';
	result.SetTitle(title);
	
	// set Description
	var des = '';
	des = '<div class="customInfoBox-address">';
	des += result.address;
	des += '</div>';
	des += '<div class="customInfoBox-bedbath">BEDS: <strong>';
	des += result.beds;
	des += '</strong>&nbsp;BATHS: <strong>';
	des += result.baths;
	des += '</strong></div>';
	// set link for more info
	des += '<div class="customInfoBox-moreinfo">';
	des += '<a href="/details/query/mls/'+result.mln+'" target="_blank">Click for more information</a>';
		des += '</div>';
	des += '<div class="customInfoBox-mlsBox"><img alt="mls house" src="/images/layout_pics/mlsLittleHouse.gif"></div>';
	result.SetDescription(des);
}
/**
*	@description Pulse and colorize the selected icon
* 	@param {VEShape} result
*/
function setSelectedIconAndPopup(result)
{
	if( result != null )
	{
		var icon = new VECustomIconSpecification();
		// give icon a unique id
		icon.CustomHTML = '<img src="/images/icon_redhouse.png" class="customSelectedHouseIcon" id="houseIcon_'+result.mln+'" onClick="houseOnClick(\''+result.mln+'\');">';
		result.SetCustomIcon(icon);
		if( $('houseIcon_'+result.mln) != null )
		{ 
			// oooohhh blinky!
			var selectedPulse = Effect.Pulsate('houseIcon_'+result.mln, {duration:4, pulses:4});
		}
	}
}
/**
*	@description Positions map to a default position/zoom
*/
function loadDefaultMap()
{
	map.SetCenterAndZoom(defaultCenterPoint, defaultZoomLevel);
	$('mapListResults').hide();
}
/**
*	@description Passes address string through VE's Find method.
*	Triggers mapRadiusSearch on callback.
*	see mapRadiusSearch().
*	@param {String} address free-form address
*/
function addressLookup(address)
{	
	  map.Find(null,address,null,null,0,20,null,null,false,false,addressCallback);	  
}
function addressCallback(a,b,c,d,e)
      {
       var inRegion = new Array();
       var inRegionCnt = 0;       
       
        if (c != null && c.length > 1)
         { 
            var results="<ul class='staticContentList' style='text-align:left;'>";
            for (x=0; x<c.length; x++)
            {  
               if(resultInSupportedRegion(c[x].LatLong.Latitude, c[x].LatLong.Longitude) && c[x].MatchConfidence<2){
                  results+="<li><a href='#' onclick='centerAndRadius("+c[x].LatLong.Latitude+","+c[x].LatLong.Longitude+")'>"+c[x].Name+"</a></li>";
                  inRegion[inRegionCnt] = new Array(c[x].LatLong.Latitude, c[x].LatLong.Longitude);                  
                  inRegionCnt++;          
               }
            }
            results+="</ol>";
            
            if(inRegionCnt>2){
            $('loadMessage').innerHTML = multipleResultsMessage+results;
            openMultipleResults();
            }else if(inRegionCnt==2){
                 var pointDistance = distanceSquared(inRegion[0][0], inRegion[0][1], inRegion[1][0], inRegion[1][0]);
                 if(pointDistance<25000){
                    centerAndRadius(inRegion[0][0], inRegion[0][1]); // if the distance between a 2 result search is insignificant simply goto the first one and ignore the second
                  }
               
            }else{
              if(inRegionCnt == 0){
                displayError(outofboundsMessage);
                $('myMap').show();
              }else{                 
                 centerAndRadius(inRegion[0][0], inRegion[0][1]);
              }              
            }           
         }else{           
           if(resultInSupportedRegion(c[0].LatLong.Latitude,c[0].LatLong.Longitude)){
             centerAndRadius(c[0].LatLong.Latitude,c[0].LatLong.Longitude); 
           }else{
            $('loadMessage').innerHTML= outofboundsMessage+regionsMessage+addressHelperMessage;
            openMultipleResults();
            
           }
           
         }
         
      }

 function distanceSquared(lat1, long1, lat2, long2) 
 {
   var latDiff = lat1-lat2;
   var longDiff = long1-long2;
   return (latDiff * latDiff) + (longDiff * longDiff); // the squared distance, in px, between the start and end points
 }
 
 function centerAndRadius(latitude, longitude, zoom)     
 { 
   zoom = typeof(zoom) != 'undefined' ? zoom : 14;   
   latLong = new VELatLong(latitude, longitude);
   map.SetCenterAndZoom(latLong, zoom);
   closeMultipleResults();
   mapRadiusSearch();
 }
 
 function openMultipleResults(){
   //$('mapLoading').hide();
   //$('mapLoading').show();
   //$('mapLoadingContent').hide();
   
   $('myMap').hide();
   $('overlayHolder').show();
   //$('multipleResultsContainer').show();
 }
 function closeMultipleResults(){
   //$('mapLoading').hide();  
   //$('mapLoadingContent').show();
   
   //$('multipleResultsContainer').hide();
   
   $('overlayHolder').hide();
   $('myMap').show();

   
 }
 
function displayError(onerror, timeout)
{
  if(onerror.error)
  {
    $('errorOverlayCopy').innerHTML=onerror.error;  
  }
  else
  {
    $('errorOverlayCopy').innerHTML=onerror;  
  }
  $('errorOverlay').show();
  if(timeout > 0)
  {
    messageOverlayTimeout = window.setTimeout(function(){Effect.Fade('errorOverlay', { duration: 1.0 })}, timeout );
  }
}
 
 
 function resultInSupportedRegion(latitude, longitude){
    for(var i = 0; i<regionBoundaries.length; i++){
        if( longitude > regionBoundaries[i][0][1] && longitude < regionBoundaries[i][1][1]){ 
          if( latitude > regionBoundaries[i][0][0] && latitude < regionBoundaries[i][1][0] )
          	{ 
          		return true;	
          	}    	  	
    	}
   }
   return false;
 }
 
      
/**
*	@description Updates mini-detail via AJAX.
*	see houseOnClick()
*	@param {Int} mln unique mln for property
*/
function updateSummary(mln)
{
	if( selectedIcon == null || selectedIcon.mln != mln )
	{
		propertyUpdater = new Ajax.Updater('micro_details', '/details/summary', {parameters:'mls='+mln, evalScripts: true});
	}
}
/**
*	@description Updates AWgrid, which in turn calls houseOnClick.
*	see houseOnClick().
*	see loadGrid().
*	@param {Int} mln unique mln for property
*/
function updateGridSelection(mln)
{	
	// 'select' the row
	awTable.setSelectedRows([]);
	awTable.clearSelectedModel();
	awTable.setSelectedRows([mlnToIndex[mln]]);
	awTable.setCurrentRow(mlnToIndex[mln]);
	
	awTable.refresh();
}
/**
*	@description Clears AWgrid, leaving the headers
*
*/
function clearGrid()
{
    awTable.clearCellModel();
    awTable.clearRowModel();
    awTable.clearScrollModel();
    awTable.clearSelectionModel();
    awTable.refresh();
} 
/**
*	@description Toggle an amenity layer on/off
*	see showAmenity()
*	@param {VEShapeLayer} layer shape layer containing amenity
*/
function toggleAmenity(layer)
{
	if( layer.onState === true )
	{
		layer.onState = false;
		layer.DeleteAllShapes();
		$(layer.id).src = layer.iconOff;
	}
	else
	{
		layer.onState = true;
		showAmenity(layer);
	}
}
/**
*	@description Clears all amenities from map
*/
function removeAmenities() {
	for( var i = 0; i < amenityArr.length; i++ )
	{
		amenityArr[i].onState = false;
		amenityArr[i].DeleteAllShapes();
		$(amenityArr[i].id).src = amenityArr[i].iconOff;
	}
}
/**
*	@description Show an amenity
*	see toggleAmenity().
*	NOTE: VE's Find method is not re-entrant.
*	Can cause problems if user hastily selects amenities.
* 	@param {VEShapeLayer} layer shape layer containing amenity
*/
function showAmenity(layer)
{
	// update the button icon
	$(layer.id).src = layer.icon;
	layer.DeleteAllShapes();
	/* 
	*  Find() is not re-entrant. 
	*  If you make multiple subsequent Find calls, the callback that is passed to the second Find call overwrites the first callback
	*/
	map.Find(layer.qry, null, null, layer, 0, 20, false, true, false, false, 
				function(a,b,c,d) {
					if( b != null )
					{
						for( var i = 0; i < b.length; i++ )
						{
							shape = new VEShape(VEShapeType.Pushpin,b[i].LatLong);
							shape.SetCustomIcon(a.icon); 
							shape.SetTitle(b[i].Name + '<BR />' + b[i].Phone);
							shape.SetDescription(b[i].Description);
							a.AddShape(shape);
						}
					}
				}
  );
}
/**
* 	@description Refresh all amenities recursively.
*	NOTE: Find() is not re-entrant. 
*	If you make multiple subsequent Find calls, the callback that is passed to the second Find call overwrites the first callback.
* 	@param {Int} z index to the amenityArr array
*/
function refreshAmenities(z)
{
	if( z < amenityArr.length )
	{
		amenityArr[z].DeleteAllShapes();
		if( amenityArr[z].onState === true )
		{
				map.Find(amenityArr[z].qry, null, null, amenityArr[z], 0, 20, false, true, false, false, 
							function(a,b,c,d) {
								if( b != null )
								{
									for( var i = 0; i < b.length; i++ ) // iterate through returned results
									{
										shape = new VEShape(VEShapeType.Pushpin,b[i].LatLong);
										shape.SetCustomIcon(a.icon); 
										shape.SetTitle(b[i].Name + '<BR />' + b[i].Phone);
										shape.SetDescription(b[i].Description);
										a.AddShape(shape);
									}
								}
								refreshAmenities(++z);
							}
			  );
		}
		else 
		{
			refreshAmenities(++z);
		}		
	}
}


/**
*	@description Triggered by a map zoom/move. FF and IE handle these events differently.
*	Certain mouse properties are passed in FF and not IE.
*	see getMap().
*	see mapRadiusSearch().
*	see refreshAmenities().
*	see http://msdn2.microsoft.com/en-us/library/bb429609.aspx.
*	@param {MapEvent object} e
*/
function handleViewUpdate(e)
{
	// are we zoomed in far enough and not on birdseye
	if( e.mapStyle != "o" && e.zoomLevel >= amenityZoomLimit )
	{
		switch(e.eventName)
		{
			case 'ondoubleclick':
				var pixelOld = map.LatLongToPixel(oldCenter);
				mouseEventTriggered = true;
				break;
			case 'onmousewheel':
			    var pixelOld = map.LatLongToPixel(oldCenter);
					
				mouseEventTriggered = true;
				break;
			case 'onendpan':
				var pixelOld = map.LatLongToPixel(oldCenter);
				//MG 2008-10-20 Removed checks for mousebuttons - onendpan is a map event, not a mouse event. 
				// Not sure why, but the event must have previously had those data members historically, because
				// this broke functionality in VE 6.2
        if( mouseEventTriggered===true )
        {
					mapRadiusSearch();
					//refreshAmenities(0); // re-draw the amenities	
				}
				mouseEventTriggered = false;
				break;
			case 'onendzoom':
				var pixelOld = map.LatLongToPixel(oldCenter);
					
				if( mouseEventTriggered===true )
				{
					mapRadiusSearch();
					//refreshAmenities(0); // re-draw the amenities	
				}
				oldCenter = map.GetCenter();
				var pixelOld = map.LatLongToPixel(oldCenter);
					
				//mouseEventTriggered = false;
				break;
			default:
				var pixelOld = map.LatLongToPixel(oldCenter);
					
				break;
		}
	  //clear error message on any user caused event
		if(mouseEventTriggered){$('errorOverlay').hide();}
		
		mouseEventTriggered = true;
	}
}
/**
* 	@description Updates UI elements: Slider.
*	Restricts zooming out too far.
* 	see onEndZoom in GetMap
*/
function handleEndZoom(e)
{ 
	var z = e.zoomLevel;
	// if zoomed too far out or if zoomstyle is anything but Birdseye
	if( z < amenityZoomLimit && map.GetMapStyle() != "o" )
	{
		$('mapListResults').hide();
		$('localSearchLinks').hide();
		map.DeleteAllShapes();
		removeAmenities();
	}
	
	mouseEventTriggered = true;
}
/**
*	@description Search by map coordinates via AJAX. Display message if map is 'out-of-bounds'.
*	see handleViewUpdate()
*/
function mapRadiusSearch()
{	 
	var LLRectangle = map.GetMapView();
	
	var center = map.GetCenter();
	
	
	var pixelOld = map.LatLongToPixel(oldCenter);
	var pixelNew = map.LatLongToPixel(center);
	var latDiff = pixelOld.x - pixelNew.x;
	var longDiff = pixelOld.y - pixelNew.y;
	
	var distanceSquared = (latDiff * latDiff) + (longDiff * longDiff); // the squared distance, in px, between the start and end points
		
	oldMapView = map.GetMapView();
	oldCenter = map.GetCenter();
	
	if (distanceSquared > pxTillResultsRefresh || distanceSquared==0) {
    $('enhancedSearch').value = '';
    var parametersStr = Form.serialize($('enhancedSearchForm'));
    parametersStr += '&radius=true';
		parametersStr += '&left=' + LLRectangle.TopLeftLatLong.Longitude;
		parametersStr += '&top=' + LLRectangle.TopLeftLatLong.Latitude;
		parametersStr += '&right=' + LLRectangle.BottomRightLatLong.Longitude
		parametersStr += '&bottom=' + LLRectangle.BottomRightLatLong.Latitude;
		
    displayOverlay(loadMessage);
		
		searchUpdater = new Ajax.Updater('resultSetJS', '/search/results', {
			parameters: parametersStr,
			evalScripts: true
		});
		$('enhancedSearch').value = 'Current Map';
	}
}
/**
* 	@description Resize the map to fit screen. Triggered on body's onresize event.
* 	see http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=693587&SiteID=1
*/
function MapResize()
{
	//Find Browser Window Size
	// var myWidth = 0, myHeight = 0;
	// if( typeof( window.innerWidth ) == 'number' )
	// {
		//Non-IE
	//	myWidth = window.innerWidth;
	//	myHeight = window.innerHeight;
	// }
	// else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
	// {
		//IE 6+ in 'standards compliant mode'
	//	myWidth = document.documentElement.clientWidth;
	//	myHeight = document.documentElement.clientHeight;
	// }
	// else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) )
	// {
		//IE 4 compatible
	//	myWidth = document.body.clientWidth;
	//	myHeight = document.body.clientHeight;
	// }
	// resize offsets
	// myWidth -= widthOffset;
    //	myHeight -= heightOffset;
	//if( myWidth < minWidth )
	//{
	//	myWidth = minWidth;
	//}
	//if( myHeight < minHeight ) 
	//{
	//	myHeight = minHeight;
	//}
	if (!(($('myMap').getStyle('border')).match('3px'))){
	    var myWidth = 740;
		var myHeight = 380;
		map.Resize(myWidth, myHeight);
		$('myMap').setStyle({
				border: '3px #e2e2cb solid'
			});
	}
}
/**
*	@description Display message overlayed on the map
*	@param {String} message message to be displayed
*	@param {Int} [timeout] time to display message. default is forever
*/
function displayOverlay(message, timeout)
{
	if( message === null )
	{
		return false;	
	}
	$('myMap').hide();
	$('mlsInfo').hide();
	$('mapListResults').hide();
	$('overlayHolder').innerHTML = message;
	$('overlayHolder').show();
	if( messageOverlayTimeout !== null )
	{
		// clear timeout id
		window.clearTimeout(messageOverlayTimeout);	
	}
	if( timeout > 0 )
	{
		messageOverlayTimeout = window.setTimeout(function(){clearOverlay(true)}, timeout );
	}
						  
}
/**
*	@description Hide the message overlay div
*	@param [boolean] fade fade the message out or instantly hide it. default is false
*/
function clearOverlay(fade)
{
	if( messageOverlayTimeout !== null )
	{
		// clear timeout id to prevent 
		window.clearTimeout(messageOverlayTimeout);	
	}
	if( fade === true )
	{
		Effect.Fade('overlayHolder', { duration: 1.0 });	
	}
	else
	{
		$('mapListResults').show();
		$('myMap').show();
		$('mlsInfo').show();
		$('overlayHolder').hide();
		$('overlayHolder').hide();

	}
	
}
/**
*	@description Update the number of results message
*	@param {Int} num number of results
*/
function updateNumResults(num)
{
	if( num === null || num < 1 )
	{
		var content = 'No Results This Search';	
	}
	else if( num == 1 )
	{
		var content = '1 Result This Search';	
	}
	else
	{
		var content = '<span style="color:#58585a;">Your Search Results:</span> '+'<span style="font-size: 18px;">'+num+'</span>';	
	}
	$('numResults').innerHTML = content;
	$('numResults').show();
}

/**
* 	@description Determine if icon is visible within bounds.
	NOTE: Not used
*	@param {VEShape} shape icon
*	@param {VELatLongRectangle} box bounds	
*	@return boolean true if icon visible, false otherwise
*/
function shapeIsVisible(shape, box) {
	var latlong = shape.GetIconAnchor();
	if( box.TopLeftLatLong.Longitude > latlong.Longitude || box.BottomRightLatLong.Longitude < latlong.Longitude )
	{
		return false;	
	}
	if( box.TopLeftLatLong.Latitude < latlong.Latitude || box.BottomRightLatLong.Latitude > latlong.Latitude )
	{
		return false;	
	}
	return true;
}