AMEXMessageBox = Class.create({});
Object.extend(AMEXMessageBox, {
    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>',
    LOADING_TPL: new Template('<img src="#{load_img}" alt="" /><p class="loading">#{load_msg}</p>'),
    CONTENT_TPL: new Template(
        '<h2>#{header}</h2> \
        <p>#{content}</p> \
        <p><a class="continue" href="#{action_link}">#{action}</a></p>'
    )
});

AMEXMap = Class.create({});
Object.extend(AMEXMap, {
    // GEOCODE_SERVER: 'geocode.dev.mapquest.com',
    // SPATIAL_SERVER: 'spatial.dev.mapquest.com',
    GEOCODE_SERVER: 'geocode.access.mapquest.com',
    SPATIAL_SERVER: 'spatial.access.mapquest.com',
    GEOCODE_PATH: 'mq',
    GEOCODE_PORT: '80',
    PROXY_SERVER: 'www.aetclocator.com', // no trailing slash!
    //PROXY_PORT: '80',
    REQUEST_HANDLER: 'JSReqHandler',
    DATA_LOCATION: 'search.json', // path for GET calls to the server for location information
    DATA_MIME_TYPE: 'application/json', // data response header type
    MAP_ELEMENT_ID: 'MapView',
    MAP_HEIGHT: '550',
    MAP_WIDTH: '657',
    POI_CODES: $H({
        'hotels': [ 7011 ],
        'dining': [ 9996, 5800 ],
        'landmarks' : [ 7996, 7992, 5999, 8060,8410, 7947, 9221, 7940, 7999, 7389 ],
        'transportation' : [ 4581, 8699, 4170, 4100, 4482, 5540, 7510, 7897, 4013 ]
    }),
    POI_MATCHES: 25,
    POI_ICON: 'images/map-point.png',
    POI_WIDTH: 25,
    POI_HEIGHT: 27,
    POI_OFFSET_X: -10,
    POI_OFFSET_Y: -22,
    POI_SHADOW: 'images/map-point-shadow.png',
    POI_SHADOW_WIDTH: 24,
    POI_SHADOW_HEIGHT: 18,
    POI_SHADOW_OFFSET_X: 10,
    POI_SHADOW_OFFSET_Y: 10,
    RESULTS_PER_PAGE: 10,
    /* ${environment.js.start}
    GEOCODE_SERVER: '${environment.mq.geocode.host}',
    SPATIAL_SERVER: '${environment.mq.spatial.host}',
    PROXY_SERVER: '${environment.proxyServer}', // no trailing slash!
    PROXY_PORT: '${environment.proxyPort}',
    ${environment.js.end} */
    RESULT_IW_TPL: new Template(
        '<div class="adr"> \
            <div class="street-address">#{street}</div> \
            <span class="locality">#{city}</span>, \
            <span class="region">#{state}</span> \
            <span class="postal-code">#{postCode}</span> \
        </div>'
    ),
  	MODEL: $H({ // Defaults for AMEXMap.instance.model
        zoom: 1, // 1-16
        maptype: 'map', // 'map', 'sat', 'hyb'
        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
            feefree: true,
            feebased: true,
            dining: false,
            hotels: false,
            landmarks: false,
            transportation: false
        }), // filter types displayed on the map
        page: 0, // current page of result list
        locations: [], // locations returned for the current query from the server
        locationsCollection: new MQPoiCollection(), // MapQuest point collection
        currentLocations: [], // locations currently on the map
        mapLocations: [], // points currently on the map
        mapPOIs: []
    })
});

/* AMEXPreloader
 * takes an array of image URLs to load
 * fires document.images:loaded on complete
 */
AMEXPreloader = Class.create({
    preload: function(images) {
        this.loaded = [];
        images.each(function(image) {
            var img = new Image();
            img.onload = this.checkLoaded(img, images);
            img.src = image;
        }.bind(this));
    },
    checkLoaded: function(img, images) {
        this.loaded.push(img);
        if(this.loaded.length === images.length) {
            document.fire('images:loaded');
        }
    }
});
AMEXPreloader.instance = new AMEXPreloader();


/* AMEXMessageBox
 * displays a small box above the map for information and warnings
 */
AMEXMessageBox.addMethods({
    initialize: function() {
        $$('body')[0].insert(AMEXMessageBox.BOX_HTML);
        
        this.loadingImage = new Image();
        this.loadingImage.src = AMEXGlobal.APPLICATION_ROOT+AMEXMessageBox.LOADING_IMAGE;
         
        this.box = $('MessageBox');
        this.content = this.box.down('#loadingContent');
        
        this.loadingContent = AMEXMessageBox.LOADING_TPL.evaluate({ 
            load_img: AMEXGlobal.APPLICATION_ROOT+AMEXMessageBox.LOADING_IMAGE, 
            load_msg: Lang.STRINGS.loading 
        });
 
        this.showLoading();
    },
    showLoading: function() {
        this.box.show();
        $('MessageContent').update(this.loadingContent);
        this.setPosition();
    },
    setPosition: function() {
        var mapHeightCenter = Math.round(Number($(AMEXMap.MAP_ELEMENT_ID).getStyle('height').replace('px', ''))/2)+$(AMEXMap.MAP_ELEMENT_ID).cumulativeOffset()[1];
        var mapWidthCenter = Math.round(Number($(AMEXMap.MAP_ELEMENT_ID).getStyle('width').replace('px', ''))/2)+$(AMEXMap.MAP_ELEMENT_ID).cumulativeOffset()[0];
        
        var heightCenter = Math.round(Number(this.box.offsetHeight.toString().replace('px', ''))/2);
        var widthCenter = Math.round(Number(this.box.offsetWidth.toString().replace('px', ''))/2);
        
        this.box.setStyle({ top: mapHeightCenter-heightCenter+'px', left: mapWidthCenter-widthCenter+'px' });
    },
    hide: function(event) {
		// Logging which method called hide
		// TODO: Find callback for tiles loaded from MQTileMap to trigger this hide; currently being called from updateLocations() before map tiles are fully loaded
        if(event) { event.stop(); }
        this.box.hide();
    },
    showMessage: function(message) {
        $('MessageContent').update(AMEXMessageBox.CONTENT_TPL.evaluate(message));

        this.box.show();
        if(
            (!message.action || message.action.blank()) && 
            (!message.action_link || message.action_link.blank())
        ) {
            $('MessageContent').select('p')[1].remove();
        } else {
            if($('MessageContent').down('a').href.indexOf('#') != -1) {
                $('MessageContent').down('a').stopObserving('click');
                $('MessageContent').down('a').observe('click', this.hide.bindAsEventListener(this));
            }
        }
        this.setPosition();
    }
});


AMEXMap.addMethods({
    initialize: function() {
        Object.extend(Lang.STRINGS.general_error, {
            action: Lang.STRINGS.actions.landing_link,
            action_link: AMEXGlobal.APPLICATION_ROOT+Lang.LANG_URL+AMEXGlobal.PAGES.LANDING
        });

        this.messageBox = new AMEXMessageBox();
        this.messageBox.showLoading();
        
        this.model = AMEXMap.MODEL;
        this.queryParams = window.location.href.split('?')[1] || '';
        if(!this.queryParams.blank()) { this.queryParams = this.queryParams.toQueryParams(); }
        
        $('LocationTypes').select('input').invoke('observe', 'click', function(event) {
            var value = false;
            if(event.target.getValue()) { value = true; }
            this.model.get('display').set(event.target.id.replace('opt_', ''), value);

            this.updateLocations();
        }.bind(this));
        $('POI').select('input').invoke('observe', 'click', function(event) {
            this.messageBox.showLoading();
            var value = false;
            var type = event.target.id.replace('cb_', '');
            // we give ourselves 1/2 of a second here so the messageBox has time to display before doing the search
            // the search is not asynchronous, so it kills all other processes
            setTimeout(function() {
                if(event.target.getValue()) { 
                    value = true; 
                    this.getPOIs(type);
                } else {
                    this.clearPOIs(type);
                }
                this.model.get('display').set(type, value);
            }.bind(this), 500);
            
        }.bind(this));
		
		    this.mapInit = new MQMapInit();

        try {
            this.resultList = new AMEXResultList();
                        
            this.geocoder = new MQExec(AMEXMap.GEOCODE_SERVER, AMEXMap.GEOCODE_PATH, AMEXMap.GEOCODE_PORT, AMEXMap.PROXY_SERVER, AMEXMap.REQUEST_HANDLER, AMEXMap.PROXY_PORT);
            this.spatial = new MQExec(AMEXMap.SPATIAL_SERVER, AMEXMap.GEOCODE_PATH, AMEXMap.GEOCODE_PORT, AMEXMap.PROXY_SERVER, AMEXMap.REQUEST_HANDLER, AMEXMap.PROXY_PORT);
          	
            document.observe('search:submit', this.geocode.bindAsEventListener(this));
            
            // used for the model:change events to update the display
            this.upbfx = this.updateLocations.bindAsEventListener(this);
        } catch(error) {
            this.messageBox.showMessage(Lang.STRINGS.general_error);
        }
    },
	buildMap: function() {
		this.mapElement = $(AMEXMap.MAP_ELEMENT_ID);

        // fix for IE forever loading map tiles
        // https://trc.mapquest.com:443/jforum/posts/list/881.page
        $(this.mapElement).setStyle({ width: AMEXMap.MAP_WIDTH+'px', height: AMEXMap.MAP_HEIGHT+'px' });
        this.map = new MQTileMap(this.mapElement, null, null, 'map', this.mapInit);
        this.map.setSize(new MQSize(AMEXMap.MAP_WIDTH, AMEXMap.MAP_HEIGHT));

        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.getDeclutter().setDeclutterMode(2);

        this.mapcontrols = new AMEXMapControls(this);
		this.infoWindow = new AMEXInfoWindow(this);
	},
    setModel: function(key, value) {
        this.model.set(key, value); 
    },
    geocode: function() {
        this.messageBox.showLoading();
        if (this.map) {
			this.map.removeAllPois();
			this.infoWindow.hide();
		}
        $('POI').select('input').each(function(poi) { poi.setValue(null); });
        this.model.set('mapPOIs', []);
 
        if(AMEXSearchForm.instance.isValidSearch()) {
            var query = AMEXSearchForm.instance.getSearchRequest();

            this.setModel('searchterms', query.resultstring);
            this.setModel('query', query.address);
            this.setModel('page', 0);

            this.collection = new MQLocationCollection('MQGeoAddress');

            this.geocoder.geocode(query.address, this.collection, new MQAutoGeocodeCovSwitch());
            this.receiveGeocode();
        } else {
            this.messageBox.hide();
            if(
                AMEXSearchForm.instance.getAbilities('geocode') == 'City' || 
                AMEXSearchForm.instance.getAbilities('geocode') == 'Address'
            ) {
                this.messageBox.showMessage({
                    header: Lang.STRINGS.city_empty.header,
                    content: Lang.STRINGS.city_empty.content,
                    action: Lang.STRINGS.actions.landing_link,
                    action_link: '#'
                });
            } else {
                this.messageBox.showMessage({
                    header: Lang.STRINGS.city_postal_empty.header,
                    content: Lang.STRINGS.city_postal_empty.content,
                    action: Lang.STRINGS.actions.landing_link,
                    action_link: '#'
                });
            }
        }
    },
    receiveGeocode: function() {
        if(this.collection.getSize() > 1 && this.resultList.bypassMultipleResults === false) {
            // return a list of the results
            this.messageBox.hide();
            this.resultList.showMultipleResults(this.collection);
            return;
        }
        
        var location = this.collection.getAt(0);
        // this.resultList.bypassNumber is 0 unless set by the multiple search results
        // Commented this out to fix problem with search for airport code with no city returning no results
        // if(location.getCity() === '' && location.getStreet() === '') {
        //     // error out
        //     this.messageBox.hide();
        //     this.resultList.showError(Lang.STRINGS.bad_search, this);
        //     return;
        // }
        var searchPointData = {
            lat: location.getMQLatLng().lat,
            lng: location.getMQLatLng().lng,
            data: location.getMQLatLng
        };

        this.setSearchPoint(searchPointData);
        
        this.setModel('radius', { value: AMEXSearchForm.instance.radius, units: AMEXSearchForm.instance.radiusUnits });
        this.setModel('response', location);
        
        this.getLocations();
    },
    getLocations: function() {
        var request = new Ajax.Request(AMEXGlobal.APPLICATION_ROOT+AMEXMap.DATA_LOCATION, {
            method: 'get',
            requestHeaders: { Accept: AMEXMap.DATA_MIME_TYPE },
            parameters: { 
                latitude: this.model.get('response').getMQLatLng().lat, 
                longitude: this.model.get('response').getMQLatLng().lng, 
                radius: AMEXSearchForm.instance.getRadiusInMiles() },
            evalJSON: 'force',
            onSuccess: function(response) {
                // stop listening to the update for a moment so we don't fire the map update twice.
                // this would only happen if a search has already happened before this one.
                // see the initialize method for this.upbfx.
                document.stopObserving('model:change', this.upbfx);
                
                this.setModel('mapLocations', []);
                this.setModel('locations', response.responseJSON.concat());
                document.fire('model:change');

				if (!this.map) this.buildMap();

                setTimeout(function() {
                  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.upbfx);
                }.bind(this), 1000);
            }.bind(this),
            // check for errors getting results.
            // report general error
            onComplete: function(response) {
                if(response.transport.status !== 200) {
                    this.messageBox.showMessage(Lang.STRINGS.general_error);
                }
            }.bind(this),
            onException: function(response) {
                if(response.transport.status !== 200) {
                    this.messageBox.showMessage(Lang.STRINGS.general_error);
                }
            }.bind(this),
            onFailure: function(response) {
                this.messageBox.showMessage(Lang.STRINGS.general_error);
            }.bind(this)
      	}, true);
    },
    filterLocations: function(key, value) {
        if (Object.isArray(value)) {
            return function(item) {
                for (var j = 0; j < value.length; j++) {
                    if (item[key] === value[j]) { return true; }
                }        
            };
        } else {
            return function(item) {
                return item[key] === value;
            };   
        }
    },
    updateLocations: function() {
        this.clearLocations();
        if(this.model.get('locations').length === 0) {
            this.resultList.showError({
                header: Lang.STRINGS.no_results.header,
                content: Lang.STRINGS.no_results.content.interpolate({
                    radius: AMEXSearchForm.instance.radius,
                    units: AMEXSearchForm.instance.radiusUnits
                }),
                help_header: Lang.STRINGS.no_results.help_header,
                help_content: Lang.STRINGS.no_results.help_content
            });
            if (this.map) this.map.bestFit(false, 1, 3);
            if (this.map) this.model.set('zoom', this.map.getZoomLevel());
            this.viewSearchPoint();
            this.messageBox.hide();
            return;
        }
         
        var selectedtypes = [];
        if(this.model.get('display').get('feefree')) { selectedtypes.push('FF'); }
        if(this.model.get('display').get('feebased')) { selectedtypes.push('FB'); }
                  
        this.setModel('currentLocations', this.model.get('locations').filter(this.filterLocations('locationType', selectedtypes)));

        var maxZoomLevel = 13;
        var minZoomLevel = 1;
        if(AMEXSearchForm.instance.getAbilities('geocode') === 'City') {
            maxZoomLevel = 9; // seems to be the common max zoom until there's no map/satellite data
            minZoomLevel = 1;
        }
         // only perform the update if there were locations
        if(this.model.get('currentLocations').length >= 1) {
            var highlight;
            if(typeof(this.queryParams) == 'object') {
                highlight = this.queryParams.locationId;
                // clear the queryParams out so new searches don't try skipping ahead to an invalid id
                this.queryParams = '';
            }
            this.addLocations(this.model.get('currentLocations'), highlight);
            this.resultList.updatePages();
            if (this.map) this.map.bestFit(false, minZoomLevel, maxZoomLevel);
            this.model.set('zoom', this.map.getZoomLevel());
            
            // MapQuest isn't using SVG for lines, but a canvas instead, so there is no clear method
            // resetting declutter mode prevents stray lines from sticking around
            if(Prototype.Browser.WebKit && this.map) {
                this.map.getDeclutter().setDeclutterMode(0);
                this.map.getDeclutter().setDeclutterMode(2);
            }
            this.messageBox.hide();

            if(typeof(this.highlight) == 'number') {
                this.model.get('mapLocations')[this.highlight].selectPoint();
                this.highlight = '';
            }
        } else {
            this.resultList.showError({
                header: Lang.STRINGS.no_results.header,
                content: Lang.STRINGS.no_results.content.interpolate({
                    radius: AMEXSearchForm.instance.radius,
                    units: AMEXSearchForm.instance.radiusUnits
                }),
                help_header: Lang.STRINGS.no_results.help_header,
                help_content: Lang.STRINGS.no_results.help_content
            });
            this.messageBox.hide();
            if (this.map) this.map.bestFit(false, minZoomLevel, maxZoomLevel);
            this.viewSearchPoint();
            this.model.set('zoom', this.map.getZoomLevel());
        }
    },
    getHighlightedLocation: function(id) {
        for (var k = 0; k < this.model.get('currentLocations').length; k++) {
            if (id == this.model.get('currentLocations')[k].id) { return k; }
        }        
    },
    getPOIs: function(type) {
        try {
            var facility_codes = AMEXMap.POI_CODES.get(type);

            var extra_criteria = facility_codes.collect(function(item) {
                return item;
            }).join(',');

            var radius = Math.round(AMEXSearchForm.instance.getRadiusInMiles());

            var sCriteria = new MQRadiusSearchCriteria();
            sCriteria.setMaxMatches(AMEXMap.POI_MATCHES);
            sCriteria.setRadius(radius);
            sCriteria.setCenter(this.model.get('response').getMQLatLng());

            // setup search source
            var dbLayerQueryCollection = new MQDBLayerQueryCollection();
            var dbLayerQuery = new MQDBLayerQuery();

            var dbLayerName = 'MQA.'+AMEXSearchForm.instance.getAbilities('poidb');
            dbLayerQuery.setDBLayerName(dbLayerName);
            dbLayerQuery.setExtraCriteria('facility in (' + extra_criteria + ')');

            dbLayerQueryCollection.add(dbLayerQuery);

            // empty FeatureCollection to hold the search results
            var searchResults = new MQFeatureCollection();

            // search!
            this.spatial.search(sCriteria, searchResults, '', dbLayerQueryCollection);

            if(searchResults.getM_Items() == 0) {
                this.messageBox.hide();
                return;
            }

            var poiRecIds = new MQStringCollection();
            for (var i = 0; i < searchResults.getM_Items().length; i++) {
                poiRecIds.add(searchResults.getM_Items()[i].getKey());
            }
            // at times this search seems to hang
            var poiFieldNames = new MQStringCollection("address, phone, I, lat, lng");
            var poiResults = new MQRecordSet();

            this.spatial.getRecordInfo(poiFieldNames, dbLayerQuery, poiResults, poiRecIds);
            
            this.addPOIs(type, [searchResults, poiResults]);
        } catch(error) {
            this.messageBox.showMessage(Lang.STRINGS.general_error);
        }
    },
    addPOIs: function(type, pois) {
		this.map.getDeclutter().setDeclutterMode(0);
        var items = pois[0].getM_Items();
        
        pois[1].moveFirst();
        for(var i = 0; i < items.length; i++) {
            itemdata = {
                locationType: type,
                name: items[i].getName(),
                address: pois[1].getField('Address'),
                city: pois[1].getField('City'),
                state: pois[1].getField('State'),
                postCode: pois[1].getField('ZIP'),
                country: pois[1].getField('Country'),
                phone: pois[1].getField('Phone'),
                distance: items[i].getProperty('Distance'),
                latitude: items[i].m_CenterLatLng.lat,
                longitude: items[i].m_CenterLatLng.lng,
                id: pois[1].getField('I')
            }
            pois[1].moveNext();
            
            this.model.get('mapPOIs').push(new AMEXPOI(this, itemdata));
        }
        if(this.map.surface) { this.map.surface.clear(); }
        this.infoWindow.setPosition();
		if(this.map) this.map.getDeclutter().setDeclutterMode(2);
        this.messageBox.hide();
    },
    clearPOIs: function(type) {
        if(this.map) this.map.getDeclutter().setDeclutterMode(0);
        this.infoWindow.hide();
        var newMapPOIs = [];
        for(var i = this.model.get('mapPOIs').length-1; i >= 0; i--) {
            if(this.model.get('mapPOIs')[i].locationType === type) {
                this.map.removePoi(this.model.get('mapPOIs')[i].poi);
          
                //if(this.model.get('mapPOIs')[i].poi === this.infoWindow.poi) {
                //    this.infoWindow.hide();
                //}
            } else {
                newMapPOIs.push(this.model.get('mapPOIs')[i])
            }
        }
        this.model.set('mapPOIs', newMapPOIs);
        
        if(this.map.surface) { this.map.surface.clear(); }
        this.map.getDeclutter().setDeclutterMode(2);
        this.messageBox.hide();
    },
    clearLocations: function() {
        this.infoWindow.hide();
        this.model.get('mapLocations').each(function(thispoi) {
            this.map.removePoi(thispoi.poi);
        }.bind(this));
        this.model.get('mapLocations').length = 0;
        this.resultList.clearResults();

        if(this.map.surface) {
            this.map.surface.clear();
        }
    },
    addLocations: function(locations, highlight) {
        if(highlight) {
            highlight = this.getHighlightedLocation(highlight);
            this.model._object.page = Math.floor(highlight/AMEXMap.RESULTS_PER_PAGE);
        }
        var first = (this.model.get('page') * AMEXMap.RESULTS_PER_PAGE);
        var last = Math.min((first + AMEXMap.RESULTS_PER_PAGE), locations.length);
        var total = locations.length;
        
        if(AMEXSearchForm.instance.getAbilities('geocode') === 'City') {
            this.resultList.addWarning(AMEXResultList.WARNING_TPL.evaluate({ content: Lang.STRINGS.warnings.geocoding }));
        }
        for(var i = first; i < last; i++) {
            this.model.get('mapLocations').push(new AMEXLocation(this, locations[i], i));
            if(highlight && i == highlight) { this.highlight = Number(this.model.get('mapLocations').length-1); }
        }
this.mapInit.setBestFitRect(this.model.get('locationsCollection').getBoundingRect());
    },
    setSearchPoint: function(data) {
        var mapIcon = new MQMapIcon();
        var mapAltIcon = new MQMapIcon();

        mapIcon.setImage(
            AMEXGlobal.APPLICATION_ROOT+AMEXMap.POI_ICON, 
            AMEXMap.POI_WIDTH, 
            AMEXMap.POI_HEIGHT, 
            true, 
            true
        ); 
		mapIcon.setShadow(
		    AMEXGlobal.APPLICATION_ROOT+AMEXMap.POI_SHADOW, 
		    AMEXMap.POI_SHADOW_OFFSET_X, 
		    AMEXMap.POI_SHADOW_OFFSET_Y, 
		    AMEXMap.POI_SHADOW_WIDTH, 
		    AMEXMap.POI_SHADOW_HEIGHT, 
		    true, 
		    true
		);
		mapIcon.setAnchorOffset(new MQPoint(AMEXMap.POI_OFFSET_X, AMEXMap.POI_OFFSET_Y));
        
		mapAltIcon.setImage(
            AMEXGlobal.APPLICATION_ROOT+AMEXMap.POI_ICON, 
            AMEXMap.POI_WIDTH, 
            AMEXMap.POI_HEIGHT, 
            true, 
            true
        );
		mapAltIcon.setShadow(
		    AMEXGlobal.APPLICATION_ROOT+AMEXMap.POI_SHADOW, 
		    AMEXMap.POI_SHADOW_OFFSET_X, 
		    AMEXMap.POI_SHADOW_OFFSET_Y, 
		    AMEXMap.POI_SHADOW_WIDTH, 
		    AMEXMap.POI_SHADOW_HEIGHT, 
		    true, 
		    true
		);
		mapAltIcon.setAnchorOffset(new MQPoint(AMEXMap.POI_OFFSET_X, AMEXMap.POI_OFFSET_Y));

		this.searchPoi = new MQPoi(new MQLatLng(data.lat, data.lng));
		this.searchPoi.setIcon(mapIcon);
		this.searchPoi.setAltIcon(mapAltIcon);
		
		this.searchPoi.element.addClassName('searchPoint');
		
		if (this.map) this.map.addPoi(this.searchPoi);
		this.searchPoi.element.snapback = true;
		
		this.searchPoi.element.observe('click', this.viewSearchPoint.bindAsEventListener(this));
    },
    viewSearchPoint: function() {
        var response = this.model.get('response');
        var data = [{
            className: 'Address',
            title: Lang.STRINGS.tabs.address,
            content: AMEXMap.RESULT_IW_TPL.evaluate({
                street: response.getStreet(),
                city: response.getCity(),
                state: response.getState(),
                postCode: response.getPostalCode()
            })
        }];
        
        this.infoWindow.populate(data, this.searchPoi);
 		var latlng = new MQLatLng(this.searchPoi.getLatLng().lat, this.searchPoi.getLatLng().lng);
		var xPos = this.searchPoi.element.cumulativeOffset()[0]-$(AMEXMap.MAP_ELEMENT_ID).cumulativeOffset()[0]+(this.searchPoi.element.down('img').width/2);
		var yPos = this.searchPoi.element.cumulativeOffset()[1]-$(AMEXMap.MAP_ELEMENT_ID).cumulativeOffset()[1];
		var centerPoint = this.map.pixToLL(new MQPoint(xPos, yPos));
		
		this.infoWindow.show(centerPoint);
    }
});

AMEXMap.init = function() { 
    // before we initialize the map, we should preload some images into the browser's memory for the message box
    document.observe('images:loaded', function() {
        AMEXMap.instance = new AMEXMap();

        // fire a search on load because the form should be filled from the landing page
        // we don't do this again until someone submits a new search
        AMEXMap.instance.geocode();
        
        document.stopObserving('images:loaded');
    });
    AMEXPreloader.instance.preload([AMEXMessageBox.LOADING_IMAGE, AMEXMessageBox.BOX_IMAGE, AMEXMessageBox.BOX_IMAGE_GIF]);
};
// waiting until the window is loaded before initializing the map.
// we need AMEXSearchForm to load first, which is on dom:loaded
Event.observe(window, 'load', AMEXMap.init);
