

/**
 * Utility function to build hotel summary tiles for display in 
 * search/browse results.
 */
function construct_snapshot(hotel, parent, params, bparams, citymode) {
	var snapshot = document.createElement('div');
	snapshot.id = 'hotel_' + hotel.id;
	snapshot.className = 'object_snapshot';
	snapshot.setAttribute('name',hotel.name);
	snapshot.setAttribute('popularity',hotel.popularity);
	
	var photo = document.createElement('div');
	photo.className = "photo";
	if (hotel.image != null && hotel.image != '') {
		photo.innerHTML = '<div class="photo_inner"><a href="/lodging/' + hotel.id + '/" target="_blank"><img src="' + hotel.image + '"/></a></div>';			
	}
	snapshot.appendChild(photo);

	var info = document.createElement('div');
	info.className = "info";
	var hotelDetailUrl;
	if (params==null || params=='') {
		hotelDetailUrl = '/lodging/' + hotel.id + '/';
		infoContents = '<h1><a href="' + hotelDetailUrl + '" target="_blank">' + hotel.name + '</a>';
		infoContents += '<div id="resultIcon_' + hotel.id + '" class="resultMarkerIcon"></div>';
		infoContents += '<div class="subtitle"><a href="/lodging/city/' + hotel.city.slug + '" target="_blank">' + hotel.city.name + '</a></div></h1>';
		infoContents += hotel.description;
		infoContents += '<div class="links"><a href="' + hotelDetailUrl + '#overview" target="_blank">Hotel Overview</a> | ';
		infoContents += '<a href="' + hotelDetailUrl + '#map" target="_blank">Map</a> | ';
		infoContents += '<a href="' + hotelDetailUrl + '#photos" target="_blank">Photos</a> | ';
		infoContents += '<a href="' + hotelDetailUrl + '#reviews" target="_blank">Guest Reviews</a>';
		infoContents += '</div>';
	}
	else {
		params += '&rt=' + hotel.price;
		hotelDetailUrl = '/lodging/' + hotel.id + '/?' + params;
		infoContents = '<h1><a href="' + hotelDetailUrl + '" target="_blank">' + hotel.name + '</a>';
		infoContents += '<div id="resultIcon_' + hotel.id + '" class="resultMarkerIcon"></div>';
		infoContents += '<div class="subtitle"><a href="/lodging/city/' + hotel.city.slug + '/" target="_blank">' + hotel.city.name + '</a></div></h1>';
		infoContents += hotel.description;
		infoContents += '<div class="links"><a href="' + hotelDetailUrl + '#overview" target="_blank">Hotel Overview</a> | ';
		infoContents += '<a href="' + hotelDetailUrl + '#map" target="_blank">Map</a> | ';
		infoContents += '<a href="' + hotelDetailUrl + '#photos" target="_blank">Photos</a> | ';
		infoContents += '<a href="' + hotelDetailUrl + '#reviews" target="_blank">Guest Reviews</a>';
		infoContents += '</div>';
	}
	info.innerHTML = infoContents;
	snapshot.appendChild(info);

	var rating = document.createElement('div');
	rating.className = "rating";
	rating.innerHTML = '<a href="' + hotelDetailUrl + '#reviews" target="_blank"><img src="/site_media/images/' + hotel.fido_rating + 'bones.gif" /></a>';
	info.appendChild(rating);

	var rate = document.createElement('div');
	rate.className = "rate";
	if (hotel.has_hotrate) {
		var blueribbon = document.createElement('a');
		blueribbon.innerHTML = '<img onclick="popout(\'/lowrate\',500,500);" src="/site_media/images/blueribbon.jpg" />';
		rate.appendChild(blueribbon);
	}
	var rate_inner = document.createElement('div');
	rate_inner.className = "rate_inner";
	var rateInnerContents;
	if (hotel.rate_type=="T") {
		rateInnerContents = 'Nightly Rates from<br /><span class="nightly_rate">';
	}
	else {
		rateInnerContents = 'Low Rates from<br /><span class="nightly_rate">';
	}
	rateInnerContents += hotel.price_display;
	if (hotel.no_fee) {
		rateInnerContents += ' (no pet fee)</span>';
	}
	else {
		rateInnerContents += ' + pet fee</span>';
	}
	rate_inner.innerHTML = rateInnerContents;
	rate.appendChild(rate_inner);

	var action_button;
	if (bparams && (hotel.rate_type=="T" || hotel.xid)) {
		if (hotel.rate_type=="T") {
			action_button = '<a href="/lodging/book/' + hotel.id + bparams + '" target="_blank" class="button">BOOK ROOM</a>';
		}
		else {
			action_button = '<a href="/lodging/book/' + hotel.id + bparams + '" target="_blank" class="button">CHECK RATES</a>';
		}
	}
	else {
		if (hotel.website != '') {
			action_button = '<a href="' + hotel.website + '" target="_blank" class="button">VISIT WEBSITE</a>';
		}
		else {
			action_button = '<a onclick="check_rates(' + hotel.id + ');" class="button">CHECK RATES</a>';
		}
	}
	rate.innerHTML += action_button;
	info.appendChild(rate);

	var bottom_edge = document.createElement('div');
	bottom_edge.className = "bottom_edge";
	snapshot.appendChild(bottom_edge);

	parent.appendChild(snapshot);
	return snapshot;
}


function HotelResultsManager(page_size, init_sort) {
	this.page_size = page_size ? page_size : 15;
	this.last_sort = init_sort ? init_sort : 'name';

	this.full_results = [];
	this.current_results = [];
	this.filtered_results = [];
	this.full_results_lookup = {};

	this.min_price = 0;
	this.max_price = 9999999;
	this.min_price_curr = 0;
	this.max_price_curr = 9999999;

	this.filters = {};
	this.slider;
	this.map = null;
	this.result_overlays = {};
	this.loading_panels = [];
}

HotelResultsManager.prototype.addLoadingPanel = function(panel) {
	this.loading_panels.push(panel);
}

HotelResultsManager.prototype.showLoadingPanels = function() {
	for (var i=0; i<this.loading_panels.length; i++) {
		var panel = document.getElementById(this.loading_panels[i]);
		if (panel) { panel.style.display = "block"; }
	}
}

HotelResultsManager.prototype.hideLoadingPanels = function() {
	for (var i=0; i<this.loading_panels.length; i++) {
		var panel = document.getElementById(this.loading_panels[i]);
		if (panel) { panel.style.display = "none"; }
	}
}


HotelResultsManager.prototype.attachMap = function(map) {
	this.map = map;
}

HotelResultsManager.prototype.clearMapResults = function(layer) {
	if (this.map && layer in this.result_overlays) {
		for (var i=0; i<this.result_overlays[layer].length; i++) {
			this.map.removeOverlay(this.result_overlays[layer][i]);
		}
	}
}

HotelResultsManager.prototype.plotResult = function(result, layer, number) {
	if (this.map) {
		// alert('A-[' + result.name + ']');
		var marker = this.createResultMarker(result, number);
		// alert('B' + number);
		this.map.addOverlay(marker);
		// alert('C' + number);
		if (!(layer in this.result_overlays)) {
			// alert('D' + number);
			this.result_overlays[layer] = [];
			// alert('E' + number);
		}
		// alert('F' + number);
		this.result_overlays[layer].push(marker);
		// alert('G' + number);
	}
}

HotelResultsManager.prototype.refresh_page_nav = function(num) {
	var results_range = document.getElementById('results_paging_range_bottom');
	var results_controls_bottom = document.getElementById('results_paging_controls_bottom');
	var results_controls_top = document.getElementById('results_paging_controls_top');

	results_range.innerHTML = '';
	if (this.filtered_results.length>0) {
		var start_index = (num-1)*this.page_size + 1;
		var end_index = Math.min(num*this.page_size, this.filtered_results.length);
		results_range.innerHTML = 'Results: ' + start_index + '-' + end_index + ' of ' + this.filtered_results.length;
	}
	else {
		results_range.innerHTML = 'Sorry. There are no results matching your criteria.';
	}

	var paging_controls = '';
	var max_page = this.filtered_results.length / this.page_size;
	if (num > 1) {
		paging_controls += "&laquo; <span id='page_" + (num-1) + "' class='result_control' onclick='resultsMgr.get_page(" + (num-1) + ");'>Prev</span> | ";
	}
	for (var i=1; i<max_page+1; i++) {
		var curr_id = 'page_' + i;
		if (i==num) {
			paging_controls += "<span id='" + curr_id + "' class='result_control_selected' onclick='resultsMgr.get_page(" + i + ");'>" + i + "</span>";
		}
		else {
			paging_controls += "<span id='" + curr_id + "' class='result_control' onclick='resultsMgr.get_page(" + i + ");'>" + i + "</span>";
		}
		if (i < max_page) {
			paging_controls += " | ";
		}
	}
	if (num < max_page) {
		paging_controls += " | <span id='page_" + (num+1) + "' class='result_control' onclick='resultsMgr.get_page(" + (num+1) + ");'>Next</span> &raquo;";
	}
	
	if (results_controls_top) {
		results_controls_top.innerHTML = paging_controls;
	}
	if (results_controls_bottom) {
		results_controls_bottom.innerHTML = paging_controls;
	}
	if (document.getElementById('result_count')) {
		document.getElementById('result_count').innerHTML = this.filtered_results.length;
	}
}


HotelResultsManager.prototype.resort = function(mode) {
	sort(mode, this.filtered_results);
	this.get_page(1, this.page_size);
	this.last_sort = mode;
	
	var sort_options = document.getElementById('results_sorting_controls').childNodes;
	for (var i=0; i<sort_options.length; i++) {
		var currNode = sort_options[i];
		if (currNode.id==('sort_'+mode)) {
			sort_options[i].className = 'result_control_selected';
		}
		else if (currNode.id != null && currNode.id.indexOf('sort_')==0) {
			sort_options[i].className = 'result_control';
		}
	}
}


HotelResultsManager.prototype.filter = function() {
	this.filtered_results = Array();
	for (var i=0; i<this.current_results.length; i++) {
		var keep = true;
		if (this.current_results[i].price == null || this.current_results[i].price < this.min_price_curr || this.current_results[i].price > this.max_price_curr+1) {
			keep = false;
			continue;
		}
		for (var f in this.filters) {
			if (this.current_results[i][f] != this.filters[f]) {
				keep = false;
				break;
			}
		}
		if (keep) {
			this.filtered_results.push(this.current_results[i]);
		}
	}
}


HotelResultsManager.prototype.reset_filters = function(advanced_options) {
	this.min_price = 9999999;
	this.max_price = 0;
	this.min_price_display = '';
	this.max_price_display = '';
	var initVals = [0,170];
	
	if (!this.filters) {
		this.filters = {};	
		document.forms['refine_form'].type.value = '';
		// document.forms['refine_form'].star_rating.value = '';
		document.forms['refine_form'].fido_rating.value = '';
		document.forms['refine_form'].no_fee.checked = false;
		document.forms['refine_form'].deposit_only.checked = false;
		document.forms['refine_form'].fee_under_25.checked = false;
		document.forms['refine_form'].large_allowed.checked = false;
		document.forms['refine_form'].multiple_allowed.checked = false;
	}
	
	for (var i=0; i<this.current_results.length; i++) {
		if (this.current_results[i].price < 9999999) {
			if (this.current_results[i].price < this.min_price) {
				this.min_price = Math.floor(this.current_results[i].price);
				this.min_price_display = this.current_results[i].price_display;
			}
			if (this.current_results[i].price > this.max_price) {
				this.max_price = this.current_results[i].price;
				this.max_price_display = Math.floor(this.current_results[i].price_display);
			}
		}
	}
	if (this.max_price < this.min_price) {
		this.min_price = 0;
		this.max_price = 0;
	}
	this.min_price_curr = this.min_price;
	this.max_price_curr = this.max_price;

	if (advanced_options) {
		if ('type' in advanced_options) {
			document.forms['refine_form'].type.value = advanced_options['type'];
			this.update_filter(document.forms['refine_form'].type, true);
		}
		if ('nofee' in advanced_options) {
			document.forms['refine_form'].no_fee.checked = (advanced_options['no_fee']=='True');
			this.update_filter(document.forms['refine_form'].no_fee, true);
		}
		if ('deposit_only' in advanced_options) {
			document.forms['refine_form'].deposit_only.checked = (advanced_options['deposit_only']=='True');
			this.update_filter(document.forms['refine_form'].deposit_only, true);
		}
		if ('fee_under_25' in advanced_options) {
			document.forms['refine_form'].fee_under_25.checked = (advanced_options['fee_under_25']=='True');
			this.update_filter(document.forms['refine_form'].fee_under_25, true);
		}
		if ('large_allowed' in advanced_options) {
			document.forms['refine_form'].large_allowed.checked = (advanced_options['large_allowed']=='True');
			this.update_filter(document.forms['refine_form'].large_allowed, true);
		}
		if ('multiple_allowed' in advanced_options) {
			document.forms['refine_form'].multiple_allowed.checked = (advanced_options['multiple_allowed']=='True');
			this.update_filter(document.forms['refine_form'].multiple_allowed, true);
		}
		
		if ('rate_low' in advanced_options) {
			var rate_low_val = parseInt(advanced_options['rate_low']);
			if (rate_low_val > this.min_price) {
				this.min_price_curr = rate_low_val;
			}
		}
		if ('rate_high' in advanced_options) {
			var rate_high_val = parseInt(advanced_options['rate_high']);
			if (rate_high_val < this.max_price) {
				this.max_price_curr = rate_high_val;
			}
		}
		
		if (this.min_price_curr<this.max_price_curr) {
			initVals = [this.convertSliderValue(this.min_price_curr,true),
			 			this.convertSliderValue(this.max_price_curr,true)];
		}
				
		// this.slider.setValues(this.convertSliderValue(this.min_price_curr,true),
		// 					  this.convertSliderValue(this.max_price_curr,true),
		//					  false, false, false);
		// this.updateSlider();
	}

	this.sliderInit(initVals);
	this.filter();
}


HotelResultsManager.prototype.update_filter = function(element, norefresh) {
	if (element.getAttribute('type')=='checkbox') {
		// alert(element.name + '=[' + element.checked + ']');
		if (element.checked) {
			this.filters[element.name] = true;
		}
		else {
			delete this.filters[element.name];
		}
	}
	else if (element.nodeName.toLowerCase()=='select') {
		// alert(element.name + '=[' + element.value + ']');
		if (element.value != '') {
			this.filters[element.name] = element.value;
		}
		else {
			delete this.filters[element.name];
		}
	}
	
	if (!norefresh) {
		this.filter();
		this.resort(this.last_sort);		
		this.get_page(1);
	}
}


HotelResultsManager.prototype.get_page = function(num) {
	this.load_page(num);
	this.refresh_page_nav(num);
}


HotelResultsManager.prototype.convertSliderValue = function(value,reverse) {
	if (this.min_price>=this.max_price) {
		return this.min_price;
	}
	else {
		var range = 170;
		var converted = 0;
		if (reverse) {
			converted = Math.floor((value-this.min_price)*170/(this.max_price-this.min_price));
		}
		else {
			converted = Math.floor((value/range)*(this.max_price-this.min_price)+this.min_price);
		}
		return converted;
	}
}


HotelResultsManager.prototype.updateSlider = function(norefresh) {
	this.min_price_curr = this.convertSliderValue(this.slider.minVal);
	this.max_price_curr = this.convertSliderValue(this.slider.maxVal);
	document.getElementById('price_min').innerHTML = '$' + this.min_price_curr;
	document.getElementById('price_max').innerHTML = '$' + this.max_price_curr;

	if (!norefresh) {
		this.filter();
		this.resort(this.last_sort);		
		this.get_page(1);
	}
}


HotelResultsManager.prototype.sliderInit = function(initVals) {
	if (!this.slider) {
		this.slider = YAHOO.widget.Slider.getHorizDualSlider("sliderbg","slider_thumb_min","slider_thumb_max",170,null,initVals);
		// this.slider = YAHOO.widget.Slider.getHorizDualSlider("sliderbg","slider_thumb_min","slider_thumb_max",170);
		this.slider.manager = this;
		this.slider.subscribe("slideEnd", function() { this.manager.updateSlider(); } );
		this.slider.subscribe("ready", function() { this.manager.updateSlider(); } );
	}
	else {
		this.updateSlider();
	}
}


HotelResultsManager.prototype.load_results = function(results, results_container, params, bparams, lodging_type, advanced_options) {
	this.current_results = [];

    for (var i=0; i<results.length; i++) {
    	var hotel = results[i];
    	if (!(hotel.id in this.full_results_lookup)) {
    		this.full_results.push(hotel);
    		this.full_results_lookup[hotel.id] = this.full_results.length-1;
	    	construct_snapshot(hotel, results_container, params, bparams, null);
	    }
	    this.current_results.push(this.full_results[this.full_results_lookup[hotel.id]]);
    }
    
    if (lodging_type) {
    	if (!advanced_options) {
    		advanced_options = {};
    	}
    	advanced_options['type'] = lodging_type;
    }
	this.reset_filters(advanced_options);
	this.get_page(1);
}

HotelResultsManager.prototype.init_results = function(params, bparams, query_keyword, lodging_type, advanced_options)	{
	this.showLoadingPanels();
	var results_container = document.getElementById("results_list_hidden");
	var callback = {
		success : function(o) {
			try {
				// alert(o.responseText);
			    var response = YAHOO.lang.JSON.parse(o.responseText);
			    this.load_results(response.mappable_objects, results_container, params, bparams, lodging_type, advanced_options);
			}
			catch (e) {
			    alert("Invalid hotel results! [" + e + "]");
				results_container.innerHTML = "Failed to load hotels (error code=102). Please try again later.";
			}
			this.hideLoadingPanels();
		},
		failure : function(o) {
			results_container.innerHTML = "Failed to load hotels (error code=101). Please try again later.";
			this.hideLoadingPanels();
		},
		scope : this
	}

	if (query_keyword) {
		var conn = YAHOO.util.Connect.asyncRequest("GET", "/lodging/service/search/?q=" + query_keyword, callback);
	}
	else {
		var conn = YAHOO.util.Connect.asyncRequest("GET", "/lodging/service/search/?" + params, callback);
	}
}

HotelResultsManager.prototype.load_city_results = function(cities) {
	this.clearMapResults('cities');
    for (var i=0; i<cities.length; i++) {
    	this.plotResult(cities[i], 'cities');
    }
}

HotelResultsManager.prototype.init_map_results = function(params, bparams, map,country,state,type)	{
	this.showLoadingPanels();

	var results_container = document.getElementById("results_list_hidden");
	var callback = {
		success : function(o) {
			try {
			    var response = YAHOO.lang.JSON.parse(o.responseText);
			    this.load_results(response.items, results_container, params, bparams, type);
			    this.load_city_results(response.cities);
			    this.hideLoadingPanels();
			}
			catch (e) {
			    alert("Invalid map results! [" + e + "]");
				results_container.innerHTML = "Failed to load hotels (error code=102). Please try again later.";
			    this.hideLoadingPanels();
			}
		},
		failure : function(o) {
			results_container.innerHTML = "Failed to load hotels (error code=101). Please try again later.";
		    this.hideLoadingPanels();
		},
		scope : this
	}

	this.attachMap(map);
	
	var bounds = this.map.getBounds();
	var southWest = bounds.getSouthWest();
	var northEast = bounds.getNorthEast();
	var objectsUrl = '/cluster/hotel/?lat1=' + southWest.lat() + '&lat2=' + northEast.lat() + '&lng1=' + southWest.lng() + '&lng2=' + northEast.lng();
	if (country) {
		objectsUrl += '&c=' + country;
	}
	if (state) {
		objectsUrl += '&s=' + state;
	}
	if (type) {
		objectsUrl += '&type=' + type;
	}
	
	var conn = YAHOO.util.Connect.asyncRequest("GET", objectsUrl, callback);
}


HotelResultsManager.prototype.load_page = function(num) {
	var visible = document.getElementById('results_list');
	var hidden = document.getElementById('results_list_hidden');

	for (var i=visible.childNodes.length-1; i>=0; i--) {
		var hotel_tile = visible.childNodes[i];
		visible.removeChild(hotel_tile);
		hidden.appendChild(hotel_tile);
	}
	this.clearMapResults('page');

	var resultNumber = 1;
	for (var i=(num-1)*this.page_size; i<num*this.page_size && i<this.filtered_results.length; i++) {
		var result = this.filtered_results[i];
		this.plotResult(result, 'page', resultNumber);
		
		var hotel_tile = document.getElementById('hotel_' + result.id);
		if (hotel_tile) {
			// Don't plot results if there is no map attached!
			if (this.map) {
				var hotel_tile_icon = document.getElementById('resultIcon_' + result.id);
				if (hotel_tile_icon) {
					hotel_tile_icon.innerHTML = '<img src="' + this.getResultIconImage(resultNumber) + '" />';
				}
			}
		
			hidden.removeChild(hotel_tile);
			visible.appendChild(hotel_tile);
			
			resultNumber++;
		}
		else {
			alert("Error: Invalid hotel id [" + result.id + "]");
		}
	}
}


HotelResultsManager.prototype.getResultIconImage = function(number) {
	var image;
	if (number > 0 && number <= 15) {
		image = "/site_media/images/marker_" + "abcdefghijklmno".charAt(number-1) + ".png";
	}
	else {
		image = "/site_media/images/marker.png";
	}
	return image;
}

HotelResultsManager.prototype.createResultMarker = function(item, number) {
	var marker = null;
	if (number) {
		var icon = new GIcon();
		icon.image = this.getResultIconImage(number);
		icon.iconSize = new GSize(16, 16);
		icon.iconAnchor = new GPoint(8, 8);
		icon.infoWindowAnchor = new GPoint(8, 8);
		var point = new GLatLng(item.latitude, item.longitude);
		marker = new GMarker(point, { icon:icon,
									  zIndexProcess:function(){ return 9999-number; } } );
	
		GEvent.addListener(marker, "click", function() {
			var html = "<div class='mapInfo'>";
			if (item.image != '') { 
				html += "<img src='" + item.image + "'/><div class='details'>"; 
			}
			else {
				html += "<div class='details' style='width:100%'>";
			}
			html += "<h1><a href='/lodging/" + item.id + "/' target='_blank'>" + item.name + "</a></h1>" + item.description + "</div></div>";
			marker.openInfoWindowHtml(html,{maxWidth:270});
		});
	}
	else {
		var icon = new GIcon();
		icon.image = "/site_media/images/cluster1.png";
		icon.iconSize = new GSize(10, 10);
		icon.iconAnchor = new GPoint(5, 5);
		icon.infoWindowAnchor = new GPoint(5, 5);
	
		var point = new GLatLng(item.latitude, item.longitude);
		marker = new GMarker(point, { icon:icon,
									  zIndexProcess:function(){ return 9000; } } );
	
		GEvent.addListener(marker, "click", function() {
			var html = "<div class='mapInfo'>";
			if (item.image != '') { 
				html += "<img src='" + item.image + "'/><div class='details'>"; 
			}
			else {
				html += "<div class='details' style='width:100%'>";
			}
			html += "<h1><a href='/lodging/city/" + item.slug + "/' target='_blank'>" + item.name + "</a></h1>" + item.description + "</div></div>";
			marker.openInfoWindowHtml(html,{maxWidth:270});
		});
	}

	return marker;
}
