function mapMarkerTracker()
{
  var _mapMarkers = new Array();
  
  this.AddMarker = AddMarker;
  this.removeMarkerById = removeMarkerById;
  this.redrawMarkers = redrawMarkers;
  this.ClearMarkerImages = ClearMarkerImages;
  
  function AddMarker(mapMarker)
  {
    for (var i in _mapMarkers)
    {
      // If we already have this in our array do not add it
      if (_mapMarkers[i].MarkerID() == mapMarker.MarkerID())
      {
        //alert("Did not add " + mapMarker.MarkerID());
        return;
        }
    }
    
    // Add the marker to the markers array
    _mapMarkers.push(mapMarker);
    
    // Draw it immediately.
    DrawMarker(mapMarker);
  }
   
  function removeMarkerFromMarkerArray(mapMarkerId)
  {
    
    var tempArray = new Array();
    
for (var i in _mapMarkers)
    {
      if (_mapMarkers[i].MarkerID() != 'mm_' + mapMarkerId)
        tempArray.push(_mapMarkers[i]);
    }
    
    _mapMarkers = tempArray;
    
  }

  function removeMarkerById(mapMarkerId)
  {
    // Remove it from the array

    removeMarkerFromMarkerArray(mapMarkerId);
    
    removeMarkerImage(mapMarkerId);

  }
  
  function removeMarkerImage(mapMarkerId)
  {  
    var mm = document.getElementById(mapMarkerId);
     
    if (mm != null)
    {
      if (m_sClientBrowserType == 'IE')
        m_imgMapLayer.removeChild(mm);
      else
        document.forms[0].removeChild(mm);
        
      m_mapViewer.removeFloatingWindow(mm);
    }
  }
  
  function DrawMarker(mapMarker)
  {       
    if (m_mapViewer.isXYInMapView(mapMarker.mapX(), mapMarker.mapY(), 0))
    {
      // Reset the screen coordinates for this marker
      mapMarker.setScreenCoords();
        
      var mapImage = mapMarker.getMarkerImage(m_mapViewer);
  
      if (m_sClientBrowserType == 'IE')
        m_imgMapLayer.appendChild(mapImage);
      else 
        document.forms[0].appendChild(mapImage);
      
      var mm = document.getElementById(mapMarker.MarkerID());
         
      mm.style.position = 'absolute';  
      mm.style.top = mapMarker.displayY() + 'px';
      mm.style.left = mapMarker.displayX() + 'px';
      mm.style.zIndex = 900;   
      mm.style.width = '32px';
      mm.style.height = '32px';
      
      
      //if (mapMarker.hasClickEvent())
      if (mapMarker.hasBubbleHtml())
      {
        m_mapViewer.addFloatingWindow(mm);
        
        mm.style.cursor = 'pointer'
        
        //attachClickEvent(mm, mapMarker.showInfoWindow); //mapMarker.fireClickEvent);
        mm.onclick = mapMarker.showInfoWindow;
      } 
    }
  }
  
  function redrawMarkers()
  {
    ClearMarkerImages();
    
    DrawMarkers();
  }
  
  function DrawMarkers()
  {
    for (var i in _mapMarkers)
    {
      DrawMarker(_mapMarkers[i]);
    }
  }
  
  function ClearMarkerImages()
  {
    for (var i in _mapMarkers)
    {
      removeMarkerImage(_mapMarkers[i].MarkerID());
    }
  }
}

function mapBubbleManager()
{
  var _lastMarkerClickedId = '';
  var _bubbleVisible = false;
  
  this.hideMapBubble = hideMapBubble;
  this.showMapBubble = showMapBubble;

  function hideMapBubble()
  {
    if (_bubbleVisible)
    {
      _mapMarkerBubble.style.visibility = 'hidden';
      _markerBalloonString.style.visibility = 'hidden';  
            
      m_mapViewer.removeFloatingWindow(_mapMarkerBubble);
      
      _bubbleVisible = false;
    }
  } 
  
  function showMapBubble(xCoord, yCoord, innerHtml, markerId)
  {     
      // If the bubble is visible and the user clicked the same marker then hide it
      if (_lastMarkerClickedId == markerId && _bubbleVisible)
      {
        hideMapBubble();
      }
      else
      {    
          // First get the quadrant this marker is in from the map
          var markerQuadrant = m_mapViewer.determineMapQuadrant(xCoord, yCoord);       
          
          // Addjust the relative coordinates (to the map image) for absolute coordinates for the screen - ONLY FOR IE
          if (m_sClientBrowserType == 'IE')
          {
            xCoord += GetImageLeft();
            yCoord += GetImageTop();
          }
          
          if (m_sClientBrowserType == 'IE')
            _mapMarkerBubble.innerHTML = innerHtml;
          else
            document.getElementById('markerContent').innerHTML = innerHtml;

          
          var balloonStringYCoord;
          var balloonStringImage = '/aspnet_client/system_web/CoEGenericGIS/v3/images/';
                                   
          // Get the resulting width and height of the div after applying the table inside.
          _mapMarkerBubble.height = 0;
          
          var divWidth = parseInt(_mapMarkerBubble.scrollWidth);
          var divHeight = parseInt(_mapMarkerBubble.scrollHeight);          
                    
          switch (markerQuadrant)
          {
            case 1: // Northwest - we will put the bubble to the south east
              xCoord += 15; // Subtract the width of the div to shift it to the left and then adjust it back a little
              yCoord += 32 + 30; // Add the height of the image and the height of balloon "string"
              balloonStringYCoord = (yCoord - 28); // The balloonString will go to the top of the div
              balloonStringImage += 'bs_s.gif';
              // Need to align the image to the left
              _markerBalloonString.style.textAlign = 'left';
              break;
            case 2: // Northeast - we will put the bubble to the south west
              xCoord -= (divWidth - 75); // Subtract the width of the div to shift it to the left and then adjust it back a little
              yCoord += 32 + 30;  // Add the height of the image and the height of balloon "string"
              balloonStringYCoord = (yCoord - 28); // The balloonString will go to the top of the div
              balloonStringImage += 'bs_s.gif';
              // Need to align the image to the right
              _markerBalloonString.style.textAlign = 'right';
              break;
            case 3: // Southeast - we will put the bubble to the north west
              xCoord -= (divWidth - 75); // Subtract the width of the div to shift it to the left and then adjust it back a little
              yCoord -= (divHeight + 30); // Subtract the height of the div + height of the balloon "string'
              balloonStringYCoord = yCoord + divHeight - 1; // Add back the div height
              balloonStringImage += 'bs_n.gif';
              // Need to align the image to the right
              _markerBalloonString.style.textAlign = 'right';
              break;
            case 4: // Southwest - we will put the bubble to the north east
              yCoord -= (divHeight + 30); // Subtract the height of the balloon "string'
              xCoord += 15; // Push bubble over a little bit
              balloonStringYCoord = yCoord + divHeight; // Add back the div height
              balloonStringImage += 'bs_n.gif';
              // Need to align the image to the left
              _markerBalloonString.style.textAlign = 'left';
              break;        
          }
          
          _markerBalloonString.style.width = divWidth;
          _markerBalloonString.style.top = balloonStringYCoord;
          _markerBalloonString.style.left = xCoord;          
          
          _markerBalloonStringImage.src = balloonStringImage;      
                
          _mapMarkerBubble.style.top = yCoord + 'px';
          _mapMarkerBubble.style.left = xCoord + 'px';
          //_mapMarkerBubble.style.height = '1px'
              
          _mapMarkerBubble.style.visibility = 'visible';
          _markerBalloonString.style.visibility = 'visible';
          
          m_mapViewer.addFloatingWindow(_mapMarkerBubble);
          
          _bubbleVisible = true;
          _lastMarkerClickedId = markerId;
       }  
   }
}

function mapMarker(markerId, MapX, MapY, imgUrl)
{
	var _imgUrl = '/aspnet_client/system_web/CoEGenericGIS/v3/images/blue_pointer.png';
	var _xCoord;
	var _yCoord;
	var _markerId;
  var _bubbleHtml = '';

  var _mapX;
  var _mapY;
   
  var _displayX;
  var _displayY;
  
  var _clickEvent = null;

  _markerId = 'mm_' + markerId;

	// TODO - ALLOW CUSTOM URLS - CHECK IF imgUrl is not blank, or null and set the image there.
	if (imgUrl != '')
    _imgUrl = imgUrl;
	
  _mapX = MapX; 
  _mapY = MapY; 
  
  setScreenCoords();
   
  this.getMarkerImage = getMarkerImage;
  this.MarkerID = MarkerID;
  this.mapX = mapX;
  this.mapY = mapY;
  this.displayX = displayX;
  this.displayY = displayY;
  this.setScreenCoords = setScreenCoords;
  //this.setClickEvent = setClickEvent;
  //this.fireClickEvent = fireClickEvent;
  //this.clearClickEvent = clearClickEvent;
  //this.hasClickEvent = hasClickEvent;
  this.showInfoWindow = showInfoWindow;
  this.setBubbleHtml = setBubbleHtml;
  this.hasBubbleHtml = hasBubbleHtml;
  
  function mapX()
  {
    return _mapX;
  }
  
  function  mapY()
  {
    return _mapY;
  }
  
  function displayX()
  {
    return _displayX;
  }
  
  function displayY()
  {
    return _displayY;
  }
  
  function MarkerID()
  {
    return _markerId;
  }
  
  function setScreenCoords()
  { 
    // Convert the map coordinates to page coordinates
    var pagePoint = m_mapViewer.toPagePoint(_mapX, _mapY);   
    
    _displayX = pagePoint.x;
    _displayY = pagePoint.y;
              
    // Since the Map Markers are rendered using Absolute positioning (it should be relative but
    // there appears to be a bug when adding a child element via javascript to another element
    // that causes relative positioning to not work as advertised) we need to adjust the positions
    // by the top/left of the map to position them correctly -- ONLY IN IE
     if (m_sClientBrowserType == 'IE')
     {
      _displayX -= GetImageLeft();
      _displayY -= GetImageTop();
     }
            
    // Modify the screen coordinates for the image size - centers the bottom middle of the image
    // on the actual point where the click or point is
    _displayX = Math.round(_displayX - 16);
    _displayY = Math.round(_displayY - 32);  
  }
  
  function setClickEvent(clickEvent)
  {
    _clickEvent = clickEvent;
  }
  
  function hasBubbleHtml()
  {
    return _bubbleHtml != '';
  }
  
  function fireClickEvent()
  {    
    //if (_clickEvent != null)
    //  _clickEvent();
  }
  
  function clearClickEvent(clickEvent)
  {
    _clickEvent = null;
  }
  
  function hasClickEvent()
  {
    return (_clickEvent != null);
  }
  
  function setBubbleHtml(htmlString)
  {
    _bubbleHtml = htmlString;
  }
  
  function showInfoWindow()
  {
    if (_bubbleHtml != '')
      _mapBubbleManager.showMapBubble(_displayX, _displayY, _bubbleHtml, MarkerID());    
  }
  
  function getMarkerImage()
  {
    var markerImage = document.createElement('img');

    markerImage.setAttribute('id', _markerId);
    markerImage.setAttribute('style', getImageStyle());
    markerImage.setAttribute('src', _imgUrl);
        
    return markerImage;    
  }
  
  function getImageStyle()
  {    
    //var styleString = "width: 32px;height: 32px;position: absolute;top: " + displayY() + "px;left: ";
    //styleString += displayX();
    //styleString += "px; z-index: 900;";
    
    var styleString = "width: 32px;height: 32px";
        
    return styleString;
  }
  
  function renderAsXml()
  {
    var xmlRep = "<marker>"
    xmlRep += "<markerId>" + _markerId; + "</markerId>";
    xmlRep += "<xCoord>" + _screenX + "</xCoord>";
    xmlRep += "<yCoord>" + _screenY + "</yCoord>";
    xmlRep += "<imgUrl>" + _imgUrl + "</imgUrl>";
    xmlRep += "</marker>";
  
    return xmlRep;
  }
}