var HolidayFinder;

(function($)
{
	HolidayFinder = 
	{
		CHOOSE_DATE: 'CHOOSE_DATE',
		CHOOSE_TYPE: 'CHOOSE_TYPE',
		CHOOSE_COUNTRY: 'CHOOSE_COUNTRY',
		CHOOSE_HOTEL: 'CHOOSE_HOTEL',
		state: 'CHOOSE_DATE',
		
		sort: 'price',
		enquiryData: false,
		hotelFinder: (typeof hotelFinder != 'undefined') && hotelFinder,
		
		// Store country state (checked/unchecked) so they will remain checked if they're removed and put back (by changing options)
		countryStates: {},
		loadingFromJson: false,
		lastCountryJson: '',
		lastHotelJson: '',
		lastEnquiryJson: '',
		
		savedHotels: [],
		discardedHotels: [],
		
		init: function()
		{
			var self = this;
			var json = location.hash.replace(/^#/, '');
			var change = function() { self.update(); };
			
			$('#hf-temperature').html('').slider({value:20, step:5, min:0, max:40, change: change, slide: function(event, ui)
			{
				var value = ui ? ui.value : $(this).slider('value');
				var text = 'Over ' + value + '°C';
				
				$('#hf-temperature-value').text(text);
				$(this).attr('title', text);
			}})
			
			$('#hf-rainfall').html('').slider({value:200, step:50, min:0, max:500, change: change, slide: function(event, ui)
			{
				var value = ui ? ui.value : $(this).slider('value');
				var text = 'Under ' + (500 - value) + 'mm /mth';
				
				$('#hf-rainfall-value').text(text);
				$(this).attr('title', text);
			}});
			
			$('#hf-flight-time').html('').slider({value:13, step:1, min:6, max:20, change: change, slide: function(event, ui)
			{
				var value = ui ? ui.value : $(this).slider('value');
				var text = 'Under ' + value + ' hours';
				
				$('#hf-flight-time-value').text(text);
				$(this).attr('title', text);
			}});
			
			$('#hf-transfer-time').html('').slider({value:180, step:60, min:0, max:300, change: change, slide: function(event, ui)
			{
				var value = ui ? ui.value : $(this).slider('value');
				var text = 'Under ' + (value / 60) + ' hours';
				
				$('#hf-transfer-time-value').text(text);
				$(this).attr('title', text);
			}});
			
			
			$('#hf-temperature,#hf-rainfall,#hf-flight-time,#hf-transfer-time').each(function()
			{
				var $this = $(this);
				$this.slider('option', 'slide').call($this);
			});
			
			$('.hf-section input,.hf-section select').change(change);
			$('.hf-section input,.hf-section select').click(change);
			
			$('#hf-enquiry-form h6 span').html('Our system will search tour operators for the best prices for <span>Your Holiday</span>.');
			
			if (json)
			{
				this.loadingFromJson = true;
				var data = this.updateFromJson(json);
				this.updateCountries(function()
				{
					self.setChecked('#hf-matched-countries', data.c);
					self.countryStates = {};
					
					try
					{
						$.each(data.c, function()
						{
							self.countryStates[this] = true;
						});
					}
					catch (e)
					{
					}
					
					self.loadingFromJson = false;
					
					self.update();
					self.updateHotels();
					
				});
			}
			
			if (this.hotelFinder)
			{
				this.setSliderValue('#hf-temperature', 0);
				this.setSliderValue('#hf-rainfall', 0);
				
				$('#hf-weather').hide();
				$('.hf-col').css('padding', '0 15px');
			}
			
			var oldSubmit = $('#hf-enquiry-form form').get(0).onsubmit;
			$('#hf-enquiry-form form').get(0).onsubmit = null;
			
			$('#hf-enquiry-form form').submit(function()
			{
				if (!oldSubmit.call($(this).get(0)))
					return false;
				
				self.enquiryData = {};
				
				$('input, select', this).each(function()
				{
					var elm = $(this);
					self.enquiryData[elm.attr('name').replace(/^.*_/, '')] = elm.val();
				});
				
				$.modal.close();
				
				self.addEnquiry();
				
				return false;
			});
			
			this.update();
		},
		
		update : function()
		{
			var self = this;
			
			// Step 1 - travel date
			this.travelDay = $('#travel-day').val();
			this.travelMonth = $('#travel-month').val();
			this.travelYear = $('#travel-year').val();
			
			$('#hf-enquiry-form select').each(function(i)
			{
				if (i == 0)
					$(this).val(self.travelDay);
				else if (i == 1)
					$(this).val(self.travelMonth);
				else if (i == 2)
					$(this).val(self.travelYear);
			});
			
			// Step 2 - holiday type
			this.amenities = this.getChecked('#hf-amenities');
			
			// Step 3
			// Weather
			this.temperature = $('#hf-temperature').slider('value');
			this.rainfall = 500 - $('#hf-rainfall').slider('value');
			
			// Journey
			this.flightTime = $('#hf-flight-time').slider('value');
			this.transferTime = $('#hf-transfer-time').slider('value');
			
			// Hotel facilities
			this.stars = this.getChecked('#hf-stars');
			this.activities = this.getChecked('#hf-activities');
			
			
			// Countries
			this.countries = this.getChecked('#hf-matched-countries');
			
			if (this.loadingFromJson)
				return;
			
			this.updateUrl();
			
			var lastState = '';
			while (lastState != this.state)
			{
				lastState = this.state;
				this['state' + this.state]();
			}
			
		},
		
		getChecked : function(selector)
		{
			var checked = [];
			
			$(selector + ' input:checked').each(function()
			{
				checked.push(parseInt($(this).val(), 10));
			});
			
			return checked;
		},
		
		setChecked : function(selector, data)
		{
			$(selector + ' input[type=checkbox]').each(function()
			{
				this.checked = $.inArray(parseInt($(this).val(), 10), data) != -1;
			});
		},
		
		stateCHOOSE_DATE : function()
		{
			if (this.travelDay && this.travelMonth && this.travelYear)
			{
				$('#hf-amenities').fadeIn(500);
				this.state = this.CHOOSE_TYPE;
				$('#hf-step').text('2');
				
				this.track('completed-choose-date');
			}
		},
		
		stateCHOOSE_TYPE : function()
		{
			if (this.amenities.length)
			{
				$('#hf-journey,#hf-hotel-activities').fadeIn(500);
				
				if (!this.hotelFinder)
					$('#hf-weather').fadeIn(500);
				
				$('#hf-countries').slideDown(500);
				this.state = this.CHOOSE_COUNTRY;
				$('#hf-step').text('3');
				
				this.track('completed-choose-type');
			}
		},
		
		stateCHOOSE_COUNTRY : function()
		{
			this.updateCountries();
			
			if (this.countries.length)
			{
				this.state = this.CHOOSE_HOTEL;
				$('#hf-step').text('4');
				$('#hf-hotels-container,#hf-hotels-below').fadeIn(500,
					function() { $(this).fadeOut(500,
						function() { $(this).fadeIn(500);
						});
					});
				
				this.track('completed-choose-country');
			}
		},
		
		stateCHOOSE_HOTEL : function()
		{
			if (!this.updateCountries())
				this.updateHotels();
		},
		
		updateCountries : function(onComplete)
		{
			var self = this;
			var data = 
			{
				'amenities[]' : this.amenities,
				temperature : this.temperature,
				rainfall : this.rainfall,
				flightTime : this.flightTime,
				transferTime : this.transferTime,
				'stars[]' : this.stars,
				'activities[]' : this.activities,
				travelMonth : this.travelMonth,
				action : 'getCountries'
			};
			
			var json = $.toJSON(data);
			if (json == this.lastCountryJson)
				return false;
			
			this.lastCountryJson = json;
			
			$('#hf-matched-countries').html('<div class="hf-loading">Loading...</div>');
			
			$.post(ROOT + '/holiday-finder-ajax/?rnd=' + Math.random(), data, function(html)
			{
				self.updateCountriesComplete(html);
				if (typeof onComplete == 'function')
					onComplete()
			}, 'html');
			
			return true;
		},
		
		updateHotels : function()
		{
			var self = this;
			var data = 
			{
				'amenities[]' : this.amenities,
				temperature : this.temperature,
				rainfall : this.rainfall,
				flightTime : this.flightTime,
				transferTime : this.transferTime,
				'stars[]' : this.stars,
				'activities[]' : this.activities,
				travelDay : this.travelDay,
				travelMonth : this.travelMonth,
				travelYear : this.travelYear,
				'countries[]' : this.countries,
				'savedHotels[]' : this.savedHotels,
				'discardedHotels[]' : this.discardedHotels,
				sort : this.sort,
				action : 'getHotels'
			};
			
			var json = $.toJSON(data);
			if (json == this.lastHotelJson)
				return;
			
			this.lastHotelJson = json;
			
			$('#hf-matched-hotels').html('<tr><td><div class="hf-loading">Loading...</div></td></tr>');
			
			$.post(ROOT + '/holiday-finder-ajax/?rnd=' + Math.random(), data, function(html) { self.updateHotelsComplete(html); }, 'html');
		},
		
		updateCountriesComplete : function(html)
		{
			var self = this;
			$('#hf-matched-countries').html(html);
			
			var change = function()
			{
				self.countryStates[this.value] = this.checked;
				self.update();
			}
			
			// Tick the previously ticked countries
			$('#hf-matched-countries input[type="checkbox"]')
				.each(function()
				{
					this.checked = (self.countryStates[this.value] == true);
				})
				.change(change)
				.click(change);
			
			this.update();
			this.updateHotels();
		},
		
		updateHotelsComplete : function(html)
		{
			$('#hf-matched-hotels').html(html);
			$('#hf-num-results').text($('#hf-total-rows td').text());
			$('#hf-total-rows').remove();
			
			this.updateSavedHotels();
		},
		
		moreDetails : function(hotelId)
		{
			$('#hf-more-details-loading').show();
			$('#hf-more-details-results').empty();
			
			$('#hf-more-details').modal();
			
			var self = this;
			var data = 
			{
				hotelId : hotelId,
				travelMonth : this.travelMonth,
				action : 'getHotel'
			};
			
			$.post(ROOT + '/holiday-finder-ajax/?rnd=' + Math.random(), data, function(html) { self.moreDetailsComplete(html); }, 'html');
			
			this.track('hotel-more-details');
			
			return false;
		},
		
		moreDetailsComplete : function(html)
		{
			var self = this;
			
			$.modal.close();
			$('#hf-more-details-loading').hide();
			$('#hf-more-details-results').html(html);
			
			// Acts buggy without timeout
			setTimeout(function()
			{
				$('#hf-more-details').modal({ onOpen : self.modalOpen });
			}, 100);
		},
		
		discard : function(hotelId)
		{
			this.discardedHotels.push(hotelId);
			
			var index = $.inArray(hotelId, this.savedHotels);
			if (index != -1)
				this.savedHotels.splice(index, 1);
			
			$('#hotel-' + hotelId).fadeOut(500);
			
			this.updateUrl();
			
			var self = this;
			setTimeout(function() { self.updateHotels(); }, 400);
			
			return false;
		},
		
		saveHotel : function(hotelId)
		{
			if ($.inArray(hotelId, this.savedHotels) != -1)
				return false;
			
			this.savedHotels.push(hotelId);
			
			$('#hotel-' + hotelId + ' .hf-save').addClass('hf-saved');
			
			this.updateUrl();
			
			return false;
		},
		
		updateSavedHotels : function()
		{
			$.each(this.savedHotels, function()
			{
				var hotelId = this.toString();
				
				$('#hotel-' + hotelId + ' .hf-save').addClass('hf-saved');
			});
		},
		
		modalOpen : function(dialog)
		{
			dialog.overlay.fadeIn(500);
			dialog.container.fadeIn(500);
			dialog.data.fadeIn(500);
		},
		
		enquire : function(hotelId)
		{
			var self = this;
			$.modal.close();
			
			this.saveHotel(hotelId);
			
			if (!this.enquiryData)
			{
				var self = this;
				var text1 = $('#hotel-' + hotelId + ' .hf-hotel-name').text();
				var text2 = $('#hotel-' + hotelId + ' .hf-hotel-country').text();
				$('#hf-enquiry-form h6 span span').text(text1 && text2 ? text1 + ', ' + text2 : 'Your Holiday');
				$('#hf-enquiry-form input[type=submit]').val('Proceed').click(function()
				{
					self.track('hotel-enquire-proceed');
				});
				
				setTimeout(function()
				{
					$('#hf-enquiry-form-container').modal({ persist: true, onOpen: self.modalOpen });
				}, 50);
			}
			else
			{
				this.addEnquiry();
			}
			
			this.track('hotel-enquire-begin');
			
			return false;
		},
		
		enquireAll : function()
		{
			if (!this.savedHotels.length)
			{
				alert('Please save some hotels before making an enquiry.');
				return false;
			}
			
			if (!this.enquiryData)
			{
				$('#hf-enquiry-form h6 span span').text('Your Holiday');
				$('#hf-enquiry-form input[type=submit]').val('Proceed');
				$('#hf-enquiry-form-container').modal({ persist: true, onOpen: this.modalOpen });
			}
			else
			{
				this.addEnquiry();
			}
			
			return false;
		},
		
		updateUrl : function()
		{
			if (this.loadingFromJson)
				return;
			
			location.hash = $.toJSON(
			{
				d : this.travelYear + '-' + this.travelMonth + '-' + this.travelDay,
				a : this.amenities,
				t : this.temperature,
				r : 500 - this.rainfall,
				f : this.flightTime,
				tr : this.transferTime,
				s : this.stars,
				ac : this.activities,
				c : this.countries,
				sh : this.savedHotels,
				dh : this.discardedHotels
			}).replace(/\s/g, '');
		},
		
		setSliderValue: function(slider, value)
		{
			slider = $(slider);
			
			slider.slider('value', value);
			slider.slider('option', 'slide').call(slider);
		},
		
		updateFromJson : function(json)
		{
			var self = this;
			
			try
			{
				var data = $.secureEvalJSON(decodeURIComponent(json));
			}
			catch (e)
			{
				return false;
			}
			
			try
			{
				var date = data.d.split('-');
				$('#travel-day').val(date[2]);
				$('#travel-month').val(date[1]);
				$('#travel-year').val(date[0]);
				
				this.setChecked('#hf-amenities', data.a);
				
				// Weather
				this.setSliderValue('#hf-temperature', data.t);
				this.setSliderValue('#hf-rainfall', data.r);
				
				// Journey
				this.setSliderValue('#hf-flight-time', data.f);
				this.setSliderValue('#hf-transfer-time', data.tr);
				
				// Hotel facilities
				this.setChecked('#hf-stars', data.s);
				this.setChecked('#hf-activities', data.ac);
				
				this.savedHotels = data.sh;
				this.discardedHotels = data.dh;
			}
			catch (e)
			{
				return false;
			}
			
			return data;
		},
		
		sortBy : function(sort)
		{
			this.sort = sort;
			this.updateHotels();
			
			return false;
		},
		
		addEnquiry : function()
		{
			var self = this;
			
			data = this.enquiryData;
			data['savedHotels[]'] = this.savedHotels;
			data.action = 'addEnquiry';
			
			var json = $.toJSON(data);
			if (json == this.lastEnquiryJson)
				return;
			
			this.lastEnquiryJson = json;
			
			data.href = location.href;
			
			$.modal.close();
			$('#hf-loading').modal({ onOpen : this.modalOpen });
			
			$.post(ROOT + '/holiday-finder-ajax/?rnd=' + Math.random(), data, function(data) { self.addEnquiryComplete(data); }, 'json');
		},
		
		addEnquiryComplete : function(data)
		{
			var self = this;
			
			$.modal.close();
			
			var options = { onOpen : this.modalOpen };
			
			if (!data.success)
			{
				this.enquiryData = '';
				this.lastEnquiryJson = '';
				options.onClose = function()
				{
					$.modal.close();
					self.enquireAll();
				};
			}
			
			$('#hf-thanks').html(data.message)
				.modal(options);
		},
		
		track : function(url)
		{
			try
			{
				if (typeof pageTracker != 'undefined')
					pageTracker._trackPageview('/holiday-finder/' + url + '/');
			}
			catch (e)
			{
				// Ignore it
			}
		}
	}
})(jQuery);

