/**
 *   YellowPages Search Manager
 *        returns yp business listing search results
 *
 *   These scripts need to be included: 
 *
 *   <script type="text/javascript" src="Scripts/ServerAJAX.js"></script>
 *   <script type="text/javascript" src="Scripts/JSON.js"></script>
 *   <script type="text/javascript" src="Scripts/ClientCache.js"></script>
 */

var YPSearchManager = new YPSearchManagerClass();

function YPSearchManagerClass()
{
    // Public methods
    this.Search = m_Search;
    this.ReSearch = m_ReSearch;
    this.RetrieveQueries = m_RetrieveQueries;
    this.AddLocationPinToMap = AddLocationPinToMap;
    this.CenterListing = m_CenterListing;
    this.ShowDualResults= ShowDualResults;
    //this.DefaultRecommendSearch = RecommendSearchDefault;
    this.ShowPopup = m_ShowPopup;
    this.OpenURL = OpenURL;
    this.ShowActionDiv = ShowActionDiv;
    this.GDDForListingPopup = GDDForListingPopup;
    this.GNBForListingPopup = GNBForListingPopup;
    this.GDDForLocationPopup = GDDForLocationPopup;
    this.GNBForLocationPopup = GNBForLocationPopup;
    this.SaveListingToCustomMap = SaveListingToCustomMap;
    this.SaveLocationToCustomMap = SaveLocationToCustomMap;
    this.HBXSearch = hbxSearch;
    this.isGNBForListingPopup = false;
    this.GenerateName = GenerateName;       //NEW
    this.GenerateAddress = GenerateAddress; //NEW
    this.GeneratePhone = GeneratePhone;		//NEW
    this.GenerateImage = GenerateImage;     //NEW
    this.GenerateDescription = GenerateDescription; //NEW
    this.GetMPData = GetMPData;             //NEW
    this.GetMPDataForMP = GetMPDataForMP;	//NEW
    var g_MPResult = new Object;			//NEW
    var g_GNBSelectedData = new Object;     //NEW
    var g_FullMPSelectedData = new Object;	//NEW FullMP
    this.toggleLinkedSection = toggleLinkedSection;     //NEW
    this.toggleToFromDDSection = toggleToFromDDSection; //NEW
    var mpShapeId; //NEW
    var ranGNBOnce = false;
    this.g_mapRadiusInPixels = null;		//NEW
    var visitedListings = new Object();	//NEW
    
    var dualResultShortTableSize = 1;   // Number of listing on short table for dual results
    var popupDelay = 800;               // Number of miliseconds to delay for popup after listing is centered
    
    var g_sResult = new Object();
    var g_recResult = new Object();
    var pinShapeLayer = null;
    var g_Locations = new Object();
    var locationIndex = 0;
    
    var tempIndex = 1; //Remove after index property added to businessList JSON data.  Used in AddListingPinToMap()
	var meterPerPixelAtZoom = new Hash({1:'78271.52', 2:'39135.76', 3:'19567.88', 4:'9783.94', 5:'4891.97', 6:'3445.98', 7:'1222.99', 8:'611.5', 9:'305.75', 10:'152.87', 11:'76.44', 12:'38.22', 13:'19.11', 14:'9.55', 15:'4.78', 16:'2.39', 17:'1.19', 18:'0.6', 19:'0.3'});

    /* g_Locations holds most recent search results
     * this function is used to set g_Locations from a foreign function peforming a search
     *
     * @param veplaces - array of VEPlace objects
     */
    this.includePlaces = function(veplaces) {
        g_Locations = veplaces;
    }

    /* g_listingShapeMap holds lookup hash of g_sResult indexes to shapeID's for the most search results
     * this function is used to set g_listingShapeMap from a foreign function thats adding the shapes to the map
     *
     * @param veplaces - array of VEPlace objects
     */
    this.updateListingShapeMap = function(index, value) {
        g_listingShapeMap[index] = value;
    }
    
    var g_navMap = true;
    var g_showDualResults = false;
    var g_listingShapeMap = new Array();
    
    // Search session objects
    var searchingLock = null;
    var recommendMode = false;
    
    /**
    * Issues an HBX event when a search is performed
    *
    * @param searchType - Type of search ('map', 'business' or 'directions')
    * @param count - Results count
    * @param keyword - Keyword typed by the user
    * @param location - Location keyword typed by the user
    */
    function hbxSearch(searchType, count, keyword, location)
    {

		SetCookie('HBXinternalSearch', keyword + '^' + count + '^' + location, null, "/");
				
		//_hbxResetPage(); // not calling because the values are static
		var _hbEC=0,_hbE=new Array;
        var ev1 = _hbEvent("search");
        //var hbx = _hbEvent("pv");
		var cv = _hbEvent("cv");
		
		//_hbxResetCommon(); // which calls _hbxResetEvents(); -- no need to call because _hbEvent is resetting object 

		cv.c13=lastCV.c13;
		cv.c15=lastCV.c15;
		cv.c19=lastCV.c19;

        ev1.keywords = keyword != null && keyword != '' ? _hbxStrip(keyword) : null;
        ev1.results = count;
        ev1.attr1 = location != null && location != '' ? _hbxStrip(_hbxAccentStrip(location)) : null;
        ev1.attr2 = "map";
        
        var catHeadings = "";
        if(g_sResult.relevantCategories != undefined && g_sResult.relevantCategories != null & g_sResult.relevantCategories.length > 0) {
	        if(debug)console.log("g_sResult.relevantCategories: ",g_sResult.relevantCategories);

            catHeadings = g_sResult.relevantCategories.join('_1,') + "_1";
        }
        	
        if(g_sResult.nonRelevantCategories != undefined && g_sResult.nonRelevantCategories != null && g_sResult.nonRelevantCategories.length > 0) {
            catHeadings += catHeadings != "" ? "," : "";
            catHeadings += g_sResult.nonRelevantCategories.join('_0,') + "_0";
        }
        
        //ev1.attr3 = g_sResult.relevantCategories.join('_1,') + "_1," + g_sResult.nonRelevantCategories.join('_0,') + "_0";
        ev1.attr3 = catHeadings;
        ev1.attr4 = g_sResult.directories.join(',');
        /*switch(searchType)
        {
            case "map":
                ev1.attr2 = "find on a map";
                break;
            case "business":
                ev1.attr2 = "find a business";
                break;
            case "directions":
                ev1.attr2 = "get driving directions";
                break;
        }*/

        _hbSend();
    }
    
    /**
     * Find a Business or Person Search
     *
     * @param keyOrBus ('bus' or 'per') determines if the search is on business or person
     * @param navMap   (bool) specifies whether the VE map should be navigated to the first mapped result
     * @param vePlaces (VEPlace[]) is the list of VE results returned
     */
    function m_Search(keyOrBus, navMap, vePlaces) {
    	// Previous to this... a MapManager.Map.DeleteAllShapes() was already run in MapManager.FindLookup !!
    
        searchingLock = new Object();
        recommendMode = false;
        tempIndex = 1; //TEMP reset to 1 for each search done
        
        // determine search type
        var businessSearch = (keyOrBus == 'bus');
        var personSearch = (keyOrBus == 'per');
        
        // business name only search checkbox default to un-checked
        var sbn = (businessSearch) ? (document.getElementById('cbBusOnly') != null ? document.getElementById('cbBusOnly').checked : false ) : false;
        
        // Determine if navigation to first result
        g_navMap = true;
        g_showDualResults = false;
        g_Locations = vePlaces;
        
        var searchType = keyOrBus;
        var query=new SearchQuery(keyOrBus,null,null,(vePlaces != null && vePlaces.length > 0 ? vePlaces[0].LatLong : null),null,null);        
        
        if (navMap != undefined)
        {
            g_navMap = navMap;
        }
        ShowLoading()
       ClientCache.Save("g_ReusePane", paneNumber);
       ClientCache.Save("g_FullTable", "fab_table"+paneNumber);
       ClientCache.Save("g_Summary", "fab_summary"+paneNumber);
       ClientCache.Save("g_Goto", "fab_goto"+paneNumber);
       ClientCache.Save("g_Goto_top", "fab_goto_top"+paneNumber);
       ClientCache.Save("g_FullBus", "fab_full" + paneNumber);
        
        // Clear pins on map
        //pinShapeLayer not created because it was commented out by someone.... true && false
        if((pinShapeLayer != null)&&(this.isGNBForListingPopup == false))
        {
            pinShapeLayer.DeleteAllShapes();
        }
        InfoBoxManager.ClearDescriptions('Location');
        //var location = ClientCache.Retrieve('pane_' + paneNumber + '_LocationInput').cleanse(); // Just what user typed (with typos) or Center lat/lon value.  Could be fixed up by FindInputValidatorCallback or FindBusPerCallback but it isn't
        var location = ClientCache.Retrieve('pane_' + paneNumber + '_EnteredLocationInput').cleanse(); // Just what user typed (with typos)
        var keyword = ClientCache.Retrieve('pane_'+paneNumber+'_NameInput').cleanse();
if(debug)console.log("YPSM.Search: paneNumber:%s what:%s, where:%s, [entered where: %s]", paneNumber, keyword, location, ClientCache.Retrieve('pane_' + paneNumber + '_EnteredLocationInput'));
        
        //UP var qString = "?keyword=" + keyword + "&location=" + location + "&txtMode=" + keyOrBus + "&sbn=" + sbn;
        var qString = "?what=" + keyword + "&where=" + location + "&sbn=" + sbn;
        
        var vePlace = vePlaces[0];
        //vePlace.Name // city, province abreviation
        
        qString += "&lat=" + vePlace.LatLong.Latitude + "&lon=" + vePlace.LatLong.Longitude + "&confidence=" + vePlace.MatchConfidence;


        mapManager.Map.SetCenter(new VELatLong(vePlace.LatLong.Latitude, vePlace.LatLong.Longitude));
        /* Saving lat/lon of center point to compare in mm.mapSearch to prevent another search triggered by onendpan/onendzoom after a non lat/lon search.
           (i.e. user looking at map near Burnaby and then uses search form to search in Burnaby and map pans because it's close by visually) */ 
        //if(debug)console.log("Saved lat and long for mapSearch to use to compare");
        ClientCache.Save("LatLongSpecified", "true");
        ClientCache.Save("Latitude", vePlace.LatLong.Latitude);
        ClientCache.Save("Longitude", vePlace.LatLong.Longitude);
        ClientCache.Save("Confidence", vePlace.MatchConfidence);

        
        //NA if (businessSearch && location.isSimpleSearchCity()) qString += "&rci=" + location.cleanse();        
                              // simple search yes but has numbers = true  // simple search is false
        //NA var simpleSearchOff = (triggerSimpleSearchInAllCases && location.containsNumbers()) || (!triggerSimpleSearchInAllCases);
        //NA var doProximitySearch = (simpleSearchOff && vePlaces != null && vePlaces.length > 0 && !location.isSimpleSearchCity() && location.cleanse() != "canada");
        
        //UP if(doProximitySearch)
        if(this.isGNBForListingPopup)
        {
        	//if(debug)console.log("Running AddLocationPinToMap for location: ", location, " and location.isSimpleSearchCity() returns: " , location.isSimpleSearchCity());
            // The new pan/zoom->search logic requires always sending the lat/lon of the center... not just for GNB search.
            //var vePlace = vePlaces[0];
            //qString += "&lat=" + vePlace.LatLong.Latitude + "&lon=" + vePlace.LatLong.Longitude + "&confidence=" + vePlace.MatchConfidence;
            
            // For business search, put blue pin on the map
            if (businessSearch)
            {
                //AddLocationPinToMap(0, vePlace.Name, vePlace.LatLong.Latitude, vePlace.LatLong.Longitude, 1);
                AddLocationPinToMap();
            }
            
            // Saving result in client cache for re-search
            //if(debug)console.log("Saved lat and long");
            ClientCache.Save("LatLongSpecified", "true");
            ClientCache.Save("Latitude", vePlace.LatLong.Latitude);
            ClientCache.Save("Longitude", vePlace.LatLong.Longitude);
            ClientCache.Save("Confidence", vePlace.MatchConfidence);
        }
        else
        {
            ClientCache.Save("LatLongSpecified", "false");
        }

        //NA qString += "&newSearch=1";

		// Calculate radius
        var s1 = mapManager.Map.LatLongToPixel(mapManager.Map.GetCenter()).y;
        var s2 = mapManager.Map.LatLongToPixel(mapManager.Map.GetCenter()).x;
if(debug)console.log("Center pixel x y ", mapManager.Map.LatLongToPixel(mapManager.Map.GetCenter()).x, mapManager.Map.LatLongToPixel(mapManager.Map.GetCenter()).y);
        var s3 = Math.sqrt(s1*s1 + s2*s2);
        this.g_mapRadiusInPixels = s3;
        
        var curZoomLevel = mapManager.Map.GetZoomLevel();
        var mppaz = meterPerPixelAtZoom.get(curZoomLevel);
        var s3km = Math.round(s3*mppaz/1000);
        
		//var s3km = Math.round(s3*meterPerPixelAtZoom.get(mapManager.Map.GetZoomLevel())/1000);
        qString += "&dist="+s3km;
if(debug)console.log("s1:%f s2:%f s3:%f s3km:%f", s1, s2, s3, s3km);

        if (isFrench())
        {
            qString += "&language=FR";
        }
        
        //NA qString += "&perPage=10";
        
        // Save in cache
        ClientCache.Save('busName', keyword);
        ClientCache.Save('location', location);
        query.What=keyword != '' ? keyword : null;
        query.Where=location != '' ? location : null;
		
		// save keyword and location to client cache with current panenumber
        ClientCache.Save('pane_'+paneNumber+'_keyword', keyword);
        ClientCache.Save('pane_'+paneNumber+'_location', location);         
        ClientCache.Save('lastSearch', keyOrBus);
        
        ClientCache.Save('pane_'+paneNumber+'_type', keyOrBus);
        ClientCache.Save('pane_'+paneNumber+'_query', qString);
        
        // update/store query in cookie
        this.PersistQuery(query, keyOrBus);

        qStringCache = qString + "&pageNum=1";
        //UP var request = new AjaxRequest("Handlers/YPSearch.ashx" + qString, ProcessResult);
        var request = new AjaxRequest("/ajax/businesses.html" + qString, ProcessResultNew);

        request.Execute();
    }
    
    /**
     * Search frrom page nav buttons, use existing sear
     * Search from page nav buttons, use existing search result as criteria
     *
     * @param pageNum (int) indicates the current page number for a listing re-search
     * @param reusePaneNumber (int) indicates the index of the panel to reuse
     */
    function m_ReSearch(pageNum, reusePaneNumber)
    {
//        // Do not start new search when lock cannot be acquired
//        if (searchingLock) {
//            alert('Please wait for current search to finish');
//            return;
//        }
        searchingLock = new Object();
        recommendMode = false;
        currentKeyOrBus = keyOrBus;

        //every time someone searches it creates a new accordion pane
        var paneNumber;
        g_showDualResults = false;

        var keyOrBus = ClientCache.Retrieve('lastSearch');
        
        var keyword = ClientCache.Retrieve('pane_'+reusePaneNumber+'_keyword');
        var location = ClientCache.Retrieve('pane_'+reusePaneNumber+'_location');            
        
        var paneNumber;
        if (reusePaneNumber != undefined)
        {
           paneNumber = reusePaneNumber;
        }
        else 
        {
            paneNumber = ClientCache.Retrieve('selected_pane_num');
        }        
        ClientCache.Save("g_ReusePane", paneNumber);
        ClientCache.Save("g_Table", "fab_table"+paneNumber);
        ClientCache.Save("g_Summary", "fab_summary"+paneNumber);
        ClientCache.Save("g_Goto", "fab_goto"+paneNumber);   
        ClientCache.Save("g_Goto_top", "fab_goto_top"+paneNumber);        
        ClientCache.Save("g_FullBus", "fab_full"+paneNumber);

        // Clear pins on map
        if (pinShapeLayer != null)
        {
            pinShapeLayer.DeleteAllShapes();
        }

        if (!g_sResult)
        {
            keyword = g_sResult.Keyword;
            location = g_sResult.Location;
        }
        var qString = "?keyword=" + keyword + "&location=" + location + "&pageNum=" + pageNum + "&txtMode=" + keyOrBus + "&newSearch=0";
        if (location.isSimpleSearchCity()) qString += "&rci=" + location.cleanse();
        // Extract previous latlong info from client cache
        var spec = ClientCache.Retrieve("LatLongSpecified");
        if (spec && spec == "true")
        {
            qString += "&lat=" + ClientCache.Retrieve("Latitude") + "&lon=" + ClientCache.Retrieve("Longitude") + "&confidence=" + ClientCache.Retrieve("Confidence");
        }
        if (isFrench())
        {
            qString += "&language=FR";
        }
        qString += "&perPage=10";
        
        qStringCache = qString;
        var request = new AjaxRequest("Handlers/YPSearch.ashx" + qString, ProcessResult);
        request.Execute();
    }

	this.mapBranchResults = function(rText) {
	
	    ClientCache.Save('pane_-1_EnteredLocationInput', document.getElementById('newSearchWhere').value);
	    ClientCache.Save('pane_-1_NameInput', document.getElementById('newSearchWhat').value);
	
		ProcessResultNew(rText);
	}

    /**
     * Call back function on YellowPages business listing search
     */
	function ProcessResultNew(rText)
	{
	    try {
	        //TEST YPSearchManager.ClearFind(); //This clears the where form field currently, it also eventually calls mm.Map.DeleteAllShapes() which is deleting the GNB centered pin
	        document.getElementById('txtBusLocation').value = ''; //When txtBusLocation is blanked... future searches based on center lan/lon
	        g_sResult = eval('(' + rText + ')');  //Other functions are referencing this global directly

            //make an HBX event call for new business searches
            if(g_sResult != null)
            {
                //var locationSearched = ((ClientCache.Retrieve('lastSearch') == 'bus') ? document.getElementById('txtBusLocation').value : document.getElementById('txtPersonLocation').value);
                lastCV = cv;
                hbxSearch('business', g_sResult.listingTotal, g_sResult.what, ClientCache.Retrieve('pane_' + paneNumber + '_EnteredLocationInput'));
            }

            // Update Result summary
            UpdateSummaryHeading();
            		
	        if (g_sResult != undefined && g_sResult.businessList != null) {
	        	var listingAdTypeMap = { Ad:100, NonAd:101 };
	            clusterManager.PoiPresent = true;
	            var returnedShapesAds = new Array();
	            //var returnedShapesNonAds = new Array();
	            for (var x = 0; x < g_sResult.businessList.length; x++) {
	            	if(isBranchSearch == true) {
	            		var listingAdTypeId = 102;
	            	} else {
	                	var listingAdTypeId = listingAdTypeMap[g_sResult.businessList[x].pushpinType];
	                }
	            	/* separate into 2 arrays to cluster separately
	            	if(listingAdTypeId == "100")
	            		returnedShapesAds.push(AddListingShape(x, listingAdTypeId)); //100
	            	else
	            		returnedShapesNonAds.push(AddListingShape(x, listingAdTypeId)); //101
	            	*/
	            	returnedShapesAds.push(AddListingShape(x, listingAdTypeId)); //100 and 101
	            	
	            }
	        }
	    }
	    catch(e)
	    {
	        //alert(e.message);
	        if(debug)console.log("Catch Block: ProcessResultNew: %s", e.message);
	    }
	    
	    if(returnedShapesAds != null && returnedShapesAds.length > 0) {
	        // is this really needed because MapManager.Map.DeleteAllShapes() run before this already.
	        // yes because clusterManager has member variables that say they still exist!!!
	        clusterManager.DeleteShapes(100);
	        clusterManager.AddShapes(returnedShapesAds, 100);
	    }
	    /*if(returnedShapesNonAds != null && returnedShapesNonAds.length > 0) {
	        clusterManager.DeleteShapes(101);
	        clusterManager.AddShapes(returnedShapesNonAds, 101);
	    }*/

        /* The call to SetMapView zooms the map out to show all the pins and 
           this is not good because there could be pins on the outskirts of the
           radius that are not in the rectangular view port. */
        if(isBranchSearch) {
	        if(g_sResult.listingTotal == 1)
	        {
	            // Set map view based on first geocoded result
	            m_CenterListing(1);
	        }
	        else
	        {
	            var locations = new Array();
	            for (var y = 0; y < g_sResult.businessList.length; y++)
	            {
	                var business = g_sResult.businessList[y];
	                //UP if (business.GeoCodeSpecified)
	                if (business.address.location)
	                {
	                   locations.push(new VELatLong(business.address.location.latitude, business.address.location.longitude));
	                }
	            }
	            if (locations.length > 0) {
	                mapManager.Map.SetMapView(locations);
	            }
	        }
        }
	    
	    HideLoading();
	    
        ClientCache.Save('zoomSearch', mapManager.Map.GetZoomLevel());

		if(!isBranchSearch) {
	    	if(debug)console.log("In YPSM.ProcessResultNew:  Connected: %s.", mapManager.MapSearchAttachedPZ);
	        if (!mapManager.MapSearchAttachedPZ)
	        {
	        	if(debug)console.log("In YPSM.ProcessResultNew:  Connected: %s.  Going to connect.", mapManager.MapSearchAttachedPZ);
	            mapManager.AttachPanZoomEventMapSearch();
	        }
        }
	}

    /**
    * Generate Listing Shape
    */
    function AddListingShape(listingIndex, typeId) {
    	var currentListing = g_sResult.businessList[listingIndex];
    	var pinVELatLong = new VELatLong(currentListing.address.location.latitude, currentListing.address.location.longitude);
        var shape = new VEShape(VEShapeType.Pushpin, pinVELatLong);
//        var listingImg = GetIcon(currentListing.pushpinType);  // Don't want to specify image inline, do it via CSS

/*
        var pixel = mapManager.Map.LatLongToPixel(pinVELatLong);
        if (currentListing.pushpinType == 'Ad') {
        	pinXOffset = -35;
        	pinYOffset = -31;
        } else if (currentListing.pushpinType == 'NonAd') {
        	pinXOffset = -8;
        	pinYOffset = -7;
        }

        var customIconSpecification = new VECustomIconSpecification();
        customIconSpecification.ImageOffset = new VEPixel(pinXOffset,pinYOffset);
        customIconSpecification.Image = "/images/shared/map/" + listingImg;
*/

		if(currentListing.pushpinType == 'Ad') {
// Using VECustomIconSpecification to specify custom icon is only necessary if need to support 3D as well as 2D.
// CustomHTML is just property for the 2D (this value is what you would normally pass to SetCustomIcon if all you cared about was 2D
//			customIconSpecification.CustomHTML = "<div class='pin_wf'></div>";
//			shape.SetCustomIcon(customIconSpecification);

// This is attempt to position absolutely to the corner of the map, but failed because there is anchor tag containing this div that is set absolute which is wrong reference container.
//        	shape.SetCustomIcon("<div class='pin_wf' style='position:absolute; left:" + (pixel.x + pinXOffset) + "px; top:" + (pixel.y + pinYOffset) + "px;'></div>");
//          if(debug)console.log("SetCustomIcon:", pixel.x, pinXOffset, pixel.y, pinYOffset);

//          shape.SetCustomIcon("<div class='pin_wf' style='background:url(/images/shared/map/" + listingImg + ")'></div>");

            if(visitedListings[currentListing.listingId] == 1)
              	shape.SetCustomIcon("<div class='pin_v_wf'></div>");
            else
        		shape.SetCustomIcon("<div class='pin_wf'></div>");
        } else {
//        	customIconSpecification.CustomHTML = "<div class='pin_nonad'></div>";
//			shape.SetCustomIcon(customIconSpecification);

//        	shape.SetCustomIcon("<div class='pin_nonad' style='position:absolute; left:" + (pixel.x + pinXOffset) + "px; top:" + (pixel.y + pinYOffset) + "px;'></div>");        

//          shape.SetCustomIcon("<div class='pin_nonad' style='background:url(/images/shared/map/" + listingImg + ")'></div>");

            if(visitedListings[currentListing.listingId] == 1)
               	shape.SetCustomIcon("<div class='pin_v_nonad'></div>");
            else
        		shape.SetCustomIcon("<div class='pin_nonad'></div>");
        }
        
        if(isBranchSearch == true) {
        	shape.SetCustomIcon("<div class='mapIcon'>" + currentListing.index + "</div>");
        }
        
        var imKey = InfoBoxManager.GenerateKey('imListing' + typeId, listingIndex);
        var description = imKey;
        shape.SetDescription(description + GenerateOnHoverDescription(listingIndex,typeId));
        //Stop  shape.SetTitle('poi');

        return shape;
    }

    /**
     * Get listing icon depending on listing type
     */
    function GetIcon(pushpinType, listingId)
    {
        var imageExt = (browserManager.BrowserName == 'msie' && browserManager.BrowserVersion < 7.0 ? '.gif' : '.png');
		var imageName = "";
        		    
        switch (pushpinType)    
        {
            case 'Ad':
                if(visitedListings[listingId] == 1)
                	imageName = 'Visited-WF';
                else
                	imageName = 'WF';
                return imageName + imageExt;
            case 'NonAd':
                if(visitedListings[listingId] == 1)
                	imageName = 'BasicVisited';
                else
                	imageName = 'BasicMarker';
                return imageName + imageExt;
            default:
                return 'WF' + imageExt;
        }
    }

    /**
     * Toggle Action Section open/closed
     * @param section id of section to show/hide
     * @param collapse id of icon in corner to switch between +/-
     */
	function toggleLinkedSection(section, closeSection)
	{
		if(section && section != "") {
			var collapse = section + "Toggle";
			if ("none" == document.getElementById(section).style.display) {
				document.getElementById(section).style.display = "block";
				$(collapse).addClassName('ypSmCollapse');
				$(collapse).removeClassName('ypSmExpand');
				
			} else {
				document.getElementById(section).style.display = "none";
				$(collapse).addClassName('ypSmExpand');
				$(collapse).removeClassName('ypSmCollapse');
			}
		}
		var collapse = closeSection + "Toggle";
		document.getElementById(closeSection).style.display = "none";
		$(collapse).addClassName('ypSmExpand');
		$(collapse).removeClassName('ypSmCollapse');
		
	}

    /**
     * Toggle To/From Driving Directions Section
     */
	function toggleToFromDDSection(index)
	{
		if(index && index != "") {
			if ("none" == document.getElementById('A_FROM_' + index).style.display) {
				document.getElementById('A_FROM_' + index).style.display = "block";
				document.getElementById('A_TO_' + index).style.display = "none";			
			} else {
				document.getElementById('A_FROM_' + index).style.display = "none";
				document.getElementById('A_TO_' + index).style.display = "block";
			}
		}
	}

    /**
     * Generate the mini merchant bubble html
     *
     * @return the description
     */
    function GenerateDescription(listingIndex,poiType,gnbListing)
    {
        //var currentBusListing = g_sResult.businessList[listingIndex];

        if(gnbListing != undefined && gnbListing != null) {
            var mpListing = gnbListing.listing;
            var hbxWhat = gnbListing.what;
            var hbxWhere = gnbListing.where;
        } else {
            var mpListing = g_MPResult.listing;
            var hbxWhat = g_MPResult.what;
            var hbxWhere = g_sResult.where;
        }
        
        //var mpListing = g_sResult.businessList[listingIndex];
		//var hbxWhat = g_sResult.what;
		//var hbxWhere = g_sResult.where;
		
		if(mpListing.merchantMapURL != null)
			var staticMapURL = mpListing.merchantMapURL.href;
		else
			var staticMapURL = "";
			
			
		if(mpListing.categoryDirectoryList != null)
			var catDirList = mpListing.categoryDirectoryList;
		else
			var catDirList = new Array();

/*
        if(mpListing.tabURLs.eco != undefined) {
            //GetID of "c" container pushpin so I can make changes to it
            var shapeC = g_listingShapeMap[listingIndex] + "c";
            if(debug)console.log("mmb: This is eco: Apply eco style on id:", shapeC);
            //$(shapeC).addClassName('ecoListingType');  // div not added to page yet!!! can't do this
			// Could try to setTimeout and then run to apply green...but would be wierd
        }
*/

        //var mmbClass = (mpListing.tabURLs.eco != undefined) ? 'ypgMerchantMiniBubbleWrapper ecoListingType' : 'ypgMerchantMiniBubbleWrapper';
        //var description = '<div class="' + mmbClass + '">';   // ypgMerchantMiniBubbleWrapper - Overall container for MMB edges and corners
        var description = '<div class="ypgMerchantMiniBubbleWrapper">';   // ypgMerchantMiniBubbleWrapper - Overall container for MMB edges and corners

        var ecoClass = (mpListing.tabURLs.eco != undefined) ? 'ecoType' : '';
        var ecoCornerClass = (mpListing.tabURLs.eco != undefined) ? 'ecoCornerType' : '';

        description += '<div class="ypgTopRoundedRow ' + ecoCornerClass + '">';
        description += '<div class="tl"></div>';
        description += '<div class="tm ' + ecoClass + '"></div>';
        description += '<div class="tr"></div>';
        description += '</div>'; // ypgTopRoundedRow

        var mmbClass = (mpListing.tabURLs.eco != undefined) ? 'ypgMerchantMiniBubble ecoType' : 'ypgMerchantMiniBubble';
        description += '<div class="' + mmbClass + '">';   // Overall for content
        //description += '<div class="ypgMerchantMiniBubble">';   // Overall for content

        description += '<div class="ypgMerchantMiniBubbleInner">';
        //description += '<div class="ypgMMBClose"><a class="ypSpLayerFunctions ypSmClose" href="#" onclick="javascript:activeEro.Hide();return false;" rel="nofollow">&nbsp;</a></div>';
        description += '<div class="popupLeft">';
        description += '<div class="ypgMMBStaticMap" style="background: url(' + staticMapURL + ') no-repeat"></div>';
        description += '<div class="ypgMMBStaticMapPin"><div class="pin_selected pin_staticAdjust"></div></div>';

        if(isMerchantPage == false) {

        // What's near (Action)
		description += '<div class="ypgMMBNB">';
        description += '<span class="ypgActionTitle ypgMMBLinks">';
//		description += '<a class="chicklets ypWhatsNearby" href="#" onclick="javascript:YPSearchManager.toggleLinkedSection(\'ypWhatsNearbyContent\',\'ypDrivingDirectionsContent\');return false;" onmousedown="_hbSet(\'lid\',\'whats_nearby\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" rel="nofollow">' + resourceWhatsNearby + '</a><br/>';
		description += '<a class="chicklets ypWhatsNearby" href="#" onclick="javascript:YPSearchManager.toggleLinkedSection(\'ypWhatsNearbyContent\',\'ypDrivingDirectionsContent\');return false;" onmousedown="hbxFromExpandToggle(\'ypWhatsNearbyContent\', \'whats_nearby\', \'in_bubble\');" rel="nofollow">' + resourceWhatsNearby + '</a><br/>';
		description += '</span>';
        description += '<span style="float:right; padding-top:5px;">';
//        description += '<a id="ypWhatsNearbyContentToggle" class="ypSpLayerFunctions ypSmExpand" href="javascript:YPSearchManager.toggleLinkedSection(\'ypWhatsNearbyContent\', \'ypDrivingDirectionsContent\');" onmousedown="_hbSet(\'lid\',\'whats_nearby\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" rel="nofollow">&nbsp;</a><br/>';
        description += '<a id="ypWhatsNearbyContentToggle" class="ypSpLayerFunctions ypSmExpand" href="javascript:YPSearchManager.toggleLinkedSection(\'ypWhatsNearbyContent\', \'ypDrivingDirectionsContent\');" onmousedown="hbxFromExpandToggle(\'ypWhatsNearbyContent\', \'whats_nearby\', \'in_bubble\');" rel="nofollow">&nbsp;</a><br/>';
        description += '</span>';
        description += '<div class="clearboth"></div>';
        
        description += '<div id="ypWhatsNearbyContent" class="ypgMMBSmText" style="display:none;">';
        description += resourceFind + ' <input type="text" id="nearby' + listingIndex + '" style="width:130px;" onkeydown="ExecuteFindFromInput(\'imgNear' + (listingIndex) + '\', event);"/><br/>';
        description += '<div><img id="imgNear' + (listingIndex) + '" src="/images/shared/' + lang + '/ffffff/Find.gif" class="popupLink handicon" style="float: right; margin-top:11px;" onclick="_hbSet(\'lid\',\'search_button\');_hbSet(\'lpos\',\'nearby_in_bubble\');_hbSend();YPSearchManager.GNBForListingPopup(' + listingIndex + ');"/></div>'; 

        description += '<div class="clearboth"></div>';
        description += '</div>';
  		description += '</div>'; //ypgMMBNB

		// Driving Directions (Action)
		description += '<div class="ypgMMBDD">';
        description += '<span class="ypgActionTitle ypgMMBLinks">';
//		description += '<a class="chicklets ypDrivingDirections" href="#" onclick="javascript:YPSearchManager.toggleLinkedSection(\'ypDrivingDirectionsContent\',\'ypWhatsNearbyContent\');return false;" onmousedown="_hbSet(\'lid\',\'driving_directions\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" rel="nofollow">' + resourceDD + '</a><br/>';
		description += '<a class="chicklets ypDrivingDirections" href="#" onclick="javascript:YPSearchManager.toggleLinkedSection(\'ypDrivingDirectionsContent\',\'ypWhatsNearbyContent\');return false;" onmousedown="hbxFromExpandToggle(\'ypDrivingDirectionsContent\', \'driving_directions\', \'in_bubble\');" rel="nofollow">' + resourceDD + '</a><br/>';
		description += '</span>';
        description += '<span style="float:right; padding-top:5px;">';
//      description += '<a id="ypDrivingDirectionsContentToggle" class="ypSpLayerFunctions ypSmExpand" href="javascript:YPSearchManager.toggleLinkedSection(\'ypDrivingDirectionsContent\', \'ypWhatsNearbyContent\');" onmousedown="_hbSet(\'lid\',\'driving_directions\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" rel="nofollow">&nbsp;</a><br/>';
        description += '<a id="ypDrivingDirectionsContentToggle" class="ypSpLayerFunctions ypSmExpand" href="javascript:YPSearchManager.toggleLinkedSection(\'ypDrivingDirectionsContent\', \'ypWhatsNearbyContent\');" onmousedown="hbxFromExpandToggle(\'ypDrivingDirectionsContent\', \'driving_directions\', \'in_bubble\');" rel="nofollow">&nbsp;</a><br/>';
        description += '</span>';
        description += '<div class="clearboth"></div>';
        
        // Div that opens and closes
        description += '<div id="ypDrivingDirectionsContent" class="ypgMMBSmText" style="display:none;">';

        // To somewhere (Action)
        description += '<div id="A_TO_' + listingIndex + '" style="display:none;">';
        description += '<a href="#" onclick="javascript:YPSearchManager.toggleToFromDDSection(' + listingIndex + ');return false;" name="&amp;lid=information&amp;lpos=in_bubble" rel="nofollow">' + resourceFrom + '</a> / ' + resourceTo + '<br/>';
        description += '<input type="text" id="toAddress' + listingIndex + '" style="width:158px;" onkeydown="ExecuteFindFromInput(\'imgTo' + (listingIndex) + '\', event);"/><br/>';
        description += '<div><img id="imgTo' + (listingIndex) + '" src="/images/shared/' + lang + '/ffffff/Find.gif" class="popupLink handicon" style="float: right; margin-top:11px;" onclick="_hbSet(\'lid\',\'search_button\');_hbSet(\'lpos\',\'directions_in_bubble\');_hbSend();YPSearchManager.GDDForListingPopup(\'TO\', ' + (listingIndex)  + ');" /></div>';
        description += '<div class="clearboth"></div>';
        description += '</div>'; //A_TO
        
        // From somewhere to Here (Action)
        description += '<div id="A_FROM_' + listingIndex + '" style="display:block;">';
        description += resourceFrom + ' / <a href="#" onclick="javascript:YPSearchManager.toggleToFromDDSection(' + listingIndex + ');return false;" name="&amp;lid=information&amp;lpos=in_bubble" rel="nofollow">' + resourceTo + '</a><br/>';
        description += '<input type="text" id="fromAddress' + listingIndex + '" style="width:158px;" onkeydown="ExecuteFindFromInput(\'imgFrom' + (listingIndex) + '\', event);"/><br/>';
//        description += '<div><a style="float:left; font-size:0.8em;margin:16px 0 10px 0;">'  + resourceWhatIsThis + '</a><img id="imgFrom' + (listingIndex) + '" src="/images/shared/' + lang + '/Find.gif" class="popupLink" style="float: right; margin-top:11px;" onclick="YPSearchManager.GDDForListingPopup(\'FROM\', ' + (listingIndex)  + ');"/></div>';
        description += '<div><img id="imgFrom' + (listingIndex) + '" src="/images/shared/' + lang + '/ffffff/Find.gif" class="popupLink handicon" style="float: right; margin-top:11px;" onclick="_hbSet(\'lid\',\'search_button\');_hbSet(\'lpos\',\'directions_in_bubble\');_hbSend();YPSearchManager.GDDForListingPopup(\'FROM\', ' + (listingIndex)  + ');"/></div>';
        description += '<div class="clearboth"></div>';
        description += '</div>'; //A_FROM
        
        description += '</div>'; //ypDrivingDirections       
		description += '</div>'; //ypgMMBDD
        } // if isMerchantPage == false
                		        
        description += '</div>';  //popupLeft
        description += '<div class="popupRight">';

        if(mpListing.thumbnailURL != null) {
            if(mpListing.thumbnailURL.href.search('Video.html') > 0) {
		        //video thumb image
				description += '<div style="position: relative;">';
					description += '<div class="photoFrame1">';
					//<a href="/bus/British-Columbia/Coquitlam/Ramada-Coquitlam/2488646/Video.html?  adid=14432356ac&amp;playVideo=true&amp;what=hotels&amp;where=burnaby&amp;le=9ed697834e%7C54a841060e%7C1caf4c220e%7Ccd13c6ba0e" class="listingLink" onmousedown="_hbSet('cv.c2','1329404_DPlus|video_hotels');_hbSet('cv.c3','00682205|086542,00363600|086542,00123200|086542,00880800|086542');_hbSend();" name="&amp;lid=video_th&amp;lpos=in_listing">
			        description += '<a href="' + mpListing.thumbnailURL.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|video_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'video_th\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank">';
					description += '<img border="0" src="/images/th_frame.gif"/></a>';
					description += '</div>';
		
					//<img border="0" width="90" height="70" alt="Ramada Coquitlam 604-931-4433 - www.ramadacoquitlam.com" src="http://media.yp.ca/18249/1244164650572_t.jpg"/>
					description += '<img class="noborder" src="' + mpListing.thumbnailURL.src + '" alt="' + mpListing.thumbnailURL.alt + '"/>';
				description += '</div>';
            } else {
		        //basic thumb image
		        description += '<a href="' + mpListing.thumbnailURL.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|logo_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'logo\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank"><img class="noborder" src="' + mpListing.thumbnailURL.src + '" alt="' + mpListing.thumbnailURL.alt + '"/></a>';
		        description += '<br />';
		    }
        }
        
		var clsLinkClass = "";
		if (mpListing.presentation.nameBold && mpListing.presentation.nameColour) {
			clsLinkClass = "elpBoldColour";
		} else if (mpListing.presentation.nameBold) {
			clsLinkClass = "elpBold";		
		} else if (mpListing.presentation.nameColour) {
			clsLinkClass = "elpColour";
		} else {
			clsLinkClass = "listingTitle";
		}
		                
        description += '<a href="' + mpListing.merchantURL.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|busName_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'busname\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank"><span class="ypgMMBmerchantName ' + clsLinkClass + '">' + mpListing.name + '</span></a><br />';
//        description += '<div class="phoneLink"><a class="ypgCallButton" href="javascript: openWin(\'' + mpListing.freecallURL.href  + '\', \'477\', \'405\');" class="freeCallLink" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|free_call_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'free_call\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" rel="nofollow" >' + mpListing.phone + '</a></div>';
        if( (true == isMerchantPage && true == isMerchantNonPaidListing) || (mpListing.pushpinType == 'NonAd') ) {
            description += '<div class="phoneLink">' + mpListing.phone + '</div>';
        } else {
           description += '<div class="phoneLink"><a class="ypgCallButton" href="javascript: openWin(\'' + mpListing.freecallURL.href  + '\', \'477\', \'405\');" class="freeCallLink" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|free_call_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'free_call\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" rel="nofollow" >' + mpListing.phone + '</a></div>';
        }
        
        description += '<div class="ypgMMBaddress">' + mpListing.address.street + ", <br/>" + mpListing.address.city + ", " + mpListing.address.province + " " + mpListing.address.postalCode + '</div>';
        if(mpListing.webURL != null){
        description += '<div class="urlLink ypgMMBLinks"><a class="chicklets ypWebsite" href="' + mpListing.webURL.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|website_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'website\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank" rel="nofollow">' + resourceWebsite + '</a></div>';
        }
        if(mpListing.email != null && mpListing.email != ""){
        description += '<div class="emailLink ypgMMBLinks"><a class="chicklets ypEmail" href="mailto:' + mpListing.email + '?subject=' + resourceEmailSubject + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|email_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'email\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" rel="nofollow">' + resourceEmail + '</a></div>';
        }
        description += '<div class="saveLink ypgMMBLinks"><a class="chicklets ypSaveShare" href="javascript: openWin(\'' + mpListing.agendizeURLs.SAVE_SHARE.href  + '\', \'490\', \'485\', \'no\');" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|save_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'save\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" rel="nofollow" >' + mpListing.agendizeURLs.SAVE_SHARE.content + '</a></div>';

        if(mpListing.hsText != null && mpListing.hsText != ""){
        description += '<div class="ypgMMBhsText">' + mpListing.hsText +'</div>';
		}
		
        var prodCount = 0;
        var tProducts = "", gProducts = "";
        for(var key in mpListing.tabURLs) {
        	if(key != "map" && key != "eco") prodCount++;
        	tProducts += key + " ";
        }
        if(debug)console.log("mmb: Products [TAB]: [%s]", tProducts);
        
        for(var key in mpListing.productURLs) {
        	if(key != "eco") prodCount++;
        	gProducts += key + " ";
        }
        if(debug)console.log("mmb: Products [General]: [%s]", gProducts);

		if(debug)console.log("mmb: prodCount:", prodCount);
        //if(mpListing.tabURLs != null){        
        if(prodCount > 0){        
	        var divider = '<span> | </span>';
			var notFirst = false;
	        description += '<div class="adCluster ypgMMBLinks">';
	                
	        if(mpListing.tabURLs.dspad != null){
	            description += (notFirst ? divider : "") + '<a href="' + mpListing.tabURLs.dspad.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|information_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'information\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank" rel="nofollow" title="' + mpListing.tabURLs.dspad.title + '">' + mpListing.tabURLs.dspad.content + '</a>';
	            notFirst = true;
	        }
	        if(mpListing.tabURLs.video != null){
	            description += (notFirst ? divider : "") + '<a href="' + mpListing.tabURLs.video.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|video_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'camera_ico\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank" rel="nofollow">' + mpListing.tabURLs.video.content + '</a>';
	            notFirst = true;
	        }
	        if(mpListing.tabURLs.photos != null){
	            description += (notFirst ? divider : "") + '<a href="' + mpListing.tabURLs.photos.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|photos_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'photo_ico\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank" rel="nofollow">' + mpListing.tabURLs.photos.content + '</a>';
	            notFirst = true;
	        }
	        if(mpListing.tabURLs.promo != null){
	            description += (notFirst ? divider : "") + '<a href="' + mpListing.tabURLs.promo.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|promotion_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'promotion\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank" rel="nofollow" title="' + mpListing.tabURLs.promo.title + '">' + mpListing.tabURLs.promo.content + '</a>';
	            notFirst = true;
	        }
	        if(mpListing.tabURLs.coupon != null){
	            description += (notFirst ? divider : "") + '<a href="' + mpListing.tabURLs.coupon.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|coupons_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'coupons\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank" rel="nofollow" title="' + mpListing.tabURLs.coupon.title + '">' + mpListing.tabURLs.coupon.content + '</a>';
	            notFirst = true;
	        }
	        if(mpListing.tabURLs.menu != null){
	            description += (notFirst ? divider : "") + '<a href="' + mpListing.tabURLs.menu.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|menu_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'menu\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank" rel="nofollow" title="' + mpListing.tabURLs.menu.title + '">' + mpListing.tabURLs.menu.content + '</a>';
	            notFirst = true;
	        }
	        if(mpListing.tabURLs.trader != null){
	            description += (notFirst ? divider : "") + '<a href="' + mpListing.tabURLs.trader.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|trader_link_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'trader\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank" rel="nofollow">' + mpListing.tabURLs.trader.content + '</a>';
	            notFirst = true;
	        }
	        
	        if(mpListing.productURLs.profile != null){
	            description += (notFirst ? divider : "") + '<a href="' + mpListing.productURLs.profile.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|profile_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'profile\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank" rel="nofollow">' + mpListing.productURLs.profile.content + '</a>';
	            notFirst = true;
	        }
	        if(mpListing.productURLs.hotellink != null){
	            description += (notFirst ? divider : "") + '<a href="' + mpListing.productURLs.hotellink.href + '" onmousedown="_hbSet(\'cv.c2\',\'' + mpListing.reportingId + '_' +  mpListing.listingType + '|check_rates_' + hbxWhat + '\');_hbSet(\'cv.c3\',\'' + catDirList.join(',') + '\');_hbSet(\'lid\',\'check_rates\');_hbSet(\'lpos\',\'in_bubble\');_hbSend();" target="_blank" rel="nofollow">' + mpListing.productURLs.hotellink.content + '</a>';
	            notFirst = true;
	        }
	        description += '</div>';  //tabUrls
        }

        description += '</div>';  //popupRight
		description += '<div class="clearboth"></div>';
		description += '</div>';  //ypgMerchantMiniBubbleInner
        description += '</div>';  //ypgMerchantMiniBubble

        /* This div with clear:both needed for IE8 to push ypgBottomRoundedRow to next row.  Not needed for other browsers. Did not help for IE6.
		   &nbsp; added as content so IE6 doesn't swallow up .ypgBottomRoundedRow.  All other browsers rendered correctly.
		   But, the &nbsp added a row with real height for all browswers
		   Added font-size: 0px; to remove the height caused by the &nbsp content.  Worked in IE6 but a small vertical gap still remained for IE8.
		   Added line-height: 0px; removes small vertical gap in IE8 (IE8 correct again), but in IE6 it triggers .ypgMerchantMiniBubbleInner to become completely transparent!!
		*/
		if(browserManager.BrowserName == 'msie') {
			if(browserManager.BrowserVersion > 6.0) {
				description += '<div class="clearboth"></div>'; /* IE8 pushes ypgBottomRoundedRow to next line.  IE6 still swallowed ypgBottomRoundedRow up.*/
			} else if (browserManager.BrowserVersion < 7.0) {
				description += '<div class="clearboth" style="font-size: 0px;">&nbsp;</div>'; /* the extra vertical height is removed for IE6... but in IE8 some vertical height still remained */
			}
		}
		
		//description += '<div class="clearboth"></div>'; /* IE8 pushes ypgBottomRoundedRow to next line.  IE6 still swallowed ypgBottomRoundedRow up.*/
		//description += '<div class="clearboth">&nbsp;</div>'; /* This finally pushes ypgBottomRoundedRow to next line in IE6.  But creates unwanted row height! */
		//description += '<div class="clearboth" style="font-size: 0px;">&nbsp;</div>'; /* the extra vertical height is removed for IE6... but in IE8 some vertical height still remained */
		//description += '<div class="clearboth" style="font-size: 0px; line-height: 0px;">&nbsp;</div>'; /* the remaining vertical height disappeared in IE8 but in IE6 it triggered .ypgMerchantMiniBubbleInner to become completely transparent!! */

        description += '<div class="ypgBottomRoundedRow ' + ecoCornerClass + '">';
        description += '<div class="bl"></div>';
        description += '<div class="bm ' + ecoClass + '"></div>';
        var brClass = (mpListing.tabURLs.eco != undefined) ? 'br ecoCornerIconType' : 'br';
        description += '<div class="' + brClass + '"></div>';
        description += '</div>'; // ypgTopRoundedRow
        
        description += '</div>';  // ypgMerchantMiniBubbleWrapper - Overall container for MMB edges and corners

        return description;        
    }

    function GetMPDataForMP(listingId, keyword, location, lat, lon, cli)
    {
//        var qString = "?lid=" + listingId + "&what=" + keyword + "&where=" + location + "&lat=" + lat + "&lon=" + lon + "&dist=10"; 
        var qString = "?listId=" + listingId + "&what=" + keyword + "&where=" + location + "&lat=" + lat + "&lon=" + lon + "&dist=10" + "&cli=" + cli; 


		//ShowLoading();
        // Make call to get data to build up mini merchant bubble
        var request = new AjaxRequest("/ajax/merchant.html" + qString, ProcessFullMerchant);
        request.Execute();
    }

    /**
     * Call back function for Merchant Page
     */
	function ProcessFullMerchant(rText)
	{
	    try {
	        YPSearchManager.g_FullMPSelectedData = eval('(' + rText + ')');  //Other functions are referencing this global directly

	        //HideLoading();
            AddLocationPinToMap();
            
            //Center the pin after it's on the map.  This is not really necessary as orginal map requested already at this lat/lon.
            //var currentListing = YPSearchManager.g_FullMPSelectedData;
            //mapManager.Map.SetCenter(new VELatLong(currentListing.listing.address.location.latitude, currentListing.listing.address.location.longitude));
	    }
	    catch(e)
	    {
	        alert(e.message);
	    }
	}
   
    function GetMPData(shapeId, listingIndex)
    {
    	mpShapeId = shapeId;
    
        if(mpShapeId == -1)
        	mpShapeId = g_listingShapeMap[listingIndex];
        	    	
    	if(listingIndex == null)
    	{
    		//use shapeId to get shape object to get description to get embedded listingIndex
    		var shape = mapManager.Map.GetShapeByID(mpShapeId);
    		if(shape._customIcon != undefined) {
				var curCustomIconClass = shape._customIcon.match(/class=(["'])?(\w+)\1/)[2];
				if (curCustomIconClass.match(/^pin_wf|pin_v_wf|pin_nonad|pin_v_nonad/i) != null) {
					var keyInSpan = shape.GetDescription();
					
					var imKey = InfoBoxManager.StripSpan(keyInSpan);
					if (InfoBoxManager.IsFormattedKey(imKey)) {
						var fields=imKey.split('||');
						var type = fields[0];
						listingIndex = parseInt(fields[1]);
                    }
				}
			}
    	}
        var currentListing = g_sResult.businessList[listingIndex];
        // Save away the listing id into lookup object that's referred to when the pins are redrawn
        visitedListings[currentListing.listingId] = 1;
        if(debug)console.log("YPSM.GetMPData paneNumber: ", paneNumber);
        var location = ClientCache.Retrieve('pane_' + paneNumber + '_EnteredLocationInput').cleanse();
        var keyword = ClientCache.Retrieve('pane_'+paneNumber+'_NameInput').cleanse();        

        var qString = "?listId=" + currentListing.listingId + "&what=" + keyword + "&where=" + location + "&lat=" + currentListing.address.location.latitude + "&lon=" + currentListing.address.location.longitude + "&le=" + currentListing.relevantEntryKeys + "&dist=10"; 

		ShowLoading();
        // Make call to get data to build up mini merchant bubble
        var request = new AjaxRequest("/ajax/merchant.html" + qString, ProcessMiniMerchant);
        request.Execute();
    }

    /**
     * Call back function on YellowPages business listing search
     */
	function ProcessMiniMerchant(rText)
	{
	    try {
	        g_MPResult = eval('(' + rText + ')');  //Other functions are referencing this global directly

	        HideLoading();

            //var shape = mapManager.Map.GetShapeByID(g_listingShapeMap[listingIndex]);
            //ShowMiniMerchantBubble(g_listingShapeMap[listingIndex]);
            //alert('In call back.  Finished processing mini merchant data for shapeId: ' + mpShapeId);
	        ShowMiniMerchantBubble(mpShapeId);
	    }
	    catch(e)
	    {
	        alert(e.message);
	    }
	}

    /**
     * Generate the contents of the on hover ERO
     *
     * @return the contents of the on hover ERO
     */
    function GenerateOnHoverDescription(listingIndex,poiType)
    {
        var currentListing = g_sResult.businessList[listingIndex];
        if(poiType == 100) {
        	var hbxPinType = 'num_icon'
        } else if(poiType == 101) {
        	var hbxPinType = 'dot_icon'
        }
        var description = '<a href="#" onmousedown="_hbSet(\'lid\',\'' + hbxPinType + '\');_hbSet(\'lpos\',\'imap_sr\');_hbSend();" onclick="javascript:YPSearchManager.GetMPData(-1, ' + listingIndex + ');return false;">' + currentListing.name + '</a>';
        //return ('<a href="' + currentListing.merchantURL.href + '" target="_blank">' + currentListing.name + '</a><br />');
        return description;
    }

    /**
     * Generate the location name included in the cluster dialog which shows clustered listings
     *
     * @return the location name included in the description
     */
    function GenerateName(listingIndex,poiType)
    {
        var currentListing = g_sResult.businessList[listingIndex];
        return ('<strong>' + currentListing.name + '</strong>');
        return description;
    }

    
    /**
     * Generate the location address included in the description for popup
     *
     * @return the location address included in the description
     */
    function GenerateAddress(listingIndex,poiType)
    {
        var currentListing = g_sResult.businessList[listingIndex];
        return (currentListing.address.street);
    }    

    /**
     * Generate the location phone number included in the description for popup
     *
     * @return the location phone number included in the description
     */
    function GeneratePhone(listingIndex,poiType)
    {
        var currentListing = g_sResult.businessList[listingIndex];
        return (currentListing.phone);
    } 

    
    /**
     * Generate the location image included in the description for popup
     *
     * @param (int) poiType - type of poi
     * @param poiIndex - index of the specific poi
     *
     * @return the location image included in the description
     */
    function GenerateImage(listingIndex, poiType)
    {
        var currentListing = g_sResult.businessList[listingIndex];
        var listingImg = GetIcon(currentListing.pushpinType, currentListing.listingId);
        return (listingImg = '<img class="png clusterPinPos' + currentListing.pushpinType + '" src="/images/shared/map/' + listingImg + '"></img>');
    }

    /**
     * Call back function on YellowPages business listing search
     */
    function ProcessResult(rText)
    {
        //try {
            YPSearchManager.ClearFind();
            g_sResult = eval('(' + rText + ')');

            //make an HBX event call for new business searches
            /*TEMP
            if(g_sResult != null && g_sResult.CurrentPage == 1)
            {
                var locationSearched = ((ClientCache.Retrieve('lastSearch') == 'bus') ? document.getElementById('txtBusLocation').value : document.getElementById('txtPersonLocation').value);
                hbxSearch('business', g_sResult.BusinessList.length, g_sResult.Keyword, locationSearched);
            } */
            
            // Save in cache
            //NA ClientCache.Save('resultPageNum', g_sResult.CurrentPage);
            
            // Update Result summary
            UpdateSummaryHeading();
            //NA UpdateSummaryNav("g_Goto");
            //NA UpdateSummaryNav("g_Goto_top"); //the duplicated paging section at the top.
            
            /*NA this looks like its used for left hand accordian content - but maybe its content for InfoBoxManager */
            // Populate table with search results
            var fullTable = document.getElementById(ClientCache.Retrieve("g_FullTable"));
            var shortTable = document.getElementById(ClientCache.Retrieve("g_ShortTable"));

            if (fullTable != null)
            {
                var tblBody = fullTable.tBodies ? fullTable.tBodies[0] : 0;
                if (!tblBody)
                {
                    tblBody = document.createElement("TBODY");
                    fullTable.appendChild(tblBody);
                }
                var shortTblBody = null;
                if (shortTable != null) 
                {
                    shortTblBody = shortTable.tBodies ? shortTable.tBodies[0] : 0;
                    if (!shortTblBody)
                    {
                        shortTblBody = document.createElement("TBODY");
                        shortTable.appendChild(shortTblBody);
                    }
                    ShowDualResults(g_showDualResults);
                }

                // Empty tables
                var rowSize = fullTable.rows.length;
                for (var x = rowSize - 1; x >= 0; x--)
                {
                    fullTable.deleteRow(x);
                }
                if (shortTable != null) 
                {
                    rowSize = shortTable.rows.length;
                    for (var x = rowSize - 1; x >= 0; x--)
                    {
                        shortTable.deleteRow(x);
                    }
                }
            }
            InfoBoxManager.ClearDescriptions('Listing');

            // ADD PUSHPINS TO MAP
            // Reverse order pins are added (so higher listing pins are not covered)
            for (var x = g_sResult.businessList.length - 1; x >= 0; x--) {
                AddListingPinToMap(g_sResult.businessList[x]);
            }
            
            /* Not sure what is meant by dual results, but PopulateListing lookes like it adds listing entries to side pannel
            if (g_showDualResults)
            {
                for (var x = 0; x < g_sResult.BusinessList.length && x < dualResultShortTableSize; x++)
                {
                    var newRow = shortTblBody.insertRow(-1);
                    PopulateListing(newRow, g_sResult.BusinessList[x], x);
                }
            }*/
            
            // ADD LISTINGS TO SIDE PANNEL
            /*NA if(fullTable != null){
                var listingForRecommend = null;
                for (var x = 0; x < g_sResult.BusinessList.length; x++){
                    var newRow = tblBody.insertRow(-1);
                    var currentBus = g_sResult.BusinessList[x];
                    PopulateListing(newRow, currentBus, x);

                    // Get listing for "We recommend" search
                    if (listingForRecommend == null && currentBus.DistanceSpecified){
                        listingForRecommend = currentBus;
                    }
                }
            }*/
           
            
            g_navMap = true;
            if(g_navMap) {
                // Center map to the only result
                if(g_sResult.ListingTotal == 1)
                {
                    // Set map view based on first geocoded result
                    m_CenterListing(1);
                }
                /* The call to SetMapView zooms the map out to show all the pins and 
                   this is not good because there could be pins on the outskirts of the
                   radius that are not in the rectangular view port.
                else
                {
                    var locations = new Array();
                    for (var y = 0; y < g_sResult.businessList.length; y++)
                    {
                        var business = g_sResult.businessList[y];
                        //UP if (business.GeoCodeSpecified)
                        if (business.address.location)
                        {
                           locations.push(new VELatLong(business.address.location.latitude, business.address.location.longitude));
                        }
                    }
                    if (locations.length > 0) {
                        mapManager.Map.SetMapView(locations);
                    }
                }
                */
            }
            
            //reset the scroll bar to the top
            //?? var panel = document.getElementById('content' + ClientCache.Retrieve("g_ReusePane"));
            //?? panel.scrollTop = 0;
            //TEMP POIManager.RefreshPOIs();
            //NA mapManager.resizeLeftDiv();
            //NA AjaxControlManager.OpenCloseLeftNavAccordion();
            searchingLock = null;

            HideLoading();
            return;
        //}
        //catch (e)
        //{
        //}
    }

    /**
     * Dual result (show full business listing or the dual results)
     * 
     * @param showDual (bool) true to show dual result
     */
    function ShowDualResults(showDual)
    {
        var summary = document.getElementById(ClientCache.Retrieve("g_Summary"));
        var fullBus = document.getElementById(ClientCache.Retrieve("g_FullBus"));
        var shortBus = document.getElementById(ClientCache.Retrieve("g_ShortBus"));
        var gotoDiv = document.getElementById(ClientCache.Retrieve("g_Goto"));
        var gotoTopDiv = document.getElementById(ClientCache.Retrieve("g_Goto_top"));
        var locations = document.getElementById(ClientCache.Retrieve("g_Locations"));
        var dual = document.getElementById(ClientCache.Retrieve("g_Dual"));
        var dualControl = document.getElementById(ClientCache.Retrieve("g_DualControl"));

        fullBus.style.display = (showDual ? 'none' : '');
        gotoDiv.style.display = (showDual ? 'none' : '');
        gotoTopDiv.style.display = (showDual ? 'none' : '');
        summary.style.display = (showDual ? 'none' : '');
        
        // Visible for dual results
        dual.style.display = ''; //(showDual ? '' : 'none');
        shortBus.style.display = (showDual ? '' : 'none');
        locations.style.display = (showDual ? '' : 'none');
        dualControl.style.display = (showDual ? '' : 'none');
    }

    /**
     * Helper function to populate search result summary
     */
    function UpdateSummaryHeading() {
        var summary = document.getElementById(ClientCache.Retrieve("g_Summary"));
        if (summary == null) return;
        var prevCount = summary.childNodes.length;
        for (var x = prevCount - 1; x >= 0; x--)
        {
            summary.removeChild(summary.childNodes[x]);
        }
        // eg. Results for <strong> bikes </strong>near <strong>325 Milner</strong> :
        var pNode = document.createElement('div');
        pNode.style.marginLeft = '15px';

        // get last search location from client cache
        var locn = ClientCache.Retrieve('pane_' + paneNumber + '_EnteredLocationInput');
        //var locn = ClientCache.Retrieve('lastSearch_location');
        // use location search field if last search location variable null in client cache
        if(locn == undefined){
            var locationBox = ((ClientCache.Retrieve('lastSearch') == 'bus') ? document.getElementById('txtBusLocation') : document.getElementById('txtPersonLocation'));
            //UP locn = locationBox == null ? g_sResult.Location : locationBox.value;
            locn = locationBox == null ? g_sResult.where : locationBox.value;
        }
        
        //UP if (g_sResult.ListingTotal == 0)
        if (g_sResult.listingTotal == 0)
        {
            var noResultText = "";
            if (mapManager.GetIsCategorySearch() != undefined && mapManager.GetIsCategorySearch()) {
                //UP noResultText = String.format(resourceElementNoResultsCategory, g_sResult.Keyword, locn);
                noResultText = String.format(resourceElementNoResultsCategory, g_sResult.what, locn);
                
                mapManager.SetCategorySearch(false); //reset the category search value
            }
            else {
                noResultText = String.format(resourceElementNoResults, g_sResult.what, locn);
            }
            var element = document.createElement("span");
            element.innerHTML = noResultText;
            pNode.appendChild(element);
            summary.style.color = "red";
            summary.style.fontWeight = "bold";
            summary.style.fontSize = "12px";
            summary.appendChild(pNode);
            ClientCache.Save('lastSearchFailed', 'true');
            return;
        }
        summary.style.color = "";
        summary.style.fontWeight = "";
        summary.style.fontSize = "";

        //pNode.appendChild(document.createTextNode( resourceResultsFor.unescapeHTML() + ' ')); //FF OK, IE8 not unescaping
        var textElement = document.createElement("span");
        textElement.innerHTML = resourceResultsFor + " ";
        pNode.appendChild(textElement);
        
        var keyNode = document.createElement('strong');
        // get last search keyword from client cache
        var keyn = ClientCache.Retrieve('pane_' + paneNumber + '_NameInput');
        // use keyword g_sResult variable if last search keyword variable null in client cache
        if(keyn == undefined)
            keyn == g_sResult.what
            //UP keyn == g_sResult.Keyword
        
        keyNode.appendChild(document.createTextNode(keyn));
        pNode.appendChild(keyNode);
        //pNode.appendChild(document.createTextNode(' ' + resourceNear + ' '));
        pNode.appendChild(document.createTextNode(', '));
        var locNode = document.createElement('strong');
        
        locNode.appendChild(document.createTextNode(locn));
        pNode.appendChild(locNode);
        //pNode.appendChild(document.createTextNode(' :'));
        summary.appendChild(pNode);
        
        /*NA
        // eg. 1 - 5 of 45
        pNode = document.createElement('div');
        pNode.style.marginLeft = '15px';
        pNode.appendChild(document.createTextNode(g_sResult.FirstListing + ' - ' + g_sResult.LastListing + ' ' + resourceOf + ' ' + g_sResult.ListingTotal));
        summary.appendChild(pNode);
        */
    }

    /**
     * Update the page navigator for YP business listing
     */
    function UpdateSummaryNav(key)
    {
        var summary = document.getElementById(ClientCache.Retrieve(key));  
        if (summary == null) return;
        // Determine Pane to reuse on re-search
        var reusePaneNumber = ClientCache.Retrieve("g_ReusePane");
        var prevCount = summary.childNodes.length;
        for (var x = prevCount - 1; x >= 0; x--)
        {
            summary.removeChild(summary.childNodes[x]);
        }

        if (g_sResult.ListingTotal == 0)
        {
            return;
        }
        summary.appendChild(document.createTextNode(resourceGoToPage + " : "));
        
        var curPage = g_sResult.CurrentPage;
        var totPage = g_sResult.PageCount;
        var smaller = false;
        var greater = false;
        var halfRange = 2;
        var lowRange = (curPage - halfRange > 0) ? curPage - halfRange : 1;
        var highRange = (curPage + halfRange > totPage) ? totPage : curPage + halfRange;
        // Extend upper range if lower is not used up
        if (curPage - lowRange < halfRange) {
            highRange = highRange + (halfRange - curPage + lowRange);
            highRange = (highRange > totPage) ? totPage : highRange;
        } 
        // Extend lower range if higher is not used up
        if (highRange - curPage < halfRange) {
            lowRange = lowRange - (halfRange - highRange + curPage);
            lowRange = (lowRange < 1) ? 1 : lowRange;
        } 
        for (var x = 1; x <= totPage; x++)
        {
            // Skip pages if too many
            if ((x < lowRange || x > highRange) && (x != 1 && x != totPage)) {
                if (x < curPage)
                {
                    if (!smaller)
                    {  
                        summary.appendChild(document.createTextNode('... '));
                    }
                    smaller = true;
                    continue;
                } else if (x > curPage)
                {
                    if (!greater) {          
                        summary.appendChild(document.createTextNode('... '));
                    }
                    greater = true;
                    continue;
                }
            }
            var node;
            if (x == curPage) {
                 node = document.createElement('strong');
                 node.appendChild(document.createTextNode(x));
                 summary.appendChild(node);
                 summary.appendChild(document.createTextNode(' '));
                 continue;
            }
            
            node = document.createElement('span');
            node.className = 'listingunderlined';
            node.onclick = new Function('YPSearchManager.ReSearch(' + x + ',' + reusePaneNumber + ');');
            node.appendChild(document.createTextNode(x));
            summary.appendChild(node);
            summary.appendChild(document.createTextNode(' '));
        }
        if (totPage > 1 && curPage != totPage)
        {
            node = document.createElement('span');
            node.className = 'listingunderlined';
            node.onclick = new Function('YPSearchManager.ReSearch(' + (curPage + 1) + ',' + reusePaneNumber + ');');
            node.appendChild(document.createTextNode(resourceNext + ' >'));
            summary.appendChild(node);
        }
    }

    /**
     * Generates an entry of listing result for specific bussiness listing
     *
     * @param newRow (table row) - row in html table for attaching elements
     * @param currentListing (JSON - YPBussiness)
     * @param index (int) 
     */
    function PopulateListing(newRow, currentListing, index)
    {
        var newCell0 = newRow.insertCell(0);
        newCell0.className = 'listingbackground';
        if (index == 0)
        {
            newCell0.style.background = '';
        }
        
        var cellDiv = document.createElement('div');
        newCell0.appendChild(cellDiv);
        
        var dart = document.createElement('div');
        dart.className = 'dartweb handicon';
        cellDiv.appendChild(dart);
        
        // Do not show dart or index for non-geocoded listings
        if (!currentListing.GeoCodeSpecified)
        {
                dart.className = 'FloatLeft';
        } 
        else 
        {
            var dartIndex = document.createElement('div');
            var listIndex = currentListing.Index;
            if (listIndex < 10) {
                dartIndex.className = 'pinIndex_single';
            } else if (listIndex < 100) {
                dartIndex.className = 'pinIndex_double';
            } else {
                dartIndex.className = 'pinIndex_triple';
            }
            dartIndex.appendChild(document.createTextNode(listIndex));
            dart.appendChild(dartIndex);
        }
        
        if (currentListing.DistanceSpecified)
        {
           var distanceNode = document.createElement('div');
           distanceNode.className = 'distance';
           distanceNode.appendChild(document.createTextNode(currentListing.Distance + ' km'));
           dart.appendChild(distanceNode);
        }
        
        var contentNode = document.createElement('div');
        contentNode.className = 'listingcontent';
        var pNode = document.createElement('div');
        contentNode.appendChild(pNode);
        var spanNode = document.createElement('span');
        if (currentListing.GeoCodeSpecified)
        {
            spanNode.className = 'listingtitle';
        }
        spanNode.onclick = new Function('YPSearchManager.CenterListing(' + currentListing.Index + ');');
        spanNode.appendChild(document.createTextNode(currentListing.Name));
        dart.onclick = new Function('YPSearchManager.CenterListing(' + currentListing.Index + ');');
        pNode.appendChild(spanNode);
        pNode.appendChild(document.createElement('br'));
        pNode.appendChild(document.createTextNode(currentListing.Phone));
        var aNode = document.createElement('div');
        aNode.innerHTML = currentListing.AddressHtml;
        pNode.appendChild(aNode);
        
        cellDiv.appendChild(contentNode);
    }

    /**
     * Add pin to map for current listing
     * 
     * @param currentListing (JSON - YPBusiness)
     *
     * returns the shape id of the added push pin
     */
    function AddListingPinToMap(currentListing)
    {
        //UP if (!currentListing.GeoCodeSpecified)
        if (!currentListing.address.location)
        {
            return;
        }
        
        //var yellowDart = (currentListing.PushpinType == 'YellowDart');
        var yellowDart = true;
        var divHeight = (yellowDart ? "318px" : "170px");
        var topMargin = (yellowDart ? "15px" : "8px");
        // listing is a person if ListingDetails url contains 'www.canada411.ca'
        //UP var listingType = ((currentListing.ListingDetails.search('www.canada411.ca')>0) ? 'per' : 'bus');
        var listingType = 'bus';
        var description = '<div style="height: ' + divHeight + ';margin-top:' + topMargin + ';">';   // Overall
        
        description += '<div class="popupTop">';        // Top
        description += '<div class="popupTopLeft">';    // Top Left
        
        //UP var latLong = new VELatLong(currentListing.Latitude, currentListing.Longitude);
        var latLong = new VELatLong(currentListing.address.location.latitude, currentListing.address.location.longitude);        
        var shape = new VEShape(VEShapeType.Pushpin, latLong);        

/* TEMP: Skip this part of description for now
        if (currentListing.WebURL.length > 0) //DATA
        {
            description += '<div style="font-weight: bold; font: 12px/14px Arial;">';
            description += '<a herf="' + currentListing.WebURL + '">' + currentListing.Name + '</a>';
            description += '</div>';
        } else 
        {
            description += '<div style="font-weight: bold; font: 12px/14px Arial;">';
            description += '<strong>' + currentListing.Name + '</strong>';
            description += '</div>';
        }
*/
        //description += '<br />';
        //UP description += currentListing.Address;

        description += currentListing.name + '<br />';
        description += currentListing.address.street + ", " + currentListing.address.city + ", " + currentListing.address.province + " " + currentListing.address.postalCode;
        description += '<br />';
        description += currentListing.phone; //UP Changed from Phone to phone
        
/* TEMP: Skip composing rest of description for now - just plot darts for now
        // Advertisement Text
        if (yellowDart && currentListing.HSText != null && currentListing.HSText[0] != "")
        {
            // Separator
            description += '<div class="separator" style="margin-top:3px;"></div>';
        
            description += '<div>';
            for (var y = 0; y < currentListing.HSText.length; y++)
            {
                description += '<br />';
                description += currentListing.HSText[y];
            }
            description += '</div>';
        } 
        
        // Yellow Pages link
        // Separator
        description += '<div class="separator" style="margin-top:3px;"></div>';
        // if the listing is a person
        if(listingType == 'per'){
            var openURL = (CurrentLanguage == 'fr') ? 'www.canada411.ca' : 'www.canada411.ca';
            description += '<div style="margin-top:8px; cursor:pointer; font-weight:bolder;" class="listingunderlined" onclick="YPSearchManager.OpenURL(\'' + currentListing.ListingDetails + '\'); ">';
            description += '<img src="Images/YPLogo.gif" align="left"></img>';
            description += '<strong>' + resourceC411SeeMore + '</strong>';
        }
        // if the listing is a business
        else{
            var openURL = (CurrentLanguage == 'fr') ? 'pagesjaunes.ca' : 'www.yellowpages.ca';
            description += '<div style="margin-top:8px; cursor:pointer; font-weight:bolder;" class="listingunderlined" onclick="YPSearchManager.OpenURL(\'http:\/\/' + openURL + currentListing.ListingDetails + '\'); ">';
            description += '<img src="Images/YPLogo.gif" align="left"></img>';
            description += '<strong>' + resourceSeeMore + '</strong>';
        }
        description += '</div>';
        
        description += '</div>';   // top left div
        
        description += '<div class="popupTopRight">';
        // Thumbnail
        if (yellowDart)
        {
            if (currentListing.ThumbnailURLs.length > 0 && currentListing.ThumbnailURLs[0].length > 0)
            {
                description += '<div class="popupThumbnail"><img alt="' + resourceSeeMore + '" src="'+ currentListing.ThumbnailURLs[0] + ' " onclick="YPSearchManager.OpenURL(\'http:\/\/' + openURL + currentListing.ListingDetails + '\'); "> </img></div>';
            }
        }
        
        // Action area
        description += '<div id=\"A_ACTION_' + currentListing.Index + '\" class="popupActionArea" style="top: ' + (yellowDart? '120px' : '10px') + ';">';
        
        // Empty (Action)
        description += '<div id=\"A_EMPTY_' + currentListing.Index + '\" style="height:130px; width:100px;"></div>';
        
        // To Here (Action)
        description += '<div id=\"A_TO_' + currentListing.Index + '\" style="height:130px;display:none;"><div class="popupHeader"><strong>' + resourceDD + ':</strong></div><br/>';
        description += '<div>' + resourceToHere + ':</div>';
        description += '<input type="text" id="toAddress' + currentListing.Index + '" style="width:158px;" onkeydown="ExecuteFindFromInput(\'imgTo' + (currentListing.Index) + '\', event);"/><br/>';
                
        description += '<div><img id="imgTo' + (currentListing.Index) + '" src="'+ images + 'GetDD.gif" class="popupLink" style="left:100px; float: right;" onclick="YPSearchManager.GDDForListingPopup(\'TO\', ' + (currentListing.Index)  + ');" /></div>';
        description += '</div>';
        
        // From Here (Action)
        description += '<div id=\"A_FROM_' + currentListing.Index + '\" style="height:130px;display:none;"><div class="popupHeader"><strong>' + resourceDD + ': </strong></div><br/>';
        description += '<div>'+ resourceFromHere +':</div>';
        description += '<input type="text" id="fromAddress' + currentListing.Index + '" style="width:158px;" onkeydown="ExecuteFindFromInput(\'imgFrom' + (currentListing.Index) + '\', event);"/><br/>';
        
        description += '<div><img id="imgFrom' + (currentListing.Index) + '" src="'+ images + 'GetDD.gif" class="popupLink" style="left:100px; float: right;" onclick="YPSearchManager.GDDForListingPopup(\'FROM\', ' + (currentListing.Index)  + ');"/></div>';
        description += '</div>';

        // What's near (Action)
        description += '<div id=\"A_NEAR_' + currentListing.Index + '\" style="height:130px;display:none;"><div class="popupHeader"><strong>' + resourceWhatsNearby + ': </strong></div><br/>';
        description += '<div class="popupSubheader">' + resourceSearchForCategory + ':<br/></div>';
        description += '<input type="text" id="nearby' + currentListing.Index + '" style="width:158px;" onkeydown="ExecuteFindFromInput(\'imgNear' + (currentListing.Index) + '\', event);"/><br/>';
        
        description += '<div style="float:left; width:110px">' + resourceWhatsNearbyExample + '</div>';
        description += '<div><img id="imgNear' + (currentListing.Index) + '" src="'+ images + 'GetDD.gif" class="popupLink" style="left:100px; float: right; margin-top:11px; " onclick="YPSearchManager.GNBForListingPopup(' + (currentListing.Index)  + 
        ',\'' + currentListing.Name + '\',\''+ currentListing.Address + '\',\'' + currentListing.Phone + '\');"/></div>';
        description += '</div>';
        
        // Save to a Map (Action)
        var dartImg = (yellowDart ? "dartweb.gif" : "dartwebwhitegrey.gif");
        description += '<div id=\"A_MAP_' + currentListing.Index + '\" style="height:130px;display:none;">';
        
        description += '<div id=\"A_MAP_SAVE_' + currentListing.Index + '\" style="display:none;">';
        description += '<div style="float:left;">';
        description += '<div class="popupHeader" style="width:110px"><strong>' + resourceSaveToAMap + ': </strong></div><br />';
        description += '<div style="width:110px">' + resourceSaveToAMapPrompt + '</div>';
        description += '</div>';
        description += '<div><img src="Images/' + dartImg + '" class="popupLink" style="margin-right:10px; margin-top:10px; float: right; border: 1px solid black;" /></div>';

        description += '<div style="margin-top:10px;">';        
        description += '<select id="mapSelect" style="width:158px;">';
        description += '</select><br/>';
        description += '<div><img id="imgAdd' + (currentListing.Index) + '" src="' + images + 'doneButton.gif" class="popupLink" style="left:100px; float: right;" onclick="YPSearchManager.SaveListingToCustomMap(' + (currentListing.Index)  + ');"/></div>';
        description += '</div>';
        description += '</div>';
        
        description += '<div id=\"A_MAP_WARN_' + currentListing.Index + '\" style="float:left;display:none">';
        description += '<div class="popupHeader" style="width:110px"><strong>' + resourceSaveToAMap + ': </strong></div><br />';
        description += '<div style="width:180px">' + resourceLoginNeeded + '</div>';
        description += '</div>';
        
        description += '</div>';
               
        description += '</div>';   //Action area
        description += '</div>';   // top right
        description += '</div>';   // top div

        // Function bar
        description += '<div class="popupBottom">';
        description += '<table>';
        
        description += '<tr><td><table><td><img src="images/drivingicon.gif" align="left" style="margin-right:3px;margin-left:3px"></img></td>';
        description += '<td>' + resourceDD.toUpperCase();
        description += '<div></div><span class="popupLink popupDrivingFunctionTo" onclick="YPSearchManager.ShowActionDiv(\'A_\', ' + (currentListing.Index) + ', \'FROM\');"><img src="images/tohereicon.gif"><span>' + resourceToHere.toUpperCase() + '</span></img></span> | ';
        description += '<span class="popupLink popupDrivingFunctionFrom" onclick="YPSearchManager.ShowActionDiv(\'A_\', ' + (currentListing.Index) + ', \'TO\');"><img src="images/fromhereicon.gif"><span>' + resourceFromHere.toUpperCase() +'</span></img></span>';
        description += '</td>';  // DD
        
        description += '<td style="width:60px;margin-right:3px;"><span class="popupLink" onclick="YPSearchManager.ShowActionDiv(\'A_\', ' + (currentListing.Index) + ', \'NEAR\');"><img src="images/nearbyicon.gif" align="left" style="margin-right:3px"></img>';
        description += '<span class="popupLink">' + resourceWhatsNearby.toUpperCase() + '</div></span></td>';
        description += '<td style="margin-right:3px; width:70px;"><span class="popupLink" onclick="YPSearchManager.ShowActionDiv(\'A_\', ' + (currentListing.Index) + ', \'MAP\');"><img src="images/savemapicon.gif" align="left" style="margin-right:3px;margin-left:3px"></img>';
        description += resourceAddToAMap.toUpperCase() + '</span></td>';
        //description += '<td><div class="popupLink popupPrint" style="width: 60px; float:left"><img src="images/printicon.gif" style="margin-left:3px;margin-right:3px"></img>';
        //description += resourcePrint.toUpperCase() + '</div></td>';
        description += '</tr></table>';   // Function bar
*/

        description += '</div>';   // REMOVE THIS - added to match up div's for now
        description += '</div>';   // Bottom div
        
        description += '</div>';  // overall
        
        // Add prefix
        description = (yellowDart ? '(B)' : '(S)') + description;
        
        var currentListingIndex = tempIndex++;
        //UP var key = InfoBoxManager.StoreDescription('Listing', currentListing.Index, description);
        var key = InfoBoxManager.StoreDescription('Listing', currentListingIndex, description); //Need to eventually change from currentListingIndex to currentListing.index
        
        shape.SetDescription(key);
        
        //TEMP var cIndex = currentListing.Index;
        var cIndex = currentListingIndex;
        var txtStyle = 'triple';
        if (cIndex < 10)
        {
            txtStyle = 'single';
        }
        else if (cIndex < 100)
        {
            txtStyle = 'double';
        }
        //UP shape.SetCustomIcon("<div class=" + (browserManager.BrowserName == 'msie' && browserManager.BrowserVersion < 7.0 ? 'pin_yellow_ie6' : 'pin_yellow') + "><div class='" + txtStyle + "'>" + (cIndex) + "</div></div>");
        if(currentListing.pushpinType  == 'Ad')
        	shape.SetCustomIcon("<div class=" + 'pin_wf' + "></div>");
        else
        	shape.SetCustomIcon("<div class=" + 'pin_nonad' + "></div>");
        if (!yellowDart)
        {
            shape.SetCustomIcon("<div class='pin_white'><div class='" + txtStyle +"'>"+(cIndex)+"</div></div>");
        }

        mapManager.Map.AddShape(shape);
        g_listingShapeMap[cIndex] = shape.GetID();
    }

    /**
     * Add pin to map for current location
     * 
     * @param index (int) index of location in g_Locations
     * @param veLatLong (VELatLong)
     * @param businessSearch (bool) indicates whether we are doing a business search
     */
    function AddLocationPinToMap(index, location, latitude, longitude, businessSearch)
    {

        //Modifications:  Use info in saved g_GNBSelectedData to generate description that looks like Merchant Mini Bubble and add the pin to the map
        var index = 0; // Always use index 0 for the saved away pin because result data structure starts at index 1 

    	if(isMerchantPage == true)
           	var currentListing = YPSearchManager.g_FullMPSelectedData; //good for g_FullMPSelectedData.  if used this.g_FullMPSelectedData when being parsed then can not get at it via no prefix or with "this" prefix.
        else
            var currentListing = YPSearchManager.g_GNBSelectedData;
        
        var description = YPSearchManager.GenerateDescription(index,100,currentListing);

/*
        //In the case of "Quebec City [Quebec], Quebec", remove everything in the square bracket and the space before it
        location = location.replace(/ \[(.)*\]/, "");
        
        //TEMP printManager.setPrintPage("singleLocation", location);
        
*/

        var shape = new VEShape(VEShapeType.Pushpin, new VELatLong(currentListing.listing.address.location.latitude, currentListing.listing.address.location.longitude));         

        var key = InfoBoxManager.StoreDescription('Location', index, description);
        
        shape.SetDescription(key + '<strong>' + currentListing.listing.name + '</strong>');

        //UP shape.SetCustomIcon("<div class='pin_blue'></div>");
        if(currentListing.listing.pushpinType  == 'Ad') {
            if(isMerchantPage == true)
                shape.SetCustomIcon("<div class=" + 'pin_selected' + "></div>");
                //shape.SetCustomIcon("<div class=" + 'pin_star' + "></div>");
            else
        	    //shape.SetCustomIcon("<div class=" + 'pin_v_wf' + "></div>");
        	    shape.SetCustomIcon("<div class=" + 'pin_star' + "></div>");  //Make it stand out
        } else {
            if(isMerchantPage == true)
                shape.SetCustomIcon("<div class=" + 'pin_selected' + "></div>");
        	else
        	    //shape.SetCustomIcon("<div class=" + 'pin_v_nonad' + "></div>");
        	    shape.SetCustomIcon("<div class=" + 'pin_star' + "></div>");  //Make it stand out
        }
                    	
        /*if (pinShapeLayer == null)
        {
            pinShapeLayer = new VEShapeLayer();
            mapManager.Map.AddShapeLayer(pinShapeLayer);
        }
        pinShapeLayer.AddShape(shape);*/

        mapManager.Map.AddShape(shape);
        //On subsequent pan/zoom-> searches... don't want to keep centering the map to this pin
        //mapManager.Map.SetCenter(new VELatLong(latitude, longitude));
        return shape;
    }

    /**
     * Center map on listing
     * 
     * @param listinIndex - the overall index of listing
     */
    function m_CenterListing(listingIndex) {
        if(!g_listingShapeMap)
        {
            return;
        }
        
        if(!g_listingShapeMap[listingIndex])
        {
            return;
        }
        
        /*if (pinShapeLayer == null)
        {
            return;
        }*/

        var shape = mapManager.Map.GetShapeByID(g_listingShapeMap[listingIndex]);
        //var shape = pinShapeLayer.GetShapeByID(g_listingShapeMap[listingIndex]);
        if(!shape)
        {
            return;
        }

        // delete poi shapes from map before zooming out
        POIManager.HidePOIs();
        
        mapManager.Map.SetCenterAndZoom(shape.GetPoints()[0], 14);
        mapManager.Map.SetCenterAndZoom(shape.GetPoints()[0], 5);
        mapManager.Map.SetCenterAndZoom(shape.GetPoints()[0], 14);
        //mapManager.Map.SetCenterAndZoom(shape.GetPoints()[0], map.GetZoomLevel());

        // re-add poi shapes back onto map after zooming back in
        POIManager.RefreshPOIs();
        
        // Display Popup
        HideCurrentEro(null);
        YPSearchManager.ShowPopup(g_listingShapeMap[listingIndex]);
        //YPSearchManager.ShowPopup(shape.GetID());
        //setTimeout('YPSearchManager.ShowPopup("' + shape.GetID() + '")', popupDelay);
    }
    
    function m_ShowPopup(shapeID)
    {
        activeEro=new PushpinERO(shapeID,mapManager.Map);
        activeEro.Show();
    }
    
    /**
     * Returns a new search query object
     * @param searchType - Type of search (bussiness, keyword)
     * @param what - Keyword searched
     * @param where - Location searched
     * @param latLong - Geographical location of first place returned from search
     * @param origin - Origin of route search
     * @param destination - Destination of route search
     */
    this.CreateSearchQuery = function(searchType,what,where,latLong,origin,destination)
    {
        return new SearchQuery(searchType,what,where,latLong,origin,destination);
    }
    
    /**
     * Represents a recent search query
     *
     * @param searchType - Type of search (bussiness, keyword)
     * @param what - Keyword searched
     * @param where - Location searched
     * @param latLong - Geographical location of first place returned from search
     * @param origin - Origin of route search
     * @param destination - Destination of route search
     */
    function SearchQuery(searchType,what,where,latLong,origin,destination)
    {
        this.SearchType=searchType;
        this.What=what;
        this.Where=where;
        this.LatLong=latLong;
        this.Origin=origin;
        this.Destination=destination;

        /**
         * Parses a string into a SearchQuery object
         *
         * @param input - String to parse
         */
        this.Parse = function(input)
        {
            if(input == null)
            {
                return;
            }
            
            var delimiter='|';
            var fields=input.split('|');
            
            if(fields.length == 7)
            {
                this.SearchType = (fields[0] != null ? fields[0] : null);
                this.What = (fields[1] != null && fields[1] != '' ? fields[1] : null);
                this.Where = (fields[2] != null && fields[2] != '' ? fields[2] : null);
                this.LatLong = (fields[3] != null && fields[3] != '' && fields[4] != null && fields[4] != '' ? new VELatLong(fields[3],fields[4]) : null);
                this.Origin = (fields[5] != null && fields[5] != '' ? fields[5] : null);
                this.Destination = (fields[6] != null && fields[6] != '' ? fields[6] : null);
            }
        }
        
        /**
         * Converts this SearchQuery into a string
         */
        this.ToString=function()
        {
            var output='';

            output += this.SearchType != null ? this.SearchType : '';
            output += '|'+(this.What != null ? this.What : '');
            output += '|'+(this.Where != null ? this.Where : '');
            output += '|'+(this.LatLong != null ? this.LatLong.Latitude+'|'+this.LatLong.Longitude : '|');
            output += '|'+(this.Origin != null ? this.Origin : '');
            output += '|'+(this.Destination != null ? this.Destination : '');
            
            return output;
        }
    }

    /**
     * Stores a SearchQuery into a browser cookie
     *
     * @param searchQuery - Query to store
     * @param type - Type of recent search
     */
    this.PersistQuery = function(searchQuery, type) {
        if (searchQuery == null) {
            return;
        }

        // cookie lifetime in days
        var lifeTime = 366;
        var dateTime = new Date();
        dateTime.setTime(dateTime.getTime() + (lifeTime * 24 * 60 * 60 * 1000));

        var queriesCount = 5;
        var pastQueries = m_RetrieveQueries(type);
        var contents = searchQuery.ToString();

        //check for duplicates and remove old entries as required
        if (pastQueries.length > 0) {
            var currentQueries = new Array();

            for (var i = 0; i < pastQueries.length; i++) {
                if (pastQueries[i].ToString().toLowerCase() != contents.toLowerCase() && i < queriesCount - 1) {
                    currentQueries.push(pastQueries[i]);
                }
            }

            pastQueries = currentQueries;
        }

        //persist current list of search queries
        for (var i = 0; i < pastQueries.length; i++) {
            contents += (i <= pastQueries.length - 1) ? '[' : '';
            contents += pastQueries[i].ToString();
        }

        // sets document.cookie name, value, expiration, path
        ClientCache.setClientCookie('search' + type + 'Cookie', contents, dateTime, '/');
    }
    
    /**
     * Retrieves past searches from a client-side cookie
     *
     * @param type - Type of search queries to retrieve
     */
    function m_RetrieveQueries(type)
    {
        if(type == null)
        {
            return;
        }
        

        var queries = new Array();
        var contents = ClientCache.getClientCookieByName('search' + type + 'Cookie');
        //convert the stored values to an array of SearchQuery objects
        if(contents != null)
        {
            var queriesData = contents.split('[');
            
            for(var i=0; i < queriesData.length; i++)
            {
                var query=new SearchQuery();
                query.Parse(queriesData[i]);
                if (query.What != null || (type != 'bus' && type != 'per'))
                    queries.push(query);
            }
        }

        return queries;
    }
    
    /**
     * Determines if page is current in French mode
     */
    function isFrench()
    {
        var qString = window.location.search.substring(1);
        var parts = qString.split("&");
        for (i=0;i<parts.length;i++) {
            ft = parts[i].split("=");
            if (ft[0] == 'lang' && ft[1] == 'fr') {
                return true;
            }
        }
        return false;
    }
    
    function OpenURL(url)
    {
        window.open(url,'mywindow','width=800,height=600,toolbar=yes, location=yes,directories=yes,status=yes,menubar=yes,scrollbars=yes,copyhistory=yes, resizable=yes');
    }
    
    this.EmulateMapFind=function(searchText,paneClicked)
    {
        // Restore Panel number to display
        findMapResultsPaneNumber=paneClicked;
        
        //put back the search text
        document.getElementById('txtFind').value=searchText;
        
        //do the search
        mapManager.FindLookup(true);

    }
    
    this.ClearFind = function(){
        mapManager.ClearFind();
        
        // Clear pins on map
        if((pinShapeLayer != null)&&(this.isGNBForListingPopup == false))
        {
            pinShapeLayer.DeleteAllShapes();
        }
    }
    
    /**
     * Display the specified div for popup
     */
    function ShowActionDiv(prefix, listingIndex, divId) {
        if (divId == 'TO')
        {
            document.getElementById(prefix + 'EMPTY_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'FROM_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'NEAR_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'MAP_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'TO_' + listingIndex).style.display = '';
        }
        else if (divId == 'FROM') {
            document.getElementById(prefix + 'EMPTY_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'TO_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'NEAR_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'MAP_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'FROM_' + listingIndex).style.display = '';
        }
        else if (divId == 'NEAR')
        {
            document.getElementById(prefix + 'EMPTY_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'TO_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'FROM_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'MAP_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'NEAR_' + listingIndex).style.display = '';
        }
        else if (divId == 'MAP')
        {
            document.getElementById(prefix + 'EMPTY_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'TO_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'FROM_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'NEAR_' + listingIndex).style.display = 'none';
            document.getElementById(prefix + 'MAP_' + listingIndex).style.display = '';
            
            // Check for login status
            var HiddenUserId=document.getElementById("HiddenUserId");

            // User is not logged in, show warning message
            if(HiddenUserId.value == null || HiddenUserId.value == '')
            {
                document.getElementById(prefix + 'MAP_WARN_' + listingIndex).style.display = '';
                document.getElementById(prefix + 'MAP_SAVE_' + listingIndex).style.display = 'none';
            }
            // User is logged in, retrieve existing maps
            else
            {
                document.getElementById(prefix + 'MAP_WARN_' + listingIndex).style.display = 'none';
                document.getElementById(prefix + 'MAP_SAVE_' + listingIndex).style.display = '';
                PersistenceManager.LoadUserMaps(PopulateMapSelect);
            }
        }
    }
    
    /**
     * Populate the map select control of "Add to a Map" section of current info box
     *
     * Note: map select control is not id-specific (this assumes only one popup is shown at a time)
     */
    function PopulateMapSelect(responseText)
    {
        try
        {
            //  <option value = "My Map 1">Map 1</option>
            var mapSelector = document.getElementById('mapSelect');
                        
            var prevCount = mapSelector.childNodes.length;
            for (var x = prevCount - 1; x >= 1; x--)
            {
                mapSelector.removeChild(mapSelector.childNodes[x]);
            }
            var mapList = eval('(' + responseText + ')');
            
            if(mapList != undefined && mapList.DataList != null)
            {
                //for each map
                for(var x = 0; x < mapList.DataList.length; x++)
                {
                    var newOption = new Option(mapList.DataList[x].Title, mapList.DataList[x].MapID);
                    mapSelector.options[x] = newOption;
                }
            }
        }
        catch (e)
        {}
    }
    
    /**
     * Perform Driving Directions search with specified input
     */
     function GDDForListingPopup(mode, index)
     {
        var startAddress;
        var endAddress;

        if(isMerchantPage == true) {
	        var currentListing = YPSearchManager.g_FullMPSelectedData.listing;
        } else {
            if(index == 0) {
                var currentListing = YPSearchManager.g_GNBSelectedData.listing;
            } else {        	
                //UP var currentListing = g_sResult.BusinessList[index - g_sResult.FirstListing];
                var currentListing = g_sResult.businessList[index];
            }
        }
        
        if (mode == 'TO')
        {
            endAddress = document.getElementById('toAddress' + index).value;
            //UP endAddress = currentListing.Address + "@" + currentListing.Latitude + "," + currentListing.Longitude;
            startAddress = currentListing.address.street + ", " + currentListing.address.city + ", " + currentListing.address.postalCode + "@" + currentListing.address.location.latitude + "," + currentListing.address.location.longitude;;
            
            if (endAddress.trim() == '') return;
        } 
        else
        {
            startAddress = document.getElementById('fromAddress' + index).value;
            //UP startAddress = currentListing.Address + "@" + currentListing.Latitude + "," + currentListing.Longitude;
            endAddress = currentListing.address.street + ", " + currentListing.address.city + ", " + currentListing.address.postalCode + "@" + currentListing.address.location.latitude + "," + currentListing.address.location.longitude;;
            
            if (startAddress.trim() == '') return;
        }
         
        // Hide current popup 
        HideCurrentEro(null);
        
        //NA TopNav('DrivingDirections');
        document.getElementById("txtFrom").value = startAddress;
        document.getElementById("txtTo").value = endAddress;
        mapManager.GetNewDirections(startAddress,endAddress);
     }
     
     /** 
      * Get 'what's nearby' for popup
      */
     function GNBForListingPopup(index,name,address,phone)
     {
     	//NEW logic only requires the index argument
     	
        //if(debug)console.log("In GNBForListingPopup: Set isGNBForListingPopup to true");
        this.isGNBForListingPopup = true;
        this.ranGNBOnce = false;
        
        /*NA
        GlobalListing.name = name;
        GlobalListing.address = address;
        GlobalListing.phone = phone;
        */
        
        var txtNB = document.getElementById('nearby' + index).value;
        if (txtNB.trim() == '')
        {
            return;
        }
        
        if(isMerchantPage == true) {
	        var currentListing = YPSearchManager.g_FullMPSelectedData.listing;
	        YPSearchManager.g_GNBSelectedData = YPSearchManager.g_FullMPSelectedData;
        } else {
	        //NA var currentListing = g_sResult.businessList[index - g_sResult.FirstListing];
	        //var currentListing = g_sResult.businessList[index];
	        var currentListing = g_MPResult.listing;
	        // Save away "SELECTED" pushpin's entire data structure to a global instead of just name/address/phone
	        //YPSearchManager.g_GNBSelectedData = g_sResult.businessList[index];
	        YPSearchManager.g_GNBSelectedData = g_MPResult;
        }
        
        //document.getElementById('txtBusLocation').value = currentListing.Address;
        document.getElementById('txtBusLocation').value = currentListing.address.street + ", " + currentListing.address.city + ", " + currentListing.address.postalCode;
        
        document.getElementById('txtBusName').value = txtNB;
        if(index == 0)
        {
            mapManager.NewFindBusiness(true);
        }
        else
        {
            mapManager.NewFindBusiness(false);
        }                        
     }

    /**
     * Perform Driving Directions search with specified input from/to specific location
     */
     function GDDForLocationPopup(mode, index) {
        index = index == null ? locationIndex : index;
         
        this.isGNBForListingPopup = true;
        var startAddress;
        var endAddress;
      
        if (g_Locations.length - 1 < index)
        {
            return;
        }
        
        var currentLocation = g_Locations[index];
        if (mode == 'TO') {
            startAddress = document.getElementById('l_toAddress' + index).value;
            endAddress = currentLocation.Name;
            
            if (startAddress.trim() == '')
                return;
        } 
        else
        {
            endAddress = document.getElementById('l_fromAddress' + index).value;
            startAddress = currentLocation.Name;
            
            if (endAddress.trim() == '')
                return;
        }

        // Hide current popup 
        HideCurrentEro(null);
        
        TopNav('DrivingDirections');
        document.getElementById("txtFrom").value = startAddress;
        document.getElementById("txtTo").value = endAddress;
        mapManager.GetNewDirections(startAddress, endAddress);
        this.isGNBForListingPopup = false;
     }
     
     /** 
      * Get 'what's nearby' for specific location
      */
     function GNBForLocationPopup(index) {
        index = index == undefined ? locationIndex : index;
     
        //this.isGNBForListingPopup = true;
        var txtNB = document.getElementById('l_nearby' + index).value;
        if (txtNB.trim() == '')
        {
            return;
        }
        if (g_Locations.length - 1 < index)
        {
            return;
        }
        var currentLocation = g_Locations[index];

        document.getElementById('txtBusLocation').value = (Math.round(currentLocation.LatLong.Latitude*100)/100) + ", " + (Math.round(currentLocation.LatLong.Longitude*100)/100);
        document.getElementById('txtBusName').value = txtNB;
        //Turn on latlong mode if we have index of 0 (it wasn't a business listing)
        if(index == 0)
        {
            mapManager.NewFindBusiness(true);
        }
        else
        {
            mapManager.NewFindBusiness(false);
        }
     }
     
     /**
      * Save Listing Pin to user map
      */
     function SaveListingToCustomMap(pinIndex)
     {
        var currentListing = g_sResult.BusinessList[pinIndex - g_sResult.FirstListing];
        var yellowDart = (currentListing.PushpinType == 'YellowDart');
        var dartImg = (yellowDart ? "dartweb.gif" : "dartwebwhitegrey.gif");
        var mapSelector = document.getElementById('mapSelect');
        var selectedMapId = mapSelector.options[mapSelector.selectedIndex].value;
        
        PersistenceManager.SaveMapLocationDetailed(selectedMapId, currentListing.Latitude, currentListing.Longitude, 
            currentListing.Name, currentListing.Address, 'Images/' + dartImg);
     }
     
     /**
      * Save Location Pin to user map
      */
     function SaveLocationToCustomMap(pinIndex) {
        pinIndex = pinIndex == undefined ? locationIndex : pinIndex;
        var currentLocation = g_Locations[pinIndex];
        var mapSelector = document.getElementById('mapSelect');
        var selectedMapId = mapSelector.options[mapSelector.selectedIndex].value;
        
        PersistenceManager.SaveMapLocationDetailed(selectedMapId, currentLocation.LatLong.Latitude, currentLocation.LatLong.Longitude, 
            currentLocation.Name, (currentLocation.Address == null || currentLocation.Address == undefined ? '' : currentLocation.Address), "Images/dartblue.gif");
     }
     
}
String.prototype.removeWhitespace = function() {
    return this.replace(/^\s+|\s+$/g,"");
}

String.prototype.containsNumbers = function() {
    return /\d/.test(this);
}

String.prototype.removeCommas = function() {
    return this.replace(/,/g,"");
}

String.prototype.cleanse = function() { 
    return this.removeWhitespace().removeCommas().toLowerCase().replace(/ô/g,'o');
}

String.prototype.isSimpleSearchCity = function() {
    if (SimpleSearchCityList == null) return false;
    var cleanTerm = this.cleanse();
    if (cleanTerm == "canada") return false;
    var list = SimpleSearchCityList.split(',');
    for(var i = 0; i < list.length; i++)
    {
        var listItem = list[i].cleanse();
        if (listItem == cleanTerm) return true;
    }
    return false;
}
