﻿var activeEro=null;
var mapChange=false;
var customIconList = new Array("baby.gif", "beer.gif", "book.gif", "buildings.gif", "computer.gif", 
    "construction.gif", "doctor.gif", "event.gif", "food.gif", "golf.gif", "gym.gif",
    "hiker.gif", "home.gif", "mail.gif", "martini.gif", "party.gif", "piano.gif",
    "school.gif", "service.gif", "shopping.gif", "ski.gif", "suitcase.gif", "wedding.gif",
    "xcSki.gif");

/**
 * Custom ERO size enumeration
 */
var EroSize = { Small: 0, Large: 1 };

var zIndex = 1001;

/**
 * Handles mouse events to fire custom ERO functionality
 *
 * @param e - Event object
 */
function MouseHandler(e)
{
    //mouse click handler
    if(e.eventName == "onclick") {
        //The user clicks anywhere on a map. Create a new pin if the flag is set to true
        if(isAddingNewLocation && e.elementID == null) {
            isAddingNewLocation = false; //reset the flag
            //If there's no pushpin at this point, create a new one.                  
            var pixel = new VEPixel(e.mapX, e.mapY);
            var point = mapManager.Map.PixelToLatLong(pixel);
            var shape = new VEShape(VEShapeType.Pushpin, point);
            shape.SetCustomIcon("<div class='pin_personal'></div>");            
            mapManager.Map.AddShape(shape);
            
            var locationContent = {title: "", description: "", latitude: point.Latitude, longitude: point.Longitude,
                lastUpdated: "", shapeID: shape.GetID(), iconURL: ""};
                             
            var des = SetMyLocationDescription("", locationContent);            
            
            totalPersonalPins++;
            var key = InfoBoxManager.StoreDescription('Personal',totalPersonalPins, des);
    
            shape.SetDescription(key);                     
       
            activeEro = new PushpinERO(shape.GetID(), mapManager.Map);
            activeEro.Show();
            SetMapCursor("auto");
            return true;            
        }
        //If the user clicks on a pin, display corresponding information stored in the pushpin
        else if(e.elementID != null && mapManager.Map.GetShapeByID(e.elementID) != null) {
            if(activeEro != null && activeEro.ShapeId != e.elementID) {
                activeEro.Hide();
            }
            else if(activeEro != null && e.elementID == activeEro.ShapeId) {
                return true;
            }

            var shape = mapManager.Map.GetShapeByID(e.elementID);
            //if (shape.GetTitle() != 'cluster' && shape.GetTitle() != 'poi') {
                //var zoomLevel = mapManager.Map.GetZoomLevel();
                // delete poi shapes from map before zooming out
                //TEMP POIManager.HidePOIs();

				/* Don't move the map or zoom to show the Description Info
                mapManager.Map.SetCenterAndZoom(shape.GetPoints()[0], zoomLevel);
                mapManager.Map.SetCenterAndZoom(shape.GetPoints()[0], 5);
                mapManager.Map.SetCenterAndZoom(shape.GetPoints()[0], zoomLevel);
				*/
				
                // re-add poi shapes back onto map after zooming back in
                //TEMP POIManager.RefreshPOIs();
            //}
            
			if(shape._customIcon != undefined) {
			
		        var curCustomIconString = shape._customIcon;
        		if(debug)console.log("MouseHandler: curCustomIconString: %s", curCustomIconString); 
			
				//var curCustomIconClass = shape._customIcon.match(/class=(["'])?(\w+)\s*\1/)[2];
				//var curCustomIconClassArray = shape._customIcon.match(/class=(["'])?([\w\s]*)\1/); //multiple css classes
				//if (curCustomIconClassArray != undefined && curCustomIconClassArray.length > 1) {
				    //var curCustomIconClass = curCustomIconClassArray[2];
				    //if(debug)console.log("MouseHandler: curCustomIconClass: %s", curCustomIconClass); 
				    
				    if (curCustomIconString.match(/pin_wf|pin_v_wf/) != null) {
				    	_hbSet('lid','num_icon');_hbSet('lpos','imap_sr');_hbSend();
				    }
				    if (curCustomIconString.match(/pin_nonad|pin_v_nonad/) != null) {
				    	_hbSet('lid','dot_icon');_hbSet('lpos','imap_sr');_hbSend();
				    }
					if (curCustomIconString.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)) {
	                        //Call YPSearchManager.GetMPData(listingIndex) to initiate AJAX call to get data with a call back to run ShowMiniMerchantBubble -> which calls new PushpinERO  
	                        //description = InfoBoxManager.GetDescription(imKey);
	                                
					        var fields=imKey.split('||');
					        var type = fields[0];
					        var index = parseInt(fields[1]);
	                        var imPattern = new RegExp("imListing", "i");
	                        if (imPattern.test(type)) {
	                            if(debug)console.log("MouseHandler: found an imListing pin"); 
	                        	YPSearchManager.GetMPData(shape.GetID(), index);
	                        } else {
	                            activeEro = new PushpinERO(e.elementID, mapManager.Map);
	                            activeEro.Show();
	                        }
	                        return true;
	                    }
					} else {
						if(debug)console.log("MouseHandler: css class not one of pin_wf|pin_v_wf|pin_nonad|pin_v_nonad"); 
						
						// Merchant page case: pin_selected
						
					    activeEro = new PushpinERO(e.elementID, mapManager.Map);
	                    activeEro.Show();
	                    return true;
					}
				
				//}
            }
            
            //activeEro = new PushpinERO(e.elementID, mapManager.Map);
            //activeEro.Show();
            
            return true;
        }        
    }
}

/**
 * Callback to show the mini merchant bubble
 *
 * @param e - Event object
 */
function ShowMiniMerchantBubble(shapeID)
{
	// Hide already open one
	if(activeEro != null) {
	    activeEro.Hide();
	    activeEro = null;
    }
   	
	activeEro = new PushpinERO(shapeID, mapManager.Map);
	activeEro.Show();
}

/**
 * Zooms in to view the individual pins that make up a cluster
 *
 * @param shape - Clustered pin
 */
function Decluster(shape)
{
    var latLongs = shape.GetDescription().split('|');
    var points = new Array();
    
    for(var i = 0; i < latLongs.length; i++)
    {
        var point = latLongs[i].split(',');
        points.push(new VELatLong(point[0],point[1]));
    }
    
    mapManager.Map.SetMapView(points);
}


    /**
     * Generate the description for popup
     *
     * @return the expanded description
     */
    function GenerateLocationDescription(locationID, locationContent)
    {
        var latlong = new VELatLong(locationContent.latitude, locationContent.longitude);
        var shapeID = locationContent.shapeID;      
        var title = locationContent.title.replace("'", "%27").replace("\"", "%28");    
        var des = locationContent.description.replace("'", "%27").replace("\"", "%28");
   
        
        var lastUpdated = locationContent.lastUpdated;
        var iconURL = locationContent.iconURL;
        
        if (!iconURL || iconURL == "")
        {
            iconURL = "Images/MyLocationPin.gif"; //the default value
        }
        
        var divHeight = "170px";
        var topMargin = "8px";
        var description = '<div style="height: ' + divHeight + ';margin-top:' + topMargin + ';">';   // Overall
        
        description += '<div class="popupTop">';   // Top
        description += '<div class="popupTopLeft">';   // Top Left
        description += '<div style="font-weight: bold; font: 12px/14px Arial;">';
        description += '<strong style="width: 175px; overflow: auto">' + title.replace("%27","'").replace("%28","\"") + '</strong>';
        description += '<br />';      
        description += '<span style="width: 175px; height: overflow: auto">' + des.replace("%27","'").replace("%28","\"") + '</span>';
        description += '</div>';
        description += '</div>';   // top left div
        
        description += '<div class="popupTopRight" style="float: right">';
        
        //Visible top right area: image icon, delete, edit and last updated
        description += '<div class="popupTopRightVisible" style="float: left; width: 140px">';
        
        description += '<div class="popupTopRightLeft" style="width: 130px">';
        if(locationID != "" && !isCurrMapFriends)
        {
            description += '<span class="deleteButton" onclick="PersistenceManager.DeleteMyLocation(\'' + shapeID + '\', \'' + locationID + '\')">' + resourceDelete + '</span> | ';
            description += '<span class="deleteButton" onclick="restorePushPin(\'' + locationID + '\',\'' + shapeID + '\',\'' + title + '\',\''+ des + '\','+ locationContent.latitude + ','+ locationContent.longitude + ',\'' + lastUpdated + '\',\'' + iconURL + '\')">' + editText + '</span><br/>';
        }
        description += "<div class='lastUpdatedClass'>" + resourceLastUpdatedAt + " " + lastUpdated + "</div>";      
        description += '</div>'; //popupTopRightLeft        
        
        //Image icon
        description += '<div class="popupRightRight" style="float: right; position: absolute; top: 0px; left: 300px">';        
        description += '<div style="display:block;margin-top:5px; margin-bottom:5px;"><img style="border:1px solid black;" src="' + iconURL + '"></img>';
        description += '<br/><div class="popupChangeIcon" onClick="ShowSelectCustomPins(\'' + locationID + '\',\'' + shapeID + '\',\'' + title + '\',\'' + des + '\',' + locationContent.latitude + ','+ locationContent.longitude + ',\'' + lastUpdated + '\',\'' + iconURL + '\')">' + resourceChange + '</div></div>';
        description += '</div>';
        
        description += '</div>'; //popupTopRightVisible
        
        // Action area
        description += '<div id=\"AP_ACTION_' + locationID + '\" class="popupActionArea" style="height:50px;top:60px; margin-left: ';
        if(browserManager.BrowserName == "msie")
        {
            description += '-140px">';
        }
        else
        {
            description += '0px">';
        }
        
        // Empty (Action)
        description += '<div id=\"AP_EMPTY_' + locationID + '\" style="height:70px; width:100px;"></div>';
        
        // To Here (Action)
        description += '<div id=\"AP_TO_' + locationID + '\" style="height:70px;display:none;"><div class="popupHeader"><strong>' + resourceDD + ':</strong></div>';
        description += resourceToHere + ':<br/>';
        description += '<input type="text" id="p_toAddress' + locationID + '" style="width:158px;" onkeydown="ExecuteFindFromInput(\'p_imgTo' + (locationID) + '\', event);"/><br/>';
        description += '<div><img id="p_imgTo' + locationID + '" src="'+ images + 'GetDD.gif" class="popupLink" style="left:100px; float: right;" onclick="PersistenceManager.GDDForPopup(\'TO\', \'' + (locationID) + '\', ' + locationContent.latitude + ','+ locationContent.longitude + ');" /></div>';
        description += '</div>';
        
        // From Here (Action)
        description += '<div id=\"AP_FROM_' + locationID + '\" style="height:70px;display:none;"><div class="popupHeader"><strong>' + resourceDD + ': </strong></div>';
        description += resourceFromHere +':<br/>';
        description += '<input type="text" id="p_fromAddress' + locationID + '" style="width:158px;" onkeydown="ExecuteFindFromInput(\'p_imgFrom' + (locationID) + '\', event);"/><br/>';
        description += '<div><img id="p_imgFrom' + (locationID) + '" src="'+ images + 'GetDD.gif" class="popupLink" style="left:100px; float: right;" onclick="PersistenceManager.GDDForPopup(\'FROM\', \'' + (locationID) + '\', ' + locationContent.latitude + ','+ locationContent.longitude + ');"/></div>';
        description += '</div>';

        // What's near (Action)
        description += '<div id=\"AP_NEAR_' + locationID + '\" style="height:70px;display:none;"><div class="popupHeader"><strong>' + resourceWhatsNearby + ': </strong></div>';
        description += '<div class="popupSubheader">' + resourceSearchForCategory + ':<br/></div>';
        description += '<input type="text" id="p_nearby' + locationID + '" style="width:158px;" onkeydown="ExecuteFindFromInput(\'p_imgNear' + (locationID) + '\', event);"/><br/>';
        description += '<div style="float:left; width:120px">' + resourceWhatsNearbyExample + '</div>';
        description += '<div><img id="p_imgNear' + (locationID) + '" src="'+ images + 'GetDD.gif" class="popupLink" style="margin-top:11px; left:100px; float: right;" onclick="PersistenceManager.GNBForPOIPopup(\'' + (locationID) + '\', ' + locationContent.latitude + ','+ locationContent.longitude + ');"/></div>';
        description += '</div>';
        
        // Save to a Map (Action)
        description += '<div id=\"AP_MAP_' + locationID + '\" style="height:70px;display:none;">';
        description += '<div id=\"AP_MAP_SAVE_' + locationID + '\" style="display:none;">';
        description += '<div style="float:left;">';
        description += '<div class="popupHeader" style="width:120px"><strong>' + resourceSaveToAMap + ': </strong></div>';
        description += '<div style="width:150px">' + resourceSaveToAMapPrompt + '</div>';
        description += '</div>';
        //description += '<div><img src="' + iconURL + '" class="popupLink" style="margin-right:10px; margin-top:10px; float: right; border: 1px solid black;" /></div>';

        description += '<div style="">';        
        description += '<select id="mapSelect" style="width:158px;">';
        description += '</select><br/></div>';
        description += '<div><img id="p_imgAdd' + (locationID) + '" src="' + images + 'doneButton.gif" class="popupLink" style="left:100px; float: right;" onclick="POIManager.SavePOIToCustomMap(\'' + (locationID)  + '\',' + locationContent.latitude + ','+ locationContent.longitude + ',\'' + locationContent.title.replace("'", "%27").replace("\"", "%28") + '\',\'' + locationContent.description.replace("'", "%27").replace("\"", "%28") + '\',\'' + locationContent.iconURL + '\');"/></div>';
        description += '</div>';
        
        description += '<div id=\"AP_MAP_WARN_' + locationID + '\" 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" ';
        description += 'onclick="YPSearchManager.ShowActionDiv(\'AP_\', \'' + (locationID) + '\', \'FROM\');"';
        description += '><img src="images/tohereicon.gif"><span>' + resourceToHere.toUpperCase() + '</span></img></span> | ';
        description += '<span class="popupLink popupDrivingFunctionFrom" ';
        description += 'onclick="YPSearchManager.ShowActionDiv(\'AP_\', \'' + (locationID) + '\', \'TO\');"';
        description += '><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" ';
        description += 'onclick="YPSearchManager.ShowActionDiv(\'AP_\', \'' + (locationID) + '\', \'NEAR\');"';
        description += '><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" ';
        description += 'onclick="YPSearchManager.ShowActionDiv(\'AP_\', \'' + (locationID) + '\', \'MAP\');"';
        description += '><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>';   // Bottom div
        
        description += '</div>';  // overall
        
        // Add prefix
        description = '(S)' + description;
        
        return description;
        //return InfoBoxManager.StoreDescription('POI', index, description);
    }
    

function SetMyLocationDescription(locationID, locationContent)
{
    var latlong = new VELatLong(locationContent.latitude, locationContent.longitude);
    var shapeID = locationContent.shapeID;
    var title = locationContent.title;
    var des = locationContent.description;
    var lastUpdated = locationContent.lastUpdated;
    var iconURL = locationContent.iconURL;
    var deleteText = "";
    
    if (!iconURL || iconURL == "")
    {
        iconURL = "Images/MyLocationPin.gif"; //the default value
    }
    
    if(locationID != "" && !isCurrMapFriends)
    {
        deleteText += "<span id='deleteButton' class='deleteButton' onclick='PersistenceManager.DeleteMyLocation(\"" + shapeID + "\", \"" + locationID + "\")'> " + resourceDelete + "</span><br/>";
        //deleteText += "<span class='lastUpdatedClass'>" + resourceLastUpdatedAt + " " + lastUpdated + "</span>";
    }
    var description = "";
    var disableInput = "";
    description += "<table class='myLocationTable' align='center' cell-padding='10px'>";
    description += "<tr>";                                 
    
    if (isCurrMapFriends)
    {
        disableInput = "disabled=\"true\"";
    }
        
    description += "<td style='font-weight: bold; font-size: 12px'>" + titleText + "<br/><input maxlength='255' class='myLocTitle' style='border: 1px solid black;width:285px;' " + disableInput + " id='myLocTitle_" + shapeID +"' type='text' value='" + title + "'";   
    description += "></input></td>";
    
    title = title.replace("\"", "%28");;    
    des = des.replace("'", "%27").replace("\"", "%28");
        
    description += "<td rowspan='2' style='vertical-align: top'><img style='border: 1px solid black' src='" + iconURL + "'/>";
    description += "<br/><div class='popupChangeIcon' onClick='ShowSelectCustomPins(\"" + locationID + "\",\"" + shapeID + "\",\"" + title + "\",\"" + des + "\"," + latlong.Latitude + ","+ latlong.Longitude + ",\"" + lastUpdated + "\",\"" + iconURL + "\")'>" + resourceChange + "</div>";
    description += "<div class='deleteHolder' id='deleteHolder_" + shapeID + "'>" + deleteText + "</div></td></tr>";   
    description += "<tr>";
    description += "<td style='font-weight: bold; font-size: 12px'>" + descriptionText + "<br/><textarea row='5' class='myLocDescription'" + disableInput + " id='myLocDescription_" + shapeID +"' type='text' >" + des + "</textarea></td>";   
    description += "</tr>";
    
    if (!isCurrMapFriends)
    {
        description += "<tr><td align='right'><img alt='Done' src='" + images + "doneButton.gif' style='align: right; cursor: hand' ";
        description += "onclick='PersistenceManager.SaveMapLocation(\"" + locationID + "\",\"" + currMapID +"\"," + latlong.Latitude + "," + latlong.Longitude+ ",\"" + shapeID + "\", \"" + iconURL + "\");' /></td></tr>";
    }
    description += "</table>";
    
    return description;
}

function ShowSelectCustomPins(locationID, shapeID , title, description, lat, lon, lastUpdated, iconURL)
{
    var pushpin = mapManager.Map.GetShapeByID(shapeID);
    
    var customPinContent = "";
    customPinContent += "<div style='float: left; height: 164px; width: 60px; padding: 10px'>";
	customPinContent += "<img style='width: 45px; height: 45px; border:1px solid black;' id='customStarIcon' src='" + iconURL + "'/><br/>";
	customPinContent += "<div class='customizeButtonText' onclick='PersistenceManager.SaveIconSelection(\"" + locationID + "\")'>" + addIconText + "</div></br>";
	customPinContent += "<div class='customizeButtonText' onclick='restorePushPin(\"" + locationID + "\",\"" + shapeID + "\",\"" + title + "\",\""+ description + "\","+ lat + ","+ lon + ",\"" + lastUpdated + "\",\"" + iconURL + "\")'>&lt;" + backText + "</div>";
	customPinContent += "</div>";
	customPinContent += "<div style='padding-top: 5px'>";
	var i = 0;
	for(i = 0; i < customIconList.length; i++)
	{
	    var iconURL = "Images/CustomIcons/" + customIconList[i];
	    customPinContent += "<img class='customIcon' src='" + iconURL + "' " + "onclick='SelectIcon(\"" + iconURL + "\")'/>";
	}
	customPinContent += "</div>";
	
	pushpin.SetDescription(customPinContent);
	HideCurrentEro(null);
	activeEro = new PushpinERO(shapeID, mapManager.Map);
	activeEro.Show();
}

function restorePushPin(locationID, shapeID, title, des, lat, lon, lastUpdated, iconURL)
{
    HideCurrentEro(null);
    title = title.replace("%27", "'").replace("%28","\"");
    des = des.replace("%27", "'").replace("%28","\"");
    var shape = mapManager.Map.GetShapeByID(shapeID);
    var locationContent = {title: title, description: des, latitude: lat, longitude: lon,
        lastUpdated: lastUpdated, shapeID: shapeID, iconURL: iconURL};
    
    var des = SetMyLocationDescription(locationID, locationContent);
    
    shape.SetDescription(des);

    activeEro = new PushpinERO(shape.GetID(), mapManager.Map);
    activeEro.Show();
}

function SelectIcon(iconURL)
{
    var starIcon = document.getElementById("customStarIcon");
    starIcon.src = iconURL;
}

/**
 * Callback to hide a custom ERO
 *
 * @param e - Event object
 */
function HideCurrentEro(e)
{
    if(activeEro != null && mapChange == false)
    {
        activeEro.Hide();
        activeEro=null;
    }
    return true;
}

/**
 * Callback to show the current ERO if the map was repositioned around the pin
 *
 * @param e - Event object
 */
function ShowCurrentEro(e) {
    if(mapChange == true && activeEro != null) {
        mapChange = false;
        activeEro.Show();
        
        //wait before re-attaching these events to prevent the ERO from being hidden
        setTimeout(function(){
            mapManager.Map.AttachEvent('onstartpan',HideCurrentEro);
            mapManager.Map.AttachEvent('onclick', MouseHandler);
        }, 300);
    }
    return true;
}

/**
 * Get visited listing icon class depending on current css class
 */
function GetVisitedIconClass(pushpinClass)
{
    switch (pushpinClass)    
    {
        case 'pin_wf':
            return 'pin_v_wf';
        case 'pin_nonad':
            return 'pin_v_nonad';  
        case 'clusterPin100':
            return 'clusterPin100_v';
        case 'clusterPin101':
            return 'clusterPin101_v';
        default:
            return pushpinClass;
    }
}

/**
 * Represents an instance of a custom pushpin ERO
 *
 * @param shapeId - VE pushpin shape id
 * @param mapInstance - VE map instance on which to display ERO
 */
function PushpinERO(shapeId,mapInstance) {
    if(shapeId == null || mapInstance == null)
    {
        return;
    }

    //properties
    this.BaseMap=mapInstance;
    this.ShapeId=shapeId;
    this.Shape = mapInstance.GetShapeByID(this.ShapeId);
    this.Type = ClientCache.Retrieve('pane_' + paneNumber + '_type');
	this.CSSPin = "";

    //Based on current icon:
    //change to the visited version if pin one of these css classes: pin_wf|pin_nonad|clusterPin100
    //Add marker square if pin one of these css classes:  pin_wf|pin_v_wf|pin_nonad|pin_v_nonad
    //skip changing pin or adding marker for driving direction pushpins: drivingDirectionsTurnMapIcon drivingDirectionsTurnIcon)
        
    //Based on current icon, change to the visited version (skip driving direction pushpins: drivingDirectionsTurnMapIcon drivingDirectionsTurnIcon)
    if(this.Shape._customIcon != undefined) {
        var curCustomIconString = this.Shape._customIcon;
        if(debug)console.log("PushpinERO: curCustomIconString: %s", curCustomIconString); 

		// Following may pick up wrong css class because of cached div with class ypgMapMarker
        var curCustomIconClass = this.Shape._customIcon.match(/class=(["'])?([\w\s]*)\1/)[2];
        if(debug)console.log("PushpinERO: curCustomIconClass: %s", curCustomIconClass); 
        
        // Don't do anything for DD pushpin class: drivingDirectionsTurnMapIcon drivingDirectionsTurnIcon

        if (curCustomIconClass.match(/^pin_wf|pin_v_wf/i) != null) { 
            // Add marker & deal with changing to visited version
    		this.Shape.SetCustomIcon("<div class='ypgMapMarker'></div><div class=" + GetVisitedIconClass(curCustomIconClass) + "></div>");
			this.CSSPin = curCustomIconClass;
            if(debug)console.log("PushpinERO: Just added ypgMapMarker around curCustomIconClass: %s", curCustomIconClass);
    	}
        else if (curCustomIconClass.match(/pin_nonad|pin_v_nonad/i) != null) { 
            // Add marker & deal with changing to visited version & override positioning
    		this.Shape.SetCustomIcon("<div class='ypgMapMarker ypgMapMarker4NonAdPin'></div><div class=" + GetVisitedIconClass(curCustomIconClass) + "></div>");
			this.CSSPin = curCustomIconClass;
            if(debug)console.log("PushpinERO: Just added ypgMapMarker around curCustomIconClass: %s", curCustomIconClass);
    	}
    	else if (curCustomIconClass.match(/clusterPin100/i) != null) {
	    	// Don't add marker & deal with changing to visited version
	    	this.Shape.SetCustomIcon("<div class=" + GetVisitedIconClass(curCustomIconClass) + "></div>");
    		this.Type = 'poiCluster';
    		if(debug)console.log("PushpinERO: this.Type: %s", this.Type); 
    	}
	}
	
    if (this.Shape.GetTitle() == 'cluster') {
        this.Type = 'poiCluster';
    }
    else if (this.Shape.GetTitle() == 'poi') {
        this.Type = 'poi';
    }
    else if (this.Type == 'dd') {
        // get next and previous turnpoint shape ids from client cache (default both to current turnpoint shape id)
        var turnpointIds = ClientCache.Retrieve('pane_' + paneNumber + '_turnpointIds').split('|');
        this.prevShapeId = this.Shape.GetID();
        this.nextShapeId = this.Shape.GetID();
        for (var i = 0; i < turnpointIds.length; i++) {
            if (turnpointIds[i] == this.Shape.GetID()) {
                if (i > 0)
                    this.prevShapeId = turnpointIds[i - 1];
                if (i < (turnpointIds.length - 1))
                    this.nextShapeId = turnpointIds[i + 1];
            }
        }
    }
    
    if(debug)console.log("PushpinERO: this.Type: %s", this.Type); 
    
    this.Elements=new Array();
    this.Size = EroSize.Small;
    
    /**
     * Creates the visual elements of the ERO
     */
    this.Show = function() {
        //do not show the popup if we're still panning
        if (mapChange) {
            return;
        }

        var pixel = mapInstance.LatLongToPixel(this.Shape.GetIconAnchor());
        if (this.Type == 'poiCluster') {
            pixel.x += 23;
            pixel.y += 18;
        }
        else if (this.Type == 'poi') {
            pixel.x += 10;
        }
        
        centerX = (mapManager.Map.GetWidth() / 2);
        centerY = (mapManager.Map.GetHeight() / 2);
        
        // top left quadrant
        if((pixel.x < centerX) && (pixel.y < centerY))
        {        	
        	// draw to the bottom right
        	topLeftX = Math.round(pixel.x) + 28;
        	topLeftY = Math.round(pixel.y) + 50; //was 150
        	drawLeft = false;
        	drawAbove = false;
       	}
       	// top right quadrant
       	else if((pixel.x >= centerX) && (pixel.y <= centerY))
        {
        	// draw to the bottom left
       		topLeftX = Math.round(pixel.x) - 435;//was 415
        	topLeftY = Math.round(pixel.y) + 50; //was 150
        	drawLeft = true;
        	drawAbove = false;
       	}
       	// bottom left quadrant
       	else if((pixel.x < centerX) && (pixel.y > centerY))
        {
        	// draw to the top right
       		topLeftX = Math.round(pixel.x) + 28;
        	topLeftY = Math.round(pixel.y) - 150; //was 73
        	drawLeft = false;
        	drawAbove = true;
       	}
       	// bottom right quadrant
       	else if((pixel.x >= centerX) && (pixel.y >= centerY))
        {
        	// draw to the top left
       		topLeftX = Math.round(pixel.x) - 435; //was 415
        	topLeftY = Math.round(pixel.y) - 150; //was 73
        	drawLeft = true;
        	drawAbove = true;
       	}

		if(debug)console.log("PushpinERO.Show(): pixel.x:%d Original[topLeftX:%d + contentTop:%d = %d] Applying:containerStyleTop:%d",pixel.x, topLeftX, contentTop, topLeftY+contentTop, containerStyleTop);
       	
//
//        //determine whether we have enough space for the ERO, if not then move
//        var xDelta = mapManager.Map.GetWidth() - pixel.x;
//        var yDelta = mapManager.Map.GetHeight() - pixel.y;
//
//        var xPan = xDelta < 400 ? Math.round(401 - xDelta) : 0;
//        var yPan = 0;
//
//        if (yDelta < 30) {
//            yPan = Math.round(31 - yDelta);
//        }
//
//        if (pixel.y < 108) {
//            yPan += Math.round(pixel.y - 109);
//        }
//
//        if (xPan != 0 || yPan != 0) {
//            mapChange = true;
//
//            //detach these events while we're panning to the location to prevent conflicting callbacks
//            mapManager.Map.DetachEvent('onstartpan', HideCurrentEro);
//            mapManager.Map.DetachEvent('onclick', MouseHandler);
//            mapManager.Map.Pan(xPan, yPan);
//            return;
//        }

        var contentTop = 0;
        var footerTop = 0;
        var description = this.Shape.GetDescription();  
        
        /* At this point description could be a real description or a span wrapped key
           Clusters have directly useable descriptions */
        
        // Check if the description is actaully a span wrapped key
        var imKey = InfoBoxManager.StripSpan(description);

		if(debug)console.log("PushpinERO.Show(): imKey:", imKey);

        if (InfoBoxManager.IsFormattedKey(imKey)) {
            description = InfoBoxManager.GetDescription(imKey);
			if(debug)console.log("PushpinERO.Show(): Retrieved description because imKey is valid: %s", imKey);
			//if(debug)console.log("PushpinERO.Show(): description: [%s]", description);
        }
        var title = this.Shape.GetTitle();
if(debug)console.log("PushpinERO.Show(): description.substring():%s", description.substring(0, 5));
        //determine the size/type of the ERO from the shape description
        // small icon
        if (description.substring(0, 3) == '(S)') {
            this.Size = EroSize.Small;
            description = description.substring(3, description.length);
            footerTop = resources.EroFooterTopLarge;
        }
        // big icon
        else if (description.substring(0, 3) == '(B)') {
            this.Size = EroSize.Large;
            description = description.substring(3, description.length);
            footerTop = resources.EroFooterTopSmall;
        }
        else if (description.substring(0, 5) == '(DDL)') {
            this.Type = 'ddl';
            description = description.substring(5, description.length);
            // replace up arrow onclick event to call ShowNewEro with shape id of previous turnpoint
            description = description.replace(/mapManager.ShowInfoBoxp/g, "ShowNewEro(\"" + this.prevShapeId + "\")");
        }
        else if (description.substring(0, 5) == '(DDF)') {
            this.Type = 'ddf';
            description = description.substring(5, description.length);
            // replace down arrow onclick event to call ShowNewEro with shape id of next turnpoint
            description = description.replace(/mapManager.ShowInfoBoxn/g, "ShowNewEro(\"" + this.nextShapeId + "\")");
        }
        else if (description.substring(0, 5) == '(DDI)') {
            this.Type = 'ddi';
            description = description.substring(5, description.length);
            // replace up arrow onclick event to call ShowNewEro with shape id of previous turnpoint
            description = description.replace(/mapManager.ShowInfoBoxp/g, "ShowNewEro(\"" + this.prevShapeId + "\")");
            // replace down arrow onclick event to call ShowNewEro with shape id of next turnpoint
            description = description.replace(/mapManager.ShowInfoBoxn/g, "ShowNewEro(\"" + this.nextShapeId + "\")");
        }

        if (this.Size == EroSize.Small) {
            contentTop = -137;
        }
        else if (this.Size == EroSize.Large) {
            if(drawAbove == true)
                contentTop = -255;
            else
                contentTop = -137;
        }

        if(debug)console.log("PushpinERO.Show(): contentTop: %d", contentTop); 

        // adjust position for the shorter info boxes of first and last driving direction turpoints
        if (this.Type == 'ddf')
            contentTop += 113;
        else if (this.Type == 'ddl')
            contentTop += 13;
/*NA
        var header = document.createElement("div");
        header.id = shapeId + "h";
        header.style.top = topLeftY - 18 + contentTop + "px";
        header.style.left = topLeftX + "px";
        header.style.width = "368px";
        header.style.height = "19px";
        header.style.backgroundImage = "url(Images/PopupHeaderSmall.gif)";
        header.innerHTML = "<div class='EroHeader handicon' onclick='activeEro.Hide();'><span class='CloseText'>" + resourceClose + "&nbsp;</span><img class='CloseImage'  src='Images/CloseIcon.gif' /></div>";
        this.Elements.push(header);
*/

		var containerStyleTop = topLeftY + contentTop < 0 ? 0 : topLeftY + contentTop;
		if(debug)console.log("PushpinERO.Show(): pixel.y:%d Original[topLeftY:%d + contentTop:%d = %d] Applying:containerStyleTop:%d",pixel.y, topLeftY, contentTop, topLeftY+contentTop, containerStyleTop);
		
        var container = document.createElement("div");
        container.id = shapeId + "c";
        //container.style.top = topLeftY + contentTop + "px";
        container.style.top = containerStyleTop + "px";
        container.style.left = topLeftX + "px";
        
        if (this.Type == 'poiCluster') {
            container.style.width = "364px"; //new
            container.style.backgroundColor = "White";  // Added colour here directly for cluster dialog because not setting anymore in general becase of transparent rounded images in MMB

			//TEMP until add corner images
	        container.style.border = "solid 1px #999999";
	        container.style.MozBorderRadius="10px";
	        container.style.WebkitBorderRadius="10px";
        }
        
        //Make conditional on this.Type == 'im' to not use width.
        //container.style.width = "450px"; //364
        
        //container.style.opacity = "0.9"; //new but doesn't work for IE
        $(container).setOpacity( 0.9 ); // this works for everyone
        
        // info box for first or last waypoint of driving directions
        if (this.Type == 'ddf' || this.Type == 'ddl') {
            container.style.height = "176px";
            container.style.width = "364px"; //new
            container.style.backgroundColor = "#66676a";
        }
        // info box for intermediate turnpoint of driving directions
        else if (this.Type == 'ddi') {
            container.style.height = "304px";
            container.style.width = "364px"; //new
            container.style.backgroundColor = "#66676a";
        }
        else {
            //Make conditional on this.Type == 'im' to not use height.
            //container.style.height = this.Size == EroSize.Small ? "200px" : "350px"; //318
            
            //container.style.backgroundColor = "White";  // All dialogs except dd related were having their backgrounds set here.  but because of transparent rounded corners can't set background here anymore!!
        }
        
/*
        var closeIconDiv = document.createElement("div");
        closeIconDiv.id = shapeId + "t";
        closeIcon.innerHTML = "<div class='handicon' onclick='activeEro.Hide();'><span class='.menuPlus'></span></div>";
        container.appendChild(closeIconDiv);
*/
        if (title != null && this.Type != 'poi') { // removed && this.Type != 'poiCluster'
            var titleDiv = document.createElement("div");
            titleDiv.id = shapeId + "t";
            titleDiv.innerHTML = title;
            container.appendChild(titleDiv);
        }

        if (description != null) {
            var descriptionDiv = document.createElement("div");
            descriptionDiv.className = 'InfoBox';
            descriptionDiv.id = shapeId + "d";
            container.appendChild(descriptionDiv);
            var closeLine = '<div class="ypgMMBClose"><a class="ypSpLayerFunctions ypSmClose" href="#" onclick="javascript:activeEro.Hide();return false;" rel="nofollow">&nbsp;</a></div>';
            //var closeLine = '';
            descriptionDiv.innerHTML = closeLine + description;
        }

        //alert(description);

        /*UP container.style.borderLeft = "solid 1px #999999";
        container.style.borderRight = "solid 1px #999999";*/
        
        // Can't put border here because of transparent corner images defined in nested elements
        //container.style.borderLeft = "solid 1px #d5d5d5";
        //container.style.borderRight = "solid 1px #d5d5d5";
        
        /* Switching to images */
        /*
        container.style.border = "solid 1px #999999";
        container.style.MozBorderRadius="10px";
        container.style.WebkitBorderRadius="10px";
		*/

		// draw the callout triangle
/*        var beak = document.createElement("img");
        beak.id = shapeId + "b";
        if(drawLeft == false && drawAbove == false)
        {
        	// draw below and to the right
	        beak.style.top = Math.round(pixel.y) + 3 + "px";
	        beak.style.left = Math.round(pixel.x) - 1 + "px";
	        beak.src = "Images/PopupBeak.gif";
	      }
	      else if(drawLeft == true && drawAbove == false)
	      {
	      	// draw below and to the left
	      	beak.style.top = Math.round(pixel.y) + 3 + "px";
	        beak.style.left = Math.round(pixel.x) - 49 + "px";
	        beak.src = "Images/PopupBeak2.gif";
	      }
	      else if(drawLeft == false && drawAbove == true)
        {
        	// draw above and to the right
	        beak.style.top = Math.round(pixel.y) - 40 + "px";
	        beak.style.left = Math.round(pixel.x) - 1 + "px";
	        beak.src = "Images/PopupBeak4.gif";
	      }
	      else if(drawLeft == true && drawAbove == true)
	      {
	      	// draw above and to the left
	      	beak.style.top = Math.round(pixel.y) - 40 + "px";
	        beak.style.left = Math.round(pixel.x) - 45 + "px";
	        beak.src = "Images/PopupBeak3.gif";
	      }
        this.Elements.push(beak);
*/

        if (this.Type == 'ddf' || this.Type == 'ddi' || this.Type == 'ddl') {
            var footer = document.createElement("div");
            footer.id = shapeId + "f";
            footer.innerHTML = "<table><tr style='height:5px;'><td style='width:5px; background:url(\"Images/GDD_InfoBox/lowerLeftCorner.png\");'></td><td style='width:354px; background:#66676a;'></td><td style='width:5px; background: url(\"Images/GDD_InfoBox/lowerRightCorner.png\") no-repeat 0% 100%;'></td></tr></table>";
            container.appendChild(footer);
        }
        // attach footer as seperate control if shape is not a driving direction turnpoint
        else {
            var footer = document.createElement("img");
            footer.id = shapeId + "f";
            footer.src = "Images/PopupFooter.gif";
            if(this.Size == EroSize.Large)
            {
                if(drawAbove == true)
                {
                        footer.style.top = topLeftY+ 92+ footerTop + (0 - ((this.Type == 'poiCluster' || this.Type == 'poi') ? 0 : 30)) + "px";
                }
                else
                {
                        footer.style.top = topLeftY+210+ footerTop + (0 - ((this.Type == 'poiCluster' || this.Type == 'poi') ? 0 : 30)) + "px";
                }
                }
                else
                {
                footer.style.top = topLeftY+ 63+ footerTop + (0 - ((this.Type == 'poiCluster' || this.Type == 'poi') ? 0 : 30)) + "px";
            }

            footer.style.left = topLeftX + "px";
            this.Elements.push(footer);
        }

        this.Elements.push(container);

        for (var i = 0; i < this.Elements.length; i++) {
            mapInstance.AddControl(this.Elements[i]);
        }
        
        this.Shape.SetZIndex(zIndex);
        zIndex++;
        
        if(debug)console.log("PushpinERO.Show(): End of method.  zIndex", zIndex);
    }
    
    /**
     * Removes all visual elements of an ERO
     */
    this.Hide=function()
    {
        try
        { 
            // Reset value used for custom icon of pin Shape object to remove ypgMapMarker marker image div
    		if(this.CSSPin.length > 0) {
    			this.Shape.SetCustomIcon("<div class=" + GetVisitedIconClass(this.CSSPin) + "></div>");
            	if(debug)console.log("PushpinERO.Hide(): reset CustomIcon value: %s", this.CSSPin);
			}
			
            for(var i=0; i<this.Elements.length; i++)
            {
                mapInstance.DeleteControl(document.getElementById(this.Elements[i].id));
            }
        }
        catch(e)
        {}
    }
    
    /**
     * Determine whether the mouse has left the ERO
     *
     * @param x - Horizonal mouse position
     * @param y - Vertical mouse position
     */
    this.IsOutside=function(x,y)
    {
        var result=false;
        var center=mapInstance.LatLongToPixel(this.Shape.GetIconAnchor());
        var height=0;
        
        if(this.Size == EroSize.Small)
        {
            height=138;    
        }
        else if(this.Size == EroSize.Large)
        {
            height=334;
        }

        if(x<center.x-30||(x<center.x+15 && y<center.y-30)||x>center.x+368||y<center.y-height||y>center.y+2)
        {
            result=true;
        }

        return result;
    }
}

function ShowNewEro(shapeID) {
    activeEro.Hide();
    activeEro = null;
    var center = mapManager.Map.GetShapeByID(shapeID).GetPoints()[0];

    // delete poi shapes from map before zooming out
    POIManager.HidePOIs();

    mapManager.Map.SetCenterAndZoom(center, 5);
    mapManager.Map.SetCenterAndZoom(center, 13); //was 15

    // re-add poi shapes back onto map after zooming back in
    POIManager.RefreshPOIs();

    activeEro = new PushpinERO(shapeID, mapManager.Map);
    activeEro.Show();
}
