MailTo = Class.create({});

MailTo.addMethods(
{
  initialize: function() 
  {
    $$('.mailto').each(function(target) {
      if (target.href) {
        target.href = target.href.gsub(/MAILTO_PAGE_URL/, window.location);
      }
    });
  }
});
RandomSelection = Class.create({});

RandomSelection.addMethods(
{
  initialize: function(elements) 
  {
    this.items = elements;
  },
  hideAll: function() {
    this.items.each(function(target) { target.hide() });
  },
  showRandom: function() {
    this.hideAll();

    var index = Math.floor(Math.random()*this.items.size())
    if (this.items[index] != null)
    {
      this.items[index].show();
    }
  }
});
MessageBox = Class.create({});
Object.extend(MessageBox, 
{
  IMAGE_ROOT: '/',
  LOADING_IMAGE: 'images/loading.gif',
  BOX_IMAGE: 'images/messagebox.png',
  BOX_IMAGE_GIF: 'images/messagebox.gif',
  BOX_HTML: '<div id="MessageBox"><div class="top"></div><div id="MessageContent"></div><div class="bottom"</div></div>',
  MESSAGE_TPL: new Template('<h2>#{header}</h2><p>#{content}</p>'),
  LOADING_TPL: new Template('<img src="#{load_img}" alt="" /><p class="loading">#{load_msg}</p>')
});
MessageBox.addMethods(
{
  initialize: function(parentElement, loadingMessage) 
  {
    this.parentElement = parentElement;
    if ($('MessageBox') == null && $('MessageContent') == null)
    {
      this.parentElement.insert(MessageBox.BOX_HTML);
    }
    this.loadingMessage = loadingMessage;

    this.loadingImage = new Image();
    this.loadingImage.src = MessageBox.IMAGE_ROOT + MessageBox.LOADING_IMAGE;
  
    this.box = $('MessageBox');
    this.content = this.box.down('#loadingContent');
    
    this.box.hide();
  },
  showLoading: function() 
  {
    this.box.show();
    var content = MessageBox.LOADING_TPL.evaluate({ 
      load_img: this.loadingImage.src, 
      load_msg: this.loadingMessage 
    });
    $('MessageContent').update(content);
    this.setPosition();
  },
  setPosition: function() {
    var mapHeightCenter = Number(this.parentElement.getStyle('height').replace('px', '')) / 2;
    var mapWidthCenter = Number(this.parentElement.getStyle('width').replace('px', '')) / 2;

    var heightCenter = Number(this.box.offsetHeight.toString().replace('px', '')) / 2;
    var widthCenter = Number(this.box.offsetWidth.toString().replace('px', '')) / 2;
    
    this.box.setStyle({ top: mapHeightCenter - heightCenter + 'px', left: mapWidthCenter - widthCenter + 'px' });
  },
  hide: function(event) 
  {
    if(event) 
    { 
      event.stop(); 
    }
    this.box.hide();
  },
  showMessage: function(header, content, action) 
  {
    $('MessageContent').update(MessageBox.MESSAGE_TPL.evaluate({ 
      header: header, 
      content: content 
    }));
    if(action) 
    { 
      $('MessageContent').insert(action); 
    }
    this.box.show();
    this.setPosition();
    if($('MessageContent').select('.close')[0]) 
    {
      $('MessageContent').select('.close')[0].stopObserving('click');
      $('MessageContent').select('.close')[0].observe('click', this.hide.bindAsEventListener(this));
    }
  }
});
MapController = Class.create({});
Object.extend(MapController, 
{    
    MODE_NORMAL: 'normal',
    MODE_SMALL: 'small',

    STRINGS: {
        bad_search: {
            header: 'No search results',
            content: 'Sorry, but we found no search results for #{search_terms}. Please try again by starting a new search.',
            helpful_hints: 'Check that all words are spelled correctly. It may also help to try different search terms.'
        },
        no_results: {
            header: '<span style="font-size: 10px;">No results for surrounding American Express properties</span>',
            content: 'Sorry, but we found no search results within #{search_radius} of your destination that offer the services you selected.<br /><br />Please try again by starting a new search.',
            helpful_hints: 'It may help to select a larger distance, or to try a new search for a different location.'
        },
        invalid_zip: {
            header: 'Invalid ZIP Code',
            content: 'Please try again by starting a new search. Enter a valid Postal/ZIP code as a search term.'
        },
        city_empty: {
            header: 'No search results',
            content: 'We require a valid city to complete your request. Please try again by starting a new search.'
        },
        city_postal_empty: {
            header: 'No search results',
            content: 'We require a valid city and postal/ZIP code to complete your request. Please try again by starting a new search.'
        },
        feature_unavailable: {
            header: 'Feature Temporarily Unavailable',
            content: 'Because of an internal error, we are unable to show all or some of your selected location types right now. Please try again later. Click close to continue.'
        },
        helpful_hints_header: 'Helpful Hints',
        multiple_results_header: 'Multiple locations found. Please select one.',
        page_unavailable: {
            header: 'Page unavailable',
            content: 'Due to an internal error, this page is unavailable right now. Please try again later.'
        },
        general_error: {
            header: 'Error',
            content: 'Sorry, but we encountered an error. Please try again.'
        },
        actions: {
            continue_link: '<p><a class="close" href="#close">Click to continue</a></p>',
            landing_link: '<p><a href="link">Click to continue</a></p>'
        },
        loading: 'Loading&hellip;'
    },
  	MODEL: $H({ // Defaults for MapController.model
        zoom: 1, // 1-16
        maptype: 'map', // 'map', 'sat', 'hyb'
        uistate: 'normal', // 'normal', 'types', 'maponly'
        searchterms: '', // holds the actual search request from the user
        query: new MQAddress(), // searchterms converted into MapQuest preferred style
        response: '', // response from MapQuest for the query
        radius: {
            value: 10,
            units: 'miles' // or 'km'
        },
        display: $H({ // holds the type of locations that will be displayed on the map. reset on page load from html
            tso: true,
            fhr: true,
            pdl: true,
            // constants for services. services received from the server should be in the ID# form
            services: $H({
				        32: $H({ name: 'Annual Travel Benefit',                               value: true }),
                 4: $H({ name: 'Client Letter',                                       value: true }),
                 8: $H({ name: 'Emergency Card Replacement',                          value: true }),
                 9: $H({ name: 'Emergency Card Replacement – Pickup Point Only',      value: true }),
                10: $H({ name: 'Emergency Funds Access',                              value: true }),
                11: $H({ name: 'Emergency Funds Access through a Local Bank',         value: true }),
                12: $H({ name: 'Foreign Currency Exchange – Buy',                     value: true }),
                13: $H({ name: 'Foreign Currency Exchange – Sell',                    value: true }),
                38: $H({ name: 'Foreign Drafts – Sell',                               value: true }),
                14: $H({ name: 'Funds Transfer',                                      value: true }),
                36: $H({ name: 'Gift Cards – Sell',                                   value: true }),
                35: $H({ name: 'Gift Cheques – Sell',                                 value: true }),
                22: $H({ name: 'Money Order',                                         value: true }),
                42: $H({ name: 'Travelers Cheques – Cashed',                          value: true }),
                29: $H({ name: 'Travelers Cheques – Refunds',                         value: true }),
                30: $H({ name: 'Travelers Cheques – Sell',                            value: true })
            })
        }), // filter types displayed on the map
        locations: [], // locations returned for the current query from the server
        page: 0, // current page of result list
        currentLocations: [], // locations currently on the map
        locationsCollection: new MQPoiCollection(), // MapQuest point collection
        mapLocations: [] // points currently on the map
    })
});
MapController.addMethods(
{	
	initialize: function (mapElement, mode, width, height, printable)
	{
	  this.mapMode = mode;
	  this.mapElement = mapElement;
	  this.mapWidth = width;
	  this.mapHeight = height;
	  
    this.messageBox = new MessageBox(this.mapElement, MapController.STRINGS.loading);
    this.messageBox.showLoading();
    
    this.model = MapController.MODEL;
        
    this.printable = printable || false;
        
    try 
    {
        // fix for IE forever loading map tiles
        // https://trc.mapquest.com:443/jforum/posts/list/881.page
        this.mapElement.setStyle({ width: this.mapWidth + 'px', height: this.mapHeight + 'px' });

        this.map = new MQTileMap(this.mapElement);
        this.map.setSize(new MQSize(this.mapWidth, this.mapHeight));

        if (this.mapMode == MapController.MODE_NORMAL)
        {
          this.map.setLogoPlacement(
              MQMapLogo.MAPQUEST, new MQMapCornerPlacement(MQMapCorner.BOTTOM_LEFT, new MQSize(0,14))
          );
          this.map.setLogoPlacement(
              MQMapLogo.SCALES, new MQMapCornerPlacement(MQMapCorner.BOTTOM_RIGHT, new MQSize(5,14))
          );
          this.map.setBestFitMargin(50);
        }
        else
        {
          this.map.setLogoPlacement(
              MQMapLogo.MAPQUEST, new MQMapCornerPlacement(MQMapCorner.BOTTOM_RIGHT, new MQSize(0,14))
          );
        }

        this.mapcontrols = new MapControls(this.mapElement, this.map, this.mapMode);
        this.messageBox.hide();

        document.observe('model:update', this.updateLocations.bindAsEventListener(this));
        
        document.observe('pagination:change', this.onPageUpdate.bindAsEventListener(this));
    } 
    catch(error) 
    {
        this.messageBox.showMessage(
            MapController.STRINGS.general_error.content, MapController.STRINGS.actions.landing_link
        );
    }
	},
	
	// helper functions for showing selected state on a location, they just call down
	// to the location specific functions anyway
	selectLocation: function (index)
	{
	  this.model.get('mapLocations')[index].showSelected();
	  this.map.getDeclutter().setDeclutterMode(2);
	},
	deselectLocation: function (index)
	{
	  this.model.get('mapLocations')[index].showDeselected();
	},
	
  renderLocations: function (page, pageOffset)
  {
	this.pageOffset = pageOffset;
	
    this.messageBox.showLoading();
    
    document.stopObserving('model:change', this.updateLocations.bindAsEventListener(this));
    
    this.clearLocations();
    
    this.setModel('mapLocations', []);
    this.setModel('locations', page);
    document.fire('model:change');
    
    this.updateLocations();
    
    // start listening if the model changes. if so, we update the display.
    // we didn't start this when creating the map because 
    // the model changes numerous times on initial map creation.
    document.observe('model:change', this.updateLocations.bindAsEventListener(this));
  },
  
  setModel: function(key, value) 
  {
      this.model._object[key] = value; 
  },
  
	updateLocations: function (event) 
  {
      this.clearLocations();
      
      if(this.model.get('locations').length === 0) 
      {
          this.messageBox.hide();
          return;
      }
      
      var selectedtypes = [];
      if(this.model.get('display').get('tso')) { selectedtypes.push('TSO'); }
      if(this.model.get('display').get('fhr')) { selectedtypes.push('FHR'); }
      if(this.model.get('display').get('pdl')) { selectedtypes.push('PDL'); }
      
      this.setModel('currentLocations', this.model.get('locations'));
      
      var maxZoomLevel = (this.mapMode == MapController.MODE_SMALL ? 10 : 16);
      var minZoomLevel = 1;
      
      // only perform the update if there were locations
      if(this.model.get('currentLocations').length >= 1) {
          // it seems faster to add locations with declutter off first and then turn it on after
          this.map.getDeclutter().setDeclutterMode(0);
          this.addLocations(this.model.get('currentLocations'));
          this.map.getDeclutter().setDeclutterMode(2);

		  var centerLocation = this.model.get('currentLocations').first();
		  if (centerLocation.includeOnMap) 
		  {
			this.map.bestFit(false, minZoomLevel, maxZoomLevel);
		  }
		  else 
		  {
			this.map.setCenter(new MQLatLng(centerLocation.latitude, centerLocation.longitude), 2);
          }
          // select the point last so it gets the correct position after declutter
          if(this.model.get('mapLocations').length > 1) {
              this.model.get('mapLocations')[0].selectPoint();
          }
      } else {
          this.messageBox.hide();
          this.map.bestFit(false, 4, 4);
      }
  },
  
  clearLocations: function() 
  {
      this.map.getDeclutter().setDeclutterMode(0);
      this.model.get('mapLocations').each(function(thispoi) {
		try
		{
			this.map.removePoi(thispoi.poi);
		}
        catch (error) {
			// nothing
		}
      }.bind(this));
      this.model.get('mapLocations').length = 0;

      // hack to remove SVG paths and circles on pagination update
      if($('mqOverlayDiv')) {
          $('mqOverlayDiv').select('path, circle').each(function(item){ 
              $('mqOverlayDiv').select('svg')[0].removeChild(item);
          });  
      }
      
      this.map.getDeclutter().setDeclutterMode(2);
  },
  
  addLocations: function(locations) 
  {
      for(var i = 0; i < locations.length; i++) {
		
          this.model.get('mapLocations').push(
            new MapLocation(
              this, 
              locations[i], 
              i, 
              (this.pageOffset || 0) + i + 1,
              this.printable
            )
          );
      }
      this.messageBox.hide();
  }
	
});
var MapControls = Class.create({});
Object.extend(MapControls, 
{
    TYPES: {
        HYB_ID: 'mapTypeHybrid',
        MAP_ID: 'mapTypeMap',
        SAT_ID: 'mapTypeSatellite'
    },
    
    MODE_NORMAL: 'normal',
    MODE_SMALL: 'small',
    
    /*********************************************************************************
     *
     *      DO NOT EDIT BELOW THIS LINE
     *
     *********************************************************************************/
    TYPES_TPL: new Template('<div id="mapcontrols"><div id="#{SAT_ID}" class="sat"></div><div id="#{HYB_ID}" class="hyb"></div><div id="#{MAP_ID}" class="map"></div></div>'),
    CONTROLS_TPL: new Template('<div id="#{CONTAINER_ID}"><div id="pannorth" class="pan"></div><div id="paneast" class="pan"></div><div id="pansouth" class="pan"></div><div id="panwest" class="pan"></div><div id="zoomin"></div><div src="#{ZOOM_OUT}" id="zoomout"></div><div id="#{ZOOMMETER_ID}"></div><div id="#{ZOOMSLIDER_ID}"></div></div>'),
    CONTROLS: {
        ZOOMIN_ID: 'zoomin',
        ZOOMOUT_ID: 'zoomout',
        ZOOMSLIDER_ID: 'zoomslider',
        ZOOMMETER_ID: 'zoommeter',
        CONTAINER_ID: 'zoomcontrol',
        PAN_CLASS: 'pan'
    },
    SMALL_CONTROLS_TPL: new Template('<div id="#{CONTAINER_ID}"><div id="pannorth" class="pan"></div><div id="paneast" class="pan"></div><div id="pansouth" class="pan"></div><div id="panwest" class="pan"></div><div id="zoomin"></div><div src="#{ZOOM_OUT}" id="zoomout" class="small"></div></div>'),
    SMALL_CONTROLS: {
        ZOOMIN_ID: 'zoomin',
        ZOOMOUT_ID: 'zoomout',
        CONTAINER_ID: 'zoomcontrol',
        PAN_CLASS: 'pan'
    }
});

MapControls.addMethods(
{
  initialize: function(mapElement, map, mode) 
  {
    this.mapElement = mapElement;
    this.map = map;
    this.mapMode = mode;

    if (this.mapMode == MapControls.MODE_NORMAL)
    {
      this.mapElement.insert(MapControls.TYPES_TPL.evaluate(MapControls.TYPES));
      this.mapElement.insert(MapControls.CONTROLS_TPL.evaluate(MapControls.CONTROLS));
      $(MapControls.TYPES.MAP_ID).observe('click', this.clickType.bindAsEventListener(this));
      $(MapControls.TYPES.HYB_ID).observe('click', this.clickType.bindAsEventListener(this));
      $(MapControls.TYPES.SAT_ID).observe('click', this.clickType.bindAsEventListener(this));      
    }
    else
    {
      this.mapElement.insert(MapControls.SMALL_CONTROLS_TPL.evaluate(MapControls.SMALL_CONTROLS));
    }

    this.dragSliderListener = this.dragSlider.bindAsEventListener(this);
    this.placeSliderListener = this.placeSlider.bindAsEventListener(this);

    if (this.mapMode == MapControls.MODE_NORMAL)
    {
      this.slider = $(MapControls.CONTROLS.ZOOMSLIDER_ID);
    }

    $(MapControls.CONTROLS.CONTAINER_ID).select('.'+MapControls.CONTROLS.PAN_CLASS).invoke('observe', 'click', this.pan.bindAsEventListener(this));

    $(MapControls.CONTROLS.ZOOMIN_ID).observe('click', this.zoomIn.bindAsEventListener(this));
    $(MapControls.CONTROLS.ZOOMOUT_ID).observe('click', this.zoomOut.bindAsEventListener(this));

    if (this.mapMode == MapControls.MODE_NORMAL)
    {
      $(MapControls.CONTROLS.ZOOMSLIDER_ID).observe('mousedown', this.clickSlider.bindAsEventListener(this)); 
    }
    MQEventManager.addListener(this.map, 'zoomend', this.setSliderPosition.bindAsEventListener(this));

    this.setSliderPosition();
  },
  clickType: function(event) 
  {
      this.setMapByType(event.target.className);
  },
  setMapByType: function(type) 
  {
      this.map.setMapType(type);
      document.fire('maptype:change');
  },
  setSliderPosition: function() 
  {
    var moveTo = -Math.floor(this.map.getZoomLevel()*4.875)+150;

    if (this.mapMode == MapControls.MODE_NORMAL)
    {
      this.slider.setStyle({ top: moveTo+'px' });
    }
    document.fire('zoom:change');
  },
  setZoomFromSlider: function() 
  {
    var slidePos = parseInt(this.slider.getStyle('top'), 10);

    var zoomTo = -(Math.floor(slidePos/4.875)+14)+45;
    this.map.setZoomLevel(zoomTo);

    if(this.parent) { this.parent.setModel('zoom', zoomTo); }
    document.fire('zoom:change');
  },
  clickSlider: function(event) 
  {
    $('zoomslider').stopObserving('mousedown'); 

    document.observe('mousemove', this.dragSliderListener); 
    document.observe('mouseup', this.placeSliderListener); 
  },
  dragSlider: function(event) 
  {
    var newPos = event.clientY-$('zoomcontrol').cumulativeOffset()[1]+$('zoomcontrol').cumulativeScrollOffset()[1];

    if(newPos >= parseInt($('zoommeter').getStyle('top'), 10) && 
      newPos <= ($('zoommeter').getHeight()+parseInt($('zoommeter').getStyle('top'), 10))
    ) {
      this.slider.setStyle({ top: newPos+'px' });
    }
  },
  placeSlider: function(event) 
  {
    this.setZoomFromSlider();

    $('zoomslider').observe('mousedown', this.clickSlider.bindAsEventListener(this)); 

    document.stopObserving('mousemove', this.dragSliderListener);
    document.stopObserving('mouseup', this.placeSliderListener);
  } ,
  pan: function(event) 
  {
    var direction = event.element().id;
    this.panByDirection(direction);
  },
  panByDirection: function(direction) 
  {
    /*
      TODO fix panning over the "edge of the world" pacific ocean where we reset to 0
      TODO return case for going off the top and bottom poles
    */
    var lat = this.map.getCenter().lat;
    var lng = this.map.getCenter().lng;

    // calculate the pan distance as half the width/height of the current view
    var latPan = Math.abs(this.map.getBounds().ul.lat - this.map.getBounds().lr.lat)/2;
    var lngPan = Math.abs(this.map.getBounds().ul.lng - this.map.getBounds().lr.lng)/2;

    switch(direction) {
      case "pannorth" :
        lat = lat+latPan;
      break;
      case "paneast" :
        lng = lng+lngPan;
      break;
      case "pansouth" :
        lat = lat-latPan;
      break;
      case "panwest" :
        lng = lng-lngPan
      break;
      default :
        lat = 0;
        lng = 0;
      break;
    }   

    this.map.panToLatLng(new MQLatLng(lat, lng));
  },
  zoomIn: function() 
  {
    var currentZoomLevel = this.map.getZoomLevel();

    // Check valid zoom level
    if(currentZoomLevel == 16) { return; }

    currentZoomLevel++;

    if(this.parent) { this.parent.setModel('zoom', currentZoomLevel); }
    this.map.setZoomLevel(currentZoomLevel);
    this.setSliderPosition();
  },
  zoomOut: function() 
  {
    var currentZoomLevel = this.map.getZoomLevel();

    // Check valid zoom level
    if(currentZoomLevel == 1) { return; }

    currentZoomLevel--;

    if(this.parent) { this.parent.setModel('zoom', currentZoomLevel); }
    this.map.setZoomLevel(currentZoomLevel);
    this.setSliderPosition();
  }
});
/* Location
 * Every result to be placed on the map is an instance of Location
 */
MapLocation = Class.create({});

Object.extend(MapLocation, {
    IMAGES: {
        FHR_POINT: '/images/map/map-point-fhr.png',
        FHR_DECLUTTER: '/images/map/map-point-declutter-fhr.png',
        FHR_POINT_SELECTED: '/images/map/map-point-fhr.png',
        FHR_DECLUTTER_SELECTED: '/images/map/map-point-declutter-fhr.png',
        PDL_POINT: '/images/map/map-point-pdl.png',
        PDL_DECLUTTER: '/images/map/map-point-declutter-pdl.png',
        PDL_POINT_SELECTED: '/images/map/map-point-pdl.png',
        PDL_DECLUTTER_SELECTED: '/images/map/map-point-declutter-pdl.png',
        TSO_POINT: '/images/map/map-point-tso.png',
        TSO_DECLUTTER: '/images/map/map-point-declutter-tso.png',
        TSO_POINT_SELECTED: '/images/map/map-point-tso-selected.png',
        TSO_DECLUTTER_SELECTED: '/images/map/map-point-declutter-tso-selected.png',
        ICON_WIDTH: 34,
        ICON_HEIGHT: 62,
        ICON_OFFSET_X: -17,
        ICON_OFFSET_Y: -61,
        ICON_DECLUTTER_WIDTH: 34,
        ICON_DECLUTTER_HEIGHT: 42,
        ICON_DECLUTTER_OFFSET_X: -17,
        ICON_DECLUTTER_OFFSET_Y: -41,
        SHADOW_POINT: '/images/map/map-point-shadow.png',
        SHADOW_WIDTH: 49,
        SHADOW_HEIGHT: 49,
        SHADOW_OFFSET_X: 1,
        SHADOW_OFFSET_Y: 17,
        SHADOW_DECLUTTER: '/images/map/map-point-declutter-shadow.png',
        SHADOW_DECLUTTER_WIDTH: 47,
        SHADOW_DECLUTTER_HEIGHT: 37,
        SHADOW_DECLUTTER_OFFSET_X: 2,
        SHADOW_DECLUTTER_OFFSET_Y: 20
    },
    
    STRINGS: {
        short_distance: 'less than 0.5'
    }
});

MapLocation.addMethods(
{
  initialize: function(parent, data, index, displayNumber, printable) 
  {
    console.log("new MapLocation")
    console.log("MapLocation", arguments)
    this.data = data;
    this.index = index;
    this.locationType = this.data.locationType;
    this.modelType = 'locations';
    this.parent = parent;
    this.parentMap = parent.map;
    
    this.printable = printable || false;

    this.data.index = displayNumber;
    if (this.data.phone != null)
    {
      this.data.phone = this.data.phone.gsub(/[\s,-]/, '.');
      this.data.phone = this.data.phone.gsub(/['(',')']/, '');
    }
    if(Number(this.data.distance)) 
    {
      this.data.distance = Math.round(this.data.distance*10)/10;
      if(this.data.distance < 0.5) 
      { 
        this.data.distance = MapLocation.STRINGS.short_distance;
      }
    }
    if(this.data.distance === 1 && this.data.units === 'miles') 
    {
      this.data.units = 'mile';
    } 

    if (this.data.includeOnMap)
    {
      this.create();
    }
  },
  
  showSelected: function ()
  {
    if (this.poi) {
  		this.poi.setIcon(this.mapIconSelected);
      this.poi.setAltIcon(this.mapAltIconSelected);
    }
  },
  showDeselected: function ()
  {
    if (this.poi) {
      this.poi.setIcon(this.mapIcon);
      this.poi.setAltIcon(this.mapAltIcon);
    }
  },
	setIcon: function() 
	{
		this.mapIcon = new MQMapIcon();
		this.mapAltIcon = new MQMapIcon();
		
		this.mapIconSelected = new MQMapIcon();
		this.mapAltIconSelected = new MQMapIcon();
		
		switch(this.data.locationType) 
		{
			case 'TSO':
			this.mapIcon.setImage(
          this.printableImage(MapLocation.IMAGES.TSO_POINT), 
			    MapLocation.IMAGES.ICON_WIDTH, 
			    MapLocation.IMAGES.ICON_HEIGHT, 
			    true, 
			    true
			); 
			this.mapAltIcon.setImage(
			    this.printableImage(MapLocation.IMAGES.TSO_DECLUTTER),  
			    MapLocation.IMAGES.ICON_DECLUTTER_WIDTH, 
			    MapLocation.IMAGES.ICON_DECLUTTER_HEIGHT, 
			    true, 
			    true
			);
			this.mapIconSelected.setImage(
          this.printableImage(MapLocation.IMAGES.TSO_POINT_SELECTED), 
  		    MapLocation.IMAGES.ICON_WIDTH, 
  		    MapLocation.IMAGES.ICON_HEIGHT, 
  		    true, 
  		    true
  		); 
  		this.mapAltIconSelected.setImage(
  		    this.printableImage(MapLocation.IMAGES.TSO_DECLUTTER_SELECTED),  
  		    MapLocation.IMAGES.ICON_DECLUTTER_WIDTH, 
  		    MapLocation.IMAGES.ICON_DECLUTTER_HEIGHT, 
  		    true, 
  		    true
  		);
			
			break;

			case 'FHR':
			this.mapIcon.setImage(
			    MapLocation.IMAGES.FHR_POINT, 
			    MapLocation.IMAGES.ICON_WIDTH, 
			    MapLocation.IMAGES.ICON_HEIGHT, 
			    true, 
			    true
			); 
			this.mapAltIcon.setImage(
			    MapLocation.IMAGES.FHR_DECLUTTER,
			    MapLocation.IMAGES.ICON_DECLUTTER_WIDTH, 
			    MapLocation.IMAGES.ICON_DECLUTTER_HEIGHT, 
			    true, 
			    true
			); 
			this.mapIconSelected.setImage(
			    MapLocation.IMAGES.FHR_POINT_SELECTED, 
			    MapLocation.IMAGES.ICON_WIDTH, 
			    MapLocation.IMAGES.ICON_HEIGHT, 
			    true, 
			    true
			); 
			this.mapAltIconSelected.setImage(
			    MapLocation.IMAGES.FHR_DECLUTTER_SELECTED,
			    MapLocation.IMAGES.ICON_DECLUTTER_WIDTH, 
			    MapLocation.IMAGES.ICON_DECLUTTER_HEIGHT, 
			    true, 
			    true
			);
			break;

			case 'PDL':
			this.mapIcon.setImage(
			    MapLocation.IMAGES.PDL_POINT, 
			    MapLocation.IMAGES.ICON_WIDTH, 
			    MapLocation.IMAGES.ICON_HEIGHT, 
			    true, 
			    true
			); 
			this.mapAltIcon.setImage(
			    MapLocation.IMAGES.PDL_DECLUTTER,
			    MapLocation.IMAGES.ICON_DECLUTTER_WIDTH, 
			    MapLocation.IMAGES.ICON_DECLUTTER_HEIGHT, 
			    true, 
			    true
			); 
			this.mapIconSelected.setImage(
			    MapLocation.IMAGES.PDL_POINT_SELECTED, 
			    MapLocation.IMAGES.ICON_WIDTH, 
			    MapLocation.IMAGES.ICON_HEIGHT, 
			    true, 
			    true
			); 
			this.mapAltIconSelected.setImage(
			    MapLocation.IMAGES.PDL_DECLUTTER_SELECTED,
			    MapLocation.IMAGES.ICON_DECLUTTER_WIDTH, 
			    MapLocation.IMAGES.ICON_DECLUTTER_HEIGHT, 
			    true, 
			    true
			);
			break;
		}
		
		this.mapIcon.setAnchorOffset(new MQPoint(MapLocation.IMAGES.ICON_OFFSET_X, MapLocation.IMAGES.ICON_OFFSET_Y));
		this.mapAltIcon.setAnchorOffset(new MQPoint(MapLocation.IMAGES.ICON_DECLUTTER_OFFSET_X, MapLocation.IMAGES.ICON_DECLUTTER_OFFSET_Y));		
		this.mapIconSelected.setAnchorOffset(new MQPoint(MapLocation.IMAGES.ICON_OFFSET_X, MapLocation.IMAGES.ICON_OFFSET_Y));
		this.mapAltIconSelected.setAnchorOffset(new MQPoint(MapLocation.IMAGES.ICON_DECLUTTER_OFFSET_X, MapLocation.IMAGES.ICON_DECLUTTER_OFFSET_Y));
		
		// IE was not properly printing drop shadows / transparent images on maps
		// so we intentionally omit shadows for those browsers.
    if (this.shouldFixPrintingForIE() == false) {
      this.addShadows();
    }
    
	},
	
	shouldFixPrintingForIE: function() {
    return (this.printable && Prototype.Browser.IE);
	},
	
	printableImage: function(image_uri) {
	  if (this.shouldFixPrintingForIE()) {
	    /* replace with 8-bit PNG images, tailored for IE */
	    return image_uri.replace(/\.png$/, '-opaque.png');
	  } else {
	    return image_uri;
	  }
	},
	
	addShadows: function() {
		this.mapIcon.setShadow(
		    MapLocation.IMAGES.SHADOW_POINT, 
		    MapLocation.IMAGES.SHADOW_OFFSET_X, 
		    MapLocation.IMAGES.SHADOW_OFFSET_Y, 
		    MapLocation.IMAGES.SHADOW_WIDTH, 
		    MapLocation.IMAGES.SHADOW_HEIGHT, 
		    true
		); 
		this.mapAltIcon.setShadow(
		    MapLocation.IMAGES.SHADOW_DECLUTTER, 
		    MapLocation.IMAGES.SHADOW_DECLUTTER_OFFSET_X, 
		    MapLocation.IMAGES.SHADOW_DECLUTTER_OFFSET_Y, 
		    MapLocation.IMAGES.SHADOW_DECLUTTER_WIDTH, 
		    MapLocation.IMAGES.SHADOW_DECLUTTER_HEIGHT, 
		    true
		); 
		this.mapIconSelected.setShadow(
		    MapLocation.IMAGES.SHADOW_POINT, 
		    MapLocation.IMAGES.SHADOW_OFFSET_X, 
		    MapLocation.IMAGES.SHADOW_OFFSET_Y, 
		    MapLocation.IMAGES.SHADOW_WIDTH, 
		    MapLocation.IMAGES.SHADOW_HEIGHT, 
		    true
		); 
		this.mapAltIconSelected.setShadow(
		    MapLocation.IMAGES.SHADOW_DECLUTTER, 
		    MapLocation.IMAGES.SHADOW_DECLUTTER_OFFSET_X, 
		    MapLocation.IMAGES.SHADOW_DECLUTTER_OFFSET_Y, 
		    MapLocation.IMAGES.SHADOW_DECLUTTER_WIDTH, 
		    MapLocation.IMAGES.SHADOW_DECLUTTER_HEIGHT, 
		    true
		);     
  },
  
	createPoint: function() 
	{
    this.setIcon();
    this.poi = new MQPoi(new MQLatLng(this.data.latitude, this.data.longitude));
    this.poi.setIcon(this.mapIcon);
    this.poi.setAltIcon(this.mapAltIcon);
    this.poi.setDraggable(false);

    if(this.data.id) 
    { 
      this.poi.setKey(this.data.id); 
    }

    this.poi.element.addClassName(this.locationType);
    if(this.data.index >= 0) 
    { 
      this.poi.element.insert('<div class="count">' + Number(this.data.index) + '</div>'); 
    }
    this.parentMap.addPoi(this.poi);
    this.poi.element.setStyle({ cursor: 'pointer' });
	},
  create: function() 
  {
    this.createPoint();

    // check if the point has an index in the display to add to the map model collection of locations
    this.parent.model.get(this.modelType + 'Collection').add(this.poi);

	MQEventManager.addListener(this.poi, "click", this.selectPoint.bindAsEventListener(this));
    //this.poi.element.observe('click', this.selectPoint.bindAsEventListener(this));
  },
  selectPoint: function(event) 
  {
    if(event) 
    {
      //event.stop();
      document.fire('office:selected', String(this.index));
    }
  }
});
