var search = Class.create
({	
	initialize: function(search_criteria)
	{
		this.search_criteria = search_criteria;
	},

	search: function()
	{
		new Ajax.Request(this.search_url,
		{
			method: 'post',
			parameters: $H(this.search_criteria).toQueryString(),
			onSuccess: this.update_results.bind(this),
			onCreate: this.toggle_loading(true)
		});
	},
	
	get_results: function()
	{
		/* Results evaluated in a function, so we can create a copy by using
		the keyword 'new', because Prototype's clone isn't adequate */	
		var response = new this.response();
		return response.results;
	},
	
	update_results: function(transport)
	{
		if (transport.responseText)
		{
			this.toggle_loading(false);
			this.toggle_select_message(true);
			
			this.response = function() {this.results=transport.responseText.evalJSON();};
			this.original_results = this.get_results();
			
			// this.set_up_filtering();
			this.render_results(this.original_results);
		}
		else this.bounce_back();
	},
	
	render_results: function(results)
	{
		var obj = this;	// Hotel or Flight search
		var per_page = this.search_criteria.results_per_page;
		var no_of_pages = Math.ceil(results.items.length / per_page);
		var current_page_no;
		
		// This displays the message saying "couldn't find your hotel choice
		// Maybe put it somewhere else (like in the hotel module)
		this.toggle_orig_choice_message(results.unable_to_find_original_choice);
		
		$('search_id').writeAttribute('value', results.search_id);
		
		function pagination(container_id)
		{
			var max_links = 12; // Should be an even number
			var limiting = (no_of_pages >= max_links); // Do we need to limit the amount of links shown?
			var links_left = 0; // First page
			var links_right = no_of_pages; // Last page

			if (limiting)
			{
				/* Constrict pagination links to a certain amount either side of the selected page number, e.g:
				6, 7, 8, 9, 10, (11), 12, 13, 14, 15, 16 */
				var either_side = (max_links / 2);
				links_left = (current_page_no - either_side);
				links_right = (current_page_no + either_side) - 1;
			}
			
			if (links_left < 0)
			{
				if (limiting) links_right += Math.abs(links_left); // Instead we need more links more on the RHS
				links_left = 0; // We don't want negative links on the LHS
			}
			if (links_right > no_of_pages)
			{
				if (limiting) links_left -= (links_right - no_of_pages); // We need more links on the LHS
				links_right = no_of_pages; // We don't want too many links on the RHS
			}
			
			var container = $(container_id);
			var div = new Element('div', {'class': 'pagination'});
			var ol = new Element('ol');
			var li, a;
			
			if (no_of_pages > 1)
			{
				if (current_page_no > 1)
				{
					a = new Element('a', {'href': '#results_top'}).update('Prev');
					a.onclick = prev;
					li = new Element('li', {'class': 'pagination_prev'});
					li.insert(a);
					ol.insert(li);
				}
				for (var i=links_left; i<links_right; i++)
				{
					li = new Element('li');
					
					var page_no = i+1;
					if (page_no == current_page_no)
					{
						span = new Element('span').update(page_no);
						li.insert(span);
					}
					else
					{
						a = new Element('a', {'href': '#results_top'}).update(page_no);
						a.onclick = display.bind(this, page_no);
						li.insert(a);
					}
					ol.insert(li);
				}
				if (current_page_no < no_of_pages)
				{
					a = new Element('a', {'href': '#results_top'}).update('Next');
					a.onclick = next;
					li = new Element('li', {'class': 'pagination_next'});
					li.insert(a);
					ol.insert(li);
				}
			}
			else
			{
				ol.insert(new Element('li').insert(new Element('span').update('Page 1 of 1')));
			}
			div.insert(ol);
			container.update(div);
		};
		
		function prev() { display(current_page_no - 1); };
		function next()	{ display(current_page_no + 1); };
		
		function items()
		{
			var items = new Element('div');
			
			var stop = per_page * current_page_no;
			var start = stop - per_page;
			
			for (var i=start; i<stop; i++)
			{
				var result = results.items[i];
				if (typeof result != 'undefined')
				{
					// Build the item
					var item = obj.build(result,results.totals);
					// Append to SERP
					items.insert(item);
					// Element.insert.delay(.1, items, item);
				}
			}
			$('search_results').update(items);
		};
		
		function display(page_no)
		{
			current_page_no = page_no;
			
			pagination('top_pagination');
			items();
			pagination('bottom_pagination');
		};
		
		display(1); // Render the first page
	},
	
	filter_results: function()
	{		
		this.search_criteria.results_per_page = $('filter_per_page').getValue();
		
		/* Run all the filters on a copy of the original results,
		then re-render the results... */
		$('filter').writeAttribute('disabled', 'disabled');
		
		var results = this.get_results();
		var filtered_results = this.filter(results);
		
		$('filter').removeAttribute('disabled');
		$('filter').blur();
		
		var err = $$('#filters div.error')[0];
		
		if (!filtered_results.items.length)
		{
			// Insert an error message, because the filters produce no results
			err.update('No results to display with the current search filters.').removeClassName('hidden');
		}
		else
		{
			err.update('').addClassName('hidden');
			this.render_results(filtered_results);
		}
	},
	
	set_up_filtering: function()
	{
		var obj = this;
		
		function init()
		{
			$('filter').observe('click', obj.filter_results.bind(obj));
			
			// Filters are hidden intially
			var show_filters = new Element('a', {'id': 'show_filters', 'href': '#'}).update('Filter these results');
			show_filters.onclick = function()
			{
				$('show_filters').remove();
				$('filters').setStyle({display:'block'});
				return false;
			};
			$('filters').insert({'before': show_filters});
		};
		
		function budget()
		{
			var prices = obj.original_results.overall_prices;
			var ranges = prices.length;
			var select = $('filter_budget');
			var from, to;
			var low = prices[0];
			var high = prices[ranges-1];
			
			select.insert(new Element('option', {'value': '[0,'+low+']'}).update('Under &pound;'+low));
			for (var i=0, ranges = ranges-1; i<ranges; i++)
			{
				from = prices[i];
				to = prices[i+1];
				select.insert(new Element('option', {'value': '['+from+','+to+']'}).update('&pound;'+from+' to &pound;'+to));
			};
			select.insert(new Element('option', {'value': '['+high+',0]'}).update('Over &pound;'+high));
		};
		
		// set up filtering common to all types of search
		init();
		budget();
	},
	
	toggle_loading: function(toggle)
	{
		if (toggle)
			this.show_progress();
		else
			this.hide_progress();
	},
	
	show_progress: function()
	{
		var p = new Element('p').update(this.loading_message);
		var img = new Element('img', {'src': '/images/progress_bar.gif'});
		
		$('progress_bar').insert(p).insert(img).show();
	},
	
	hide_progress: function()
	{
		$('progress_bar').update('').hide();
	},
	
	toggle_select_message: function(toggle)
	{
		if (toggle)
			this.show_select_message();
		else
			this.hide_select_message();
	},
	
	show_select_message: function()
	{
		var p = new Element('p').update(this.select_message);
		
		$('select_message').insert(p).show();
	},
	
	hide_select_message: function()
	{
		$('select_message').update('').hide();
	},
	
	toggle_orig_choice_message: function(toggle)
	{
		if (toggle)
			this.show_orig_choice_message();
		else
			this.hide_orig_choice_message();
	},
	
	show_orig_choice_message: function()
	{
		var p = new Element('p').update(this.orig_choice_message);
		
		$('orig_choice_message').insert(p).show();
		this.hide_select_message();
	},
	
	hide_orig_choice_message: function()
	{
		$('orig_choice_message').update('').hide();
	}
});

// ------------------------------

function check_budget(budget, range)
{
	range = eval(range);
	
	var lower = range[0];
	var upper = range[1];
	var budget_okay = false;
	
	if (lower && upper) // [n, m] must be between n and m
		budget_okay = (budget >= lower && budget <= upper);
	
	else if (!lower && upper) // [0, n] must be less than n
		budget_okay = (budget < upper);
	
	else if (lower && !upper) // [n, 0] n to infinity (no max budget)
		budget_okay = (budget > lower);

	return budget_okay;
}

function dateStatusHandler(then, y, m, d){
	// returns true if this date is to be disabled.
	// purposely extracted into more logic so it's clearer.
	
	today = new Date();
	
	if(then.getFullYear() == today.getFullYear() && then.getMonth() < today.getMonth()){
		// This year but a previous month
		return true;
	} else if(then.getFullYear() < today.getFullYear()){
		// Previous year.
		return true;
	} else {
		return false;
	}
}	

function cyo_pop(p,n){
	window.open((n?p:'/cyo-pop?in='+p),'cyo_pop','width=440,height=350,scrollbars=yes');
}

function cyo_pop_small(p,n){
	window.open((n?p:'/cyo-pop?in='+p),'cyo_pop_small','width=400,height=200,scrollbars=yes');
}

function vrsn_splash(){
	window.open('https://seal.verisign.com/splash?form_file=fdf/splash.fdf&dn=WWW.OTBEACH.COM&lang=en','','width=600,height=450,status=yes,toolbar=yes,menubar=yes,location=yes,scrollbars=auto,resizable=yes');
}

function start_basket_timeout(m){
	return;
	thirty_minutes = 1800000;
	cart_timeout = setTimeout("basket_timeout('"+m+"')",thirty_minutes);
}

var hiw;

function show_hotel_info_win(hotel_index, hotel_page)
{
	var search_id = the_hotel_search.original_results.search_id;
	hiw = window.open
	(
		hotel_page + '?pop=1&show_boards=1&hotel_index=' + hotel_index + '&search_id=' + search_id,
		'hotel_info_win', 'scrollbars=1, toolbar=0, height=600, width=800'
	);
	hiw.focus();
	return false;
}

function date_zero_pad(s,n){
	p = "";
	l = n-String(s).length;
	for(i=0 ; i<l; i++){
		p += "0";
	}
	return p+s;
}

function basket_timeout(m){
	var d;
	if(m == 'quote'){
		d = 'ch3';
	} else if(m == 'hotel'){
		d = 'ch4';
	} else {
		d = 'ch2';
	}
	
	if(hiw){
		hiw.close();
	}
		
	
	document.location.href = d;
	cyo_pop_small('cyo-basket_expired');
}


/* Handy JS functions */

var nr_jslib_ie = ( (navigator.userAgent.toLowerCase().indexOf("msie") != -1) &&
		   (navigator.userAgent.toLowerCase().indexOf("opera") == -1) );
var nr_jslib_ajax_dump = false;

function nr_jslib_inarray($arr,$checkfor) {
	$array_string = $arr.toString();
	$array_string.search($checkfor);
	if($array_string) {
		return true;
	} else {
		return false;
	}
}

function nr_jslib_get_event(e) {
	if(!e) {
			var e = window.event;
	}
	if(!e.target) {
		e.target = e.srcElement;
	}
	if(!e.pageX && !e.pageY) {
		if(document.documentElement) {
			e.pageX  = e.clientX + document.documentElement.scrollLeft;
			e.pageY = e.clientY + document.documentElement.scrollTop;
		} else {
			e.pageX = e.clientX + document.body.scrollLeft;
			e.pageY = e.clientY + document.body.scrollTop;
		}
	}
	return e;
}

function nr_jslib_add_event(event_name, function_name, event_target) {
	if(!event_target) {
		if (nr_jslib_ie) {
		event_target = document.body;
		} else {
		event_target = document;
		}
	}
	if(document.attachEvent) {
		nr_jslib_remove_event(event_name, function_name, event_target);
		event_target.attachEvent("on" + event_name, function_name);
	} else {
		event_target.addEventListener(event_name, function_name, true);
	}
}

function nr_jslib_remove_event(event_name, function_name, event_target) {
	if(!event_target) {
		if (nr_jslib_ie) {
			event_target = document.body;
		} else {
			event_target = document;
		}
	}
	if (document.attachEvent) {
		event_target.detachEvent("on" + event_name, function_name);
	} else {
		event_target.removeEventListener(event_name, function_name, true);
	}
}

function nr_jslib_stop_event(e) {
		if (nr_jslib_ie) {
			window.event.cancelBubble = true;
			window.event.returnValue = false;
		} else {
			e.preventDefault();
			e.stopPropagation();
		}
}

function launch_popunder(){
	window.open("/ads/otb_affiliate.html",'popunder',"left=400,top=400,width=400,height=270");
	window.focus();
}

ideas = {
	count: 0,
	examples: [
		'Cyprus holidays',
		'5 star Tenerife',
		'flights to Sharm',
		'last minute Majorca',
		'Hilton Sharm el Sheikh',
		'Tunisia hotels',
		'family holidays to Turkey',
		'hotels in Crete',
		'luxury Dominican Republic'
	],
	rotate: function() {
		$$("#otb-search-ideas span")[0].update(this.examples[this.count]);
		this.count = (this.count >= this.examples.length-1) ? 0 : this.count+1;
	},
	start_rotating: function() {
		this.rotate(); // initial run
		this.timer = setInterval(this.rotate.bind(this), 2750); // subsequent runs
	}
}
