var startMils = new Date().valueOf();

var DestinationMap = function($wrapper, location, btPickHotels, readerPickHotels)
{
	var that = this;
	var config = null;
	var gmap = null;
	var attractionsMenu = null;
	var geocoder = new GClientGeocoder();
	var streetviewClient = new GStreetviewClient();
	var attractionMarkers = new Array();
	var isInitialized = false;
	var isItemsLoaded = false;
	var isStyled = false;
	var $itemTmpl = $('#map-item-tmpl');

	var attractionIcon = DestinationMap.createAttractionIcon();
	that.btPickHotels = btPickHotels;
	that.readerPickHotels = readerPickHotels;

	//TODO: This is getting called to soon. It should only get called if the map
	//		gets opened.
	getMapConfig();

	
	// private functions
	function setUpEvents()
	{
		if (attractionsMenu)
		{
			$wrapper.find('.chooser .reader-picks').click(function(){
				that.showHotels(that.readerPickHotels);
				if (attractionsMenu.isActive)
					that.showAttractions();

				selectTab($(this));
			});

			$wrapper.find('.chooser .bt-picks').click(function(){
				that.showHotels(that.btPickHotels);
				if ( attractionsMenu.isActive)
					that.showAttractions();

				selectTab($(this));
			});
		}

		$wrapper.find('.close-street-view').click( function() {
			hideStreetView();
		});
	}

	function getMapConfig()
	{
		var configDir = BT.page.incUrl + '/config.json';
		$.getJSON(configDir,  function(data){
			config = data;
		});
	}

	function initMap()
	{	
		gmap = new GMap2($wrapper.find('.gmap').get(0));
		gmap.addControl(new GLargeMapControl());

		var centerLatLng = null;

		if (config != null)
		{
			gmap.setCenter(new GLatLng(config.lat, config.lng), 12);
		}
		else
		{
			geocoder.getLatLng(location, function(latlng) {
				if (latlng)
					gmap.setCenter(latlng, 12);
			});
		}
		
		attractionsMenu = new AttractionsMenu($('#map-attractions'), that, $('#attractions-link'));

		setUpEvents();

		isInitialized = true;
	}

	function createMarker(hotel, gmap)
	{
		var html = makeInfoWindowHtml(hotel);
		enableStreetViewLink($(html), hotel.latlng, hotel);
		var hotelIcon = DestinationMap.createHotelIcon();		
		var marker = new GMarker(hotel.latlng, { icon: hotelIcon});

		GEvent.addListener(marker, 'click', function() {
			marker.openInfoWindow(html, {maxWidth: 200});
		});

		gmap.addOverlay(marker);
	}

	function showStreetView(latlng, $error, hotel)
	{
		var options = {
			latlng: latlng,
			features: {userPhotos: false}
		}
		var $sv = $wrapper.find('#street-view');
		var myPano = new GStreetviewPanorama($sv.get(0), options);
		GEvent.addListener(myPano, "error", function(errorCode){
			$error.html('Sorry, Street View is not available for this location').addClass('error');
			// TODO: This is a kludge. It would be better to not show the
			// Street View in the first place
			hideStreetView();
		});

		$sv.show();
		$wrapper.find('.chooser').hide();
		$wrapper.find('#street-view-info').show().find('h3 span').html('Near <a href="'+ hotel.contentUrl +'" target="_blank">' + hotel.title + '</a>');
		$wrapper.find('#attractions-link').hide();
	}

	function hideStreetView()
	{
		$wrapper.find('#street-view').hide();
		$wrapper.find('#street-view-info').hide();
		$wrapper.find('#attractions-link').show();
		$wrapper.find('.chooser').show();
	}

	function enableStreetViewLink($mapItem, latlng, hotel)
	{
		$mapItem.find('.street-view').bind('click', latlng ,function(event){
			event.preventDefault();
			showStreetView(event.data, $(this), hotel);
		});
	}

	function makeInfoWindowHtml(mapItem)
	{
		return $itemTmpl.jqote(mapItem).get(0).get(0);
	}

	// privileged functions
	this.showMap = function()
	{
		$wrapper.show(); 
		if (!isInitialized)
			initMap();

		if (!isItemsLoaded)
			that.showEditorPickHotels();

		that.styleMap();
	}
	
	this.hide = function()
	{
		$wrapper.hide();
	}

	this.styleMap = function()
	{
		if (!isStyled)
		{
			curvyCorners({
				tl: { radius: 10 },
				tr: { radius: 10 },
				bl: { radius: 10 },
				br: { radius: 10 }
			} , '#detail-map .map-wrapper');
		}
	}

	this.showHotels = function(hotels)
	{
		gmap.clearOverlays();
		for ( var i=0; i<hotels.length; ++i )
		{
			createMarker(hotels[i],  gmap);
		}
		isItemsLoaded = true;
	}
	
	this.showEditorPickHotels = function()
	{
		that.showHotels(btPickHotels);
	}

	this.showReaderPickHotels = function()
	{
		that.showHotels(readerPickHotels);
	}

	this.addAttraction = function(attractionName, attractionNumber, latlong, title)
	{
		if (!attractionMarkers[attractionNumber])
		{
			if (latlong == null)
			{
				geocoder.getLatLng(attractionName + ' ' + BT.page.destinationName, function(latlng) {
					if (latlng)
					{
						that.createAttractionMarker(latlng, attractionNumber, title);
					}
				});
			}
			else
			{
				that.createAttractionMarker(latlong, attractionNumber, title);
			}
		}
		else
		{
			gmap.addOverlay(attractionMarkers[attractionNumber]);
		}
	}

	this.createAttractionMarker = function(latlong, attractionNumber, title)
	{
		var opts = {
			icon: attractionIcon,
			clickable: false,
			labelText: new String(attractionNumber),
			labelOffset: new GSize(0, 0),
			labelClass: 'attraction-marker',
			title: title
		};
		var marker = new LabeledMarker(latlong, opts);

		gmap.addOverlay(marker);
		attractionMarkers[attractionNumber] = marker;
	}

	this.showAttractions = function()
	{
		for (var i=1; i<= attractionMarkers.length; i++)
		{
			if (attractionsMenu.isItemSelected(i))
				gmap.addOverlay(attractionMarkers[i]);
		}
	}

	this.hideAttraction = function(attractionNumber)
	{
		gmap.removeOverlay(attractionMarkers[attractionNumber])
	}

	this.hideAllAttractions = function()
	{
		_.each(attractionMarkers, function(aMarker){
			if (aMarker)
				gmap.removeOverlay(aMarker);
		});
		attractionsMenu.isActive = false;
	}


}

// Static functions
DestinationMap.createAttractionIcon = function()
{
	return DestinationMap.createIcon('icon-map-circle-shadow.png');
}

DestinationMap.createHotelIcon = function()
{
	return DestinationMap.createIcon('icon-gmap-hotel-shadow.png');
}

DestinationMap.createIcon = function(imgFilename)
{
	var baseUrl = BT.uiBaseUrl + '/img/';
	var icon = new GIcon();
	icon.image = baseUrl + imgFilename;
	icon.iconAnchor = new GPoint(0,0);
	icon.infoWindowAnchor = new GPoint(10,0);
	return icon;
}

DestinationMap.createTags = function(compositeLoc, interests, lifestyles)
{
	var tagUrlPrefix = "<a href=/bt-dynsrch/hotels/destination-hotels.html?destination=";
	tagUrlPrefix = tagUrlPrefix + compositeLoc;

	var tagsStrMain = "";
	var category;

	if (lifestyles != "")
	{
		var lifestylesArray = lifestyles.split("|");
		for (var x=0; x<lifestylesArray.length ; x++)
		{
			category = lifestylesArray[x].replace(/ /g,"%20");
			tagsStrMain = tagsStrMain + tagUrlPrefix + "&lifestyle=" + category + " target='_blank'>"+lifestylesArray[x]+ "</a>" + ", ";
		}
	}

	if (interests != "")
	{
		var interestsArray = interests.split("|");
		for (var x=0; x<interestsArray.length ; x++)
		{
			category = interestsArray[x].replace(/ /g,"%20");
			tagsStrMain = tagsStrMain + tagUrlPrefix + "&interests=" + category + " target='_blank'>"+interestsArray[x]+ "</a>" + ", ";
		}
	}

	// KLUDGE: trim the last comma off
	tagsStrMain = tagsStrMain.substring(0, tagsStrMain.length - 2);
	return tagsStrMain;
}

