
//################################################################
//================================================================
//  Map
//================================================================
//################################################################

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  MapClicked
//  The map should only be clicked once for Omniture reporting.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var MapClicked = false;

	
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  map
//  Variable to hold map object. Set to null here and redefined 
//  on page load.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var map = null;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  InLocationSearch()
//  Determines if we're doing an "In Location Search" or not.
//  Checks radio button in form above map.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//function InLocationSearch()
//{
    //if (gE("tmf_location") != null)
    //{
    //    if (gE("tmf_location").checked)
    //    {
    //        return true;
    //    }
    //}
    //return false;
    
//}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  New logic for SCRIPPS
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  DoReloadResults = true if the checkbox is checked.
//  All other logic follows suit.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function DoReloadResults()
{
    if (gE("mlo"))
    {
        return gE("mlo").checked;
    } 
    else 
    {
        return true;
    }
}  
    
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  PageLoader()
//  Called on Page Load. Captures mouse position for Region Marker
//  rollover bubble and loads map.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function PageLoader()
{
    CaptureMouseXY();
	LoadMap();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// A TextualZoomControl is a GControl that displays textual "Zoom In"
// and "Zoom Out" buttons (as opposed to the iconic buttons used in
// Google Maps).
// We define the function first
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
try
{
    function TextualZoomControl() {}

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // To "subclass" the GControl, we set the prototype object to
    // an instance of the GControl object
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    TextualZoomControl.prototype = new GControl();
    
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Creates a one DIV for each of the buttons and places them in a container
    // DIV which is returned as our control element. We add the control to
    // to the map container and return the element for the map class to
    // position properly.
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    TextualZoomControl.prototype.initialize = function(map) {
        var container = document.createElement("div");
        container.className = "map_zoom clearfix";
        container.id = "ZoomContainer";
        var zoomInDiv = document.createElement("div");
        zoomInDiv.className = "zoom_in";
        //this.setButtonStyle(zoomInDiv);  
        container.appendChild(zoomInDiv);
        zoomInDiv.innerHTML = "<img src='" + WebRoot + "images/zoom_bar/zoom_in.gif' />";
        //zoomInDiv.appendChild(document.createTextNode("+"));  
        GEvent.addDomListener(zoomInDiv, "click", function() {
            DoZoomIn();
        });

        var zoomLevel = document.createElement("div");
        zoomLevel.className = "level";
        //this.setLevelStyle(zoomLevel);
        container.appendChild(zoomLevel);
        if (map.getZoom() <= 18) {
            zoomLevel.innerHTML = "<img src='" + WebRoot + "images/zoom_bar/" + map.getZoom() + ".gif' usemap='#ZTracker' />";
        }
        else {
            zoomLevel.innerHTML = "<img src='" + WebRoot + "images/zoom_bar/18.gif' usemap='#ZTracker' />";
        }
        GEvent.addDomListener(map, "zoomend", function() {
            if (map.getZoom() <= 18) {
                zoomLevel.innerHTML = "<img src='" + WebRoot + "images/zoom_bar/" + map.getZoom() + ".gif' usemap='#ZTracker' />";
            }
            else {
                zoomLevel.innerHTML = "<img src='" + WebRoot + "images/zoom_bar/18.gif' usemap='#ZTracker' />";
            }
        });

        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        //  HoverZoom() is Obsolete.
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~        
        //        GEvent.addDomListener(container, "mouseover", function() 
        //        {   
        //            HoverZoom('on');
        //        });
        //        GEvent.addDomListener(container, "mouseout", function() 
        //        {   
        //            HoverZoom('off');
        //        });
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        var zoomOutDiv = document.createElement("div");
        zoomOutDiv.className = "zoom_out";
        //this.setButtonStyle(zoomOutDiv);  
        container.appendChild(zoomOutDiv);
        zoomOutDiv.innerHTML = "<img src='" + WebRoot + "images/zoom_bar/zoom_out.gif' />";
        //zoomOutDiv.appendChild(document.createTextNode("-"));  
        GEvent.addDomListener(zoomOutDiv, "click", function() {
            DoZoomOut();
        });

        map.getContainer().appendChild(container);
        return container;
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // By default, the control will appear in the top left corner of the
    // map with 7 pixels of padding.
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    TextualZoomControl.prototype.getDefaultPosition = function() 
    {  
        return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(8, 8));
    };

}
// this is sometimes placed on a page with no call to Google....
catch(ex){} 

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  DoZoomOut()
//  Function controls Zoom Out button on Zoom control
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function DoZoomOut()
{
    //if ((map.getZoom()-1) > 3)
    //{
        //MCO.AddPan(map.getCenter(), map.getZoom());
        map.zoomOut();
        RequeryOnBounds(false,true);
    //}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  DoZoomIn()
//  Function controls Zoom In button on Zoom control
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function DoZoomIn()
{
    if ((map.getZoom()+1) <= 16)
    {
        //MCO.AddPan(map.getCenter(), map.getZoom());
        map.zoomIn();
        RequeryOnBounds(false,true);
    }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  DoZoom(num)
//  Function controls Zoom Level Links on Zoom control
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function DoZoom(num)
{
    if (num <= 16)
    {
        //MCO.AddPan(map.getCenter(), map.getZoom());
        map.setZoom(num);
        RequeryOnBounds(false,true);
    }
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  LoadMap()
//  Main function called to initialize the map
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function LoadMap()
{
    map = new GMap2(gE("map"));
    
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  OVControl
    //  The small version of the map in the lower right corner
    //  After added to the map, you can get a reference to the 
    //  Overview map control using this syntax:
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  var OVMap = OVControl.getOverviewMap();
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //var OVControl = new GOverviewMapControl();
    
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  Add controls to the map
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Overview Control
	//map.addControl(OVControl);
    // Map Type ie. Map, Satellite, Hybrid
	map.addControl(new GMapTypeControl());
	// Custom Zoom Control
	map.addControl(new TextualZoomControl());   
	
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  DefaultLatitude, DefaultLongitude, DefaultZoom
    //  are defined on the loading page before this script is called
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	map.setCenter(new GLatLng(DefaultLatitude, DefaultLongitude), DefaultZoom);
	
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  Add map event listeners
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	GEvent.addListener(map, "dragend", function()
	{
	    //ZoomCache.factor = 0;
	    crosshair();
	    //map.savePosition();
	    //````````````````````````````````````````````````````````````````
	    // don't requery if the info window is open.
	    //````````````````````````````````````````````````````````````````
	    if (map.getInfoWindow().isHidden()) 
	    {
	        // allows crosshairs to exit before pause caused by query
	        window.setTimeout(function(){ 
                RequeryOnBounds(false,true);
            },100);
		}
	});
	
	
	GEvent.addListener(map, "dragstart", function()
	{
	    crosshair();
	});		
    
    
    GEvent.addListener(map, "mousedown", function()
	{
	    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	    //  OmEvent = calls Omniture script for reporting events
	    //  Should only report first click on map for any full page load
	    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		if (MapClicked == false)
		{
		    OmEvent(this, 6, 'map_clicked');
		    MapClicked = true;
		}
	});
	
    GEvent.addListener(map, "infowindowopen", function()
	{
		map.savePosition();
	});
	GEvent.addListener(map, "infowindowclose", function()
	{
		map.returnToSavedPosition();
	});
	       
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  FirstLoad()
    //  The FirstLoad function is defined on the front end page
    //  before this script is called. The script in the function comes
    //  from the XML document, from C#. It plots the Listings and 
    //  Regions on the map for itinial page load.
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    if(PageCache.XML != null)
    {
        var ListingsJS = GetSingleNodeContent(PageCache.XML, '/results/listings/mappedlistingsjs');
        var RegionsJS = GetSingleNodeContent(PageCache.XML, "/results/regions");
        NextLoad(ListingsJS, RegionsJS, true);
    }
    else
    {
	    FirstLoad();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  NextLoad(ListingsJS, RegionsJS, Recenter)
//  Manages clearing the map and redrawing overlays from the data
//  aquired through Sarissa
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function NextLoad(ListingsJS, RegionsJS, Recenter)
{
    OverlayCache.RemoveCacheTypes(["GLatLng", "Listing", "Region", "Neighborhood"]); 
    if(map)
    {
        map.clearOverlays(); 
    } 
        eval(RegionsJS);
        eval(ListingsJS);
    if(map)
    {
        if (PageCache.MapBestFit != "neighborhoods")
	    {
            RenderMapOptions(Recenter);
        }   
    }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  PostPointLoading(Recenter)
//  Called after all points have been drawn on the map
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function PostPointLoading(Recenter)
{
	//ShowLoading(null,false);
	if (Recenter==true)
	{
	    MapBestFit();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  MapBestFit()
//  Recenters and zooms map based on current OverlayCache.GetType("GLatLng")
//  array only. Does not take Regions Markers into account.
//  Only called once per data refresh.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function MapBestFit()
{
    var GLatLngs = OverlayCache.GetType("GLatLng");
    
    //if (CacheListingsGLatLng.length==0){return;}
    if (GLatLngs.length==0){return;}
    
    var Bounds = new GLatLngBounds();
    
    for (var i=0; i<GLatLngs.length; i++)
    {
        Bounds.extend(GLatLngs[i]);
    }
    var Zoom = map.getBoundsZoomLevel(Bounds);
    var Center = Bounds.getCenter();
        map.setCenter(Center, Zoom);

        // reset
        //CacheListingsGLatLng = new Array();
        // reset
        OverlayCache.RemoveCacheType("GLatLng"); 
}

function MapBestFitBounds(Bounds)
{   
    if(map)
    {
        map.checkResize(); 
        var Zoom = map.getBoundsZoomLevel(Bounds);
        var Center = Bounds.getCenter(); 
        map.setCenter(Center, Zoom);
    }
}

function RenderMapOptions(Recenter)
{ 
    if (Recenter)
    {
        var MapBounds;
        switch(PageCache.MapBestFit)
        {
            case "mapbounds":
                    MapBounds = GetBoundsFromQueryString(PageCache.QueryString);
                    break;
            case "regions":
                    MapBounds = OverlayCache.GetMapBoundsByType("Region");
                    break;
            case "neighborhoods":
                    MapBounds = OverlayCache.GetMapBoundsByType("PrimeNeighborhood");
                    break;
            case "listings":
                    MapBounds = OverlayCache.GetMapBoundsByType("Listing");
                    break;
            default:
                    MapBounds = OverlayCache.GetMapBoundsByType("Listing");
                    break;
        }
        MapBestFitBounds(MapBounds);
    }
    var RenderMapTypes = ["Region", "PrimeNeighborhood"];
    if (PageCache.ShowListingsOnMap)
    {
        RenderMapTypes.push("Listing");
    }
    OverlayCache.RenderOverlayTypes(RenderMapTypes);
    LdImgs.Init("listingimg", "images/no_photo2.gif");
}

function GetBoundsFromQueryString(QueryString)
{
    var LatMin, LatMax, LngMin, LngMax;
    var Bounds = new GLatLngBounds();
    var UGen = new UrlGen(QueryString);
    var eles = unescape(UGen.GetParam("Nf")).split("||");
    for (var x=0;x<eles.length;x++)
    {
        var Filter = eles[x].split("|");
        if (Filter[0].toLowerCase() == "Latitude")
        {
            var FilterVals = Filter[1].split(" ");
                LatMin = parseFloat(FilterVals[1]);
                LatMax = parseFloat(FilterVals[2]);
                
        }
        else if (Filter[0].toLowerCase() == "Longitude")
        {
            var FilterVals = Filter[1].split(" ");
                LngMin = parseFloat(FilterVals[1]);
                LngMax = parseFloat(FilterVals[2]);
        }
    }
    Bounds.Extend(new GLatLng(LatMin, LngMin));
    Bounds.Extend(new GLatLng(LatMax, LngMax));
    return Bounds;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  gEOpenNearCities
//  gECloseNearCities
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  Controls the opening and closing of the "nearbyCities" and
//  "NearbyNeighborhoods" flyout menus
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function gEOpenNearCities(objId, objId2, display)
{
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  Problem: we cannot get values from the div related to 
    //  position unless the object style.display = "block"
    //  Solution: we set visibility = "hidden" so we can perform 
    //  the move "in the dark", then make it visible later.
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    gE(objId).style.visibility = "hidden"; 
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    gE(objId).style.display = display;
    gE(objId2).style.background = '#E9F3F3';
    var ObjMenuOffset   = new RecurseOffset(objId);
    var ObjAnchorOffset = new RecurseOffset(objId2);
    var WinBounds = new GetWindowBunds();
    var MenuBottom = ObjMenuOffset.offsetTop + ObjMenuOffset.offsetHeight;
    var ScrollBottom = WinBounds.VisibleTop + WinBounds.VisibleHeight;

    // perform the move only if we need to
    if (MenuBottom > ScrollBottom) 
    {
        var buffer = 10;
        var MoveTo = ((MenuBottom - ScrollBottom) + buffer) * -1;
        /*
        // debug info
        //alert(String.format("MenuBottom:{0}\n\
ScrollBottom:{1}\n\
MoveTo:{2}",
        MenuBottom,
        ScrollBottom,
        MoveTo));
        */           
    //    gE(objId).style.top = MoveTo + "px";

    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  Hide form select elements in collision with the menu
    //  see Global.js
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    SweepSelects(objId);
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  Finally, Restore Visibility
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    gE(objId).style.visibility = "visible";
    gE(objId2).style.fontWeight = 'bold';
  
}
function gECloseNearCities(objId, objId2, display)
{
    // ensure menu object is reset to default relative position
    gE(objId).style.top = "0"; 
    gE(objId).style.display = display;
    gE(objId2).style.background = 'none';
    gE(objId2).style.fontWeight = 'normal';
    // bring back selects hidden in Opener
    RestoreSelects(); 
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  gEShowNearestCities
//  gEHideNearestCities
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  Controls the showing and hiding of the "moreNearestCities" li elements
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function gEShowNearestCities(){
    jQuery('.moreNearestCities').show();
    jQuery('#showMoreNearestCities').hide();
    jQuery('#hideMoreNearestCities').show();
}
function gEHideNearestCities(){
    jQuery('.moreNearestCities').hide();
    jQuery('#showMoreNearestCities').show();
    jQuery('#hideMoreNearestCities').hide();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  gEShowMoreNeighborhoods
//  gECloseMoreNeighborhoods
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  Controls the showing and hiding of the "moreNeighborhoods" li elements
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function gEShowMoreNeighborhoods(){
    jQuery('.moreNeighborhoods').show();
    jQuery('#showMoreNeighborhoods').hide();
    jQuery('#hideMoreNeighborhoods').show();
}
function gEHideMoreNeighborhoods(){
    jQuery('.moreNeighborhoods').hide();
    jQuery('#showMoreNeighborhoods').show();
    jQuery('#hideMoreNeighborhoods').hide();
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  Controls the "crosshair" that appears in the center of the 
//  map when dragging
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function crosshair()
{
    var C = new RecurseOffset(gE("crosshair"));
    var M = new RecurseOffset(gE("map"));
    var D = gE("crosshair").style.display;
    switch(D)
    {
        case "block":
            gE("crosshair").style.left = "-100px"
            gE("crosshair").style.display = "none";
            break;
        case "none":
            gE("crosshair").style.left = ( parseInt((M.offsetWidth/2) + M.offsetLeft,10) -4 ) + "px";
            gE("crosshair").style.top  = ( parseInt((M.offsetHeight/2) + M.offsetTop,10) -3 ) + "px";
            gE("crosshair").style.display = "block";
            break;
    }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  getN
//  Calls polygon data through Ajax
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  TODO: Add encrypted request code
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function getN(strRID, fillColor, borderColor, boolPrimaryNeighborhood)
{
    var NiD = "Neighborhood";
    if (boolPrimaryNeighborhood == true)
    {
        NiD = "Prime" + NiD;
    }
    else
    {
        boolPrimaryNeighborhood = false;
        removeN(strRID);
    }
    
    //alert(NiD + ":" + strRID + ":" + borderColor + ":" + boolPrimaryNeighborhood);
    
    var strURL = String.format("{0}Controls/AjaxCalls/GetN.aspx?RID={1}&B={2}", WebRoot, strRID, borderColor);
    
    //OverlayCache.RemoveCacheType("Neighborhood");
    //if (boolPageLoad == undefined)
    //{
    //    boolPageLoad = false;
    //}
    //if (boolPageLoad)
    //{

    if (OverlayCache.GetByTypeId("PrimeNeighborhood", strRID) != null)
    {
        //  Do not highlight neighborhood or add neighborhood 
        //  if it is already the prime neighborhood
        return;
    }
    
    
    $AJAX.GetForDelegate(function(AjaxResponse)
    {
        OverlayCache.Add(NiD, strRID, eval("new GPolygon.fromEncoded({\
		      polylines: [" + AjaxResponse + "],\
		      fill: true,\
		      color: '#" + fillColor + "',\
		      outline: true\
		    });"));
	    OverlayCache.RenderOverlayType(NiD);
		
		if (NiD=="PrimeNeighborhood")
		{
		    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		    //  if we're here, then it's a new Primary Neighborhood,
		    //  requiring that we recenter on the neighborhood boundaries
		    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		    RenderMapOptions(true);
		}
		
    }, strURL);
    return;
    //}
    /*
    for (var x=0;x<Pollies.length;x++)
    {
        if (Pollies[x][0] == strRID)
        {
            map.addOverlay(Pollies[x][1]);
            return;
        }
    }
    
    $AJAX.GetForDelegate(function(AjaxResponse)
    {
        var tPoly = eval("new GPolygon.fromEncoded({\
			  polylines: [" + AjaxResponse + "],\
			  fill: true,\
			  color: '#" + fillColor + "',\
			  outline: true\
			});");
			
         Pollies.push([strRID, tPoly]);
		 map.addOverlay(tPoly);
		 
    }, strURL);
    */
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  removeN(strRID)
//  Removes all highlighted neighborhoods from map, except Prime
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function removeN(strRID)
{
    //alert("here");
    OverlayCache.RemoveOverlayType("Neighborhood");
    OverlayCache.RemoveCacheType("Neighborhood");
    //OverlayCache.RenderOverlayType("Neighborhood");
    //alert("here");
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  CustomZIndexOrder
//  This is the delegate to pass to the zIndexProcess property of the 
//  Marker constructor. Don't know what the b value is or what it's used for.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function CustomZIndexOrder(Marker, b) 
{
    return GOverlay.getZIndex(Marker.getPoint().lat()) + Marker.CustomZIndex * 1000000;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  ReturnLastPan()
//  Returns map to last queried state
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ReturnLastPan()
{
	RunQuery(PageCache.LastQueryString, true);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  Get_Detail(IdListing)
//  Jump to the Listing Detail page
//  We need to carry several hidden form parameters with us
//  for Paging and Return to Results
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function Get_Detail(IdListing, e, eleDiv, SeoUrl)
{ 
     var target;
     var evt = e || window.event;
     target = evt.srcElement || evt.target; 
     if((target.id.indexOf("link_result_advertisername_")>-1)||
        (target.id.indexOf("result_logo_")>-1)||
        (target.id.indexOf("vt_")>-1)) return;
     
     if(SeoUrl == undefined || SeoUrl == '' || SeoUrl == null)
     {
        if(target == undefined || target == '' || target == null)
        {
            target = e;        
        }
        if(target.tagName.toLowerCase() == 'img')
        {
            if(target.parentNode.tagName.toLowerCase() == 'a')
            {
                target = target.parentNode;
            }else{
                target = target.parentNode.parentNode;        
            }
        }
    }
    else
    {
        target = SeoUrl;
    }    
    var isCTRL = false;
    
    if(evt.ctrlKey != undefined && evt.ctrlKey != null)
    {
        isCTRL = evt.ctrlKey;
    }
    
    var UGen = new UrlGen(PageCache.QueryString);
        UGen.RemoveParams(["LID","LIDS","T"]);
        UGen.AddParam("T",PageCache.TotalRecords);
        UGen.AddParam("LID",IdListing.toUpperCase());
        UGen.AddParam("LIDS",PageCache.ListingIds.toUpperCase());
        
        var strURL = WebRoot + "controls/ajaxcalls/DetailListingPath.aspx?" + UGen.ToString();
         
         //MA: Temp Commnets 
//        var arrHref = DetailSEOURL.split('/');
//        DetailSEOURL = arrHref[arrHref.length-2].toString();
//        if (DetailSEOURL != '') strURL += '&DetailSEOURL=' + DetailSEOURL.toUpperCase(); 
//                
        $AJAX.GetForDelegate(function(AjaxResponse)
        {
           // alert(AjaxResponse);
            var w = window;
            if(isCTRL)
            {w = window.open();w.opener.focus()}
            w.location.href = target;
            
        }, strURL);
        
//        if (WebRoot != "/")
//        {
//            window.location.href = WebRoot + "detail.aspx?" + UGen.ToString();
//            return;
//        }
//        
//        var theTarget = String.format("/for_sale/listing/{1}", WebRoot, IdListing);

//        document.SEO.Query.value = UGen.ToString();
//        document.SEO.action = theTarget;
//        document.SEO.submit();
}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  ToggleMapLoadOption
//  manages the ckeckbox that allows users to either reload the entire
//  page of results, or only the map.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ToggleMapLoadOption(ele)
{
    // Defined in the top of Results.aspx
    var CookieName = LastSearchCookieName; 
    var Key = "MapLoadOption";
    var Value = "False";
    if (ele.checked)
    {
        Value = "True";
        window.setTimeout(function()
        {
            RequeryOnBounds(false, true);
        },100);
    }
    SetCookieState(CookieName, Key, Value);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  Custom Price Range Functions
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function CustomPriceRangeToggle(objOpener, strMin, strMax)
{
    var ele = gE("custom_price");
    if (ele.style.display == "block")
    {
        ele.style.left = "1px";
        ele.style.top = "1px";
        ele.style.display = "none";
    }
    else
    {
        // for "modify"
        if (strMin != undefined && strMax != undefined) 
        {
            gE("custom_price_min").value = strMin;
            gE("custom_price_max").value = strMax;
        }
        else
        {
            gE("custom_price_min").value = "";
            gE("custom_price_max").value = "";
        }
        ele.style.left = ( RecurseOffset(objOpener).offsetLeft + RecurseOffset(objOpener).offsetWidth ) + "px";
        ele.style.top = RecurseOffset(objOpener).offsetTop + "px";
        ele.style.display = "block";
    }
    
}

function CustomPrice(FilterName)
{
    var CustomPrice = gE("custom_price");
    var Min = gE("custom_price_min").value;
    var Max = gE("custom_price_max").value;
    var MinHeader = gE("custom_price_min_header");
    var MaxHeader = gE("custom_price_max_header");
    var MinFooter = gE("custom_price_min_footer");
    var MaxFooter = gE("custom_price_max_footer");
    var Message = gE("custom_price_message");
    
    // reset all values
    MinHeader.innerHTML = "Minimum Price";
    MaxHeader.innerHTML = "Maximum Price";
    MinFooter.innerHTML = "i.e. 100,000";
    MaxFooter.innerHTML = "i.e. 153,000";
    Message.innerHTML = "";
    
    MinHeader.className = "CustomPriceNorm";
    MaxHeader.className = "CustomPriceNorm";
    MinFooter.className = "CustomPriceNorm";
    MaxFooter.className = "CustomPriceNorm";
    Message.style.display = "none";
    
    // validate
    
    Min = Min.replace(/[$,]+/g,'');
    Max = Max.replace(/[$,]+/g,'');
        
    if (isNaN(Min) || trim(Min) == "")
    {
       MinHeader.className = "CustomPriceError"; 
       MinFooter.className = "CustomPriceError";
       MinFooter.innerHTML = "please enter a number";
       return;
    }
    if (isNaN(Max) || trim(Max) == "")
    {
       MaxHeader.className = "CustomPriceError"; 
       MaxFooter.className = "CustomPriceError";
       MaxFooter.innerHTML = "please enter a number";
       return;
    }
    if (parseInt(Max,10) <= parseInt(Min,10))
    {
       MaxHeader.className = "CustomPriceError"; 
       MinHeader.className = "CustomPriceError";
       Message.className = "CustomPriceError";
       Message.style.display = "block";
       Message.innerHTML = "The minimum price cannot be greater than the maximum price";
       return;
    }
    
    var query = PageCache.QueryString;
    
    if (PageCache.TotalRecords == 0)
    {
        if (trim(PageCache.LastQueryString) != "")
        {
            query = PageCache.LastQueryString;
        }
    }
    
    var UGquery = new UrlGen(query);
        UGquery.RemoveParam("sid");
    var strURL = WebRoot + "controls/ajaxcalls/filterby.aspx?query=" + escape(UGquery.ToString());
    
    strURL += String.format("&type=range&name={0}&min={1}&max={2}", FilterName, Min, Max);
    
    CustomPriceRangeToggle();
     
    $AJAX.GetForDelegate(function(AjaxResponse)
    {
        //alert(AjaxResponse);
        RefinementQuery(AjaxResponse);
    },strURL);
   
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  Alters the CSS opacity of a Div Object
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function DivObjOpacity(DivObj, Op)
{
    // the DIV containing the map
    if (DivObj.id == "dMap") 
    {
        var tmp = /MSIE\s(\d+\.\d+);/;
        //test for MSIE x.x;
        if (tmp.test(navigator.userAgent)) 
        { 
            var matches = tmp.exec(navigator.userAgent);
            // capture x.x portion, make a number
            var ieversion= new Number(matches[1]); 
            if (ieversion < 7)
            {
                return;
            }
        }
    }
    DivObj.style.opacity = Op / 100;
	DivObj.style.filter = 'alpha(opacity=' + Op + ')';
}
































