﻿/**
 * static object that handles page logic
 * @class
 * @constructor
 * @param {jQuery} $ Reference to the jQuery object
 */
var SearchMain = function($) {

	/**
	* @namespace Private methods and variables
	*/
	var priv = {
		freeTextInputElement: "#inp-search",
		freeTextSubmitElement: "#btnsearch",
		showLocationTooltip: true,
		calendarInputElement: 'span.seldate input',
		calendarObj: null,

		/**
		* maximum number of tips to show initially
		* @private
		*/
		maxTips: 10,

		/**
		* Container object, holding references to the lightboxes that have been initialized in this page.
		* Using this each lightbox only has to be instantiated once, when it is first called.
		* @type {Lightbox}
		* @private
		*/
		lightboxes: {},

		/**
		* Generic way to open a new lightbox: the contents of the container identified by the supplied id
		* are loaded in a lightbox. Also, the lightbox is cached and thus only has to be initialized once.
		* @param {String} id The id of the container to show in the lightbox
		* @param {Object} options (Optional) Several options can be supplied to override default behavior of just
		* loading the contents of the container. When supplied, these options will be used to initialize the lightbox.
		* @private
		*/
		openLightbox: function(id, options) {
			if (typeof (options) == 'undefined' || !options) {
				options = { container: document.getElementById(id) };
			}
			var lightbox = Lightbox.CreateCached(id, options);
			lightbox.Show();
		},

		/**
		* Show the element matching the supplied ID in a lightbox. Used on the offers page.
		* @param {HTMLElement} anchor The anchor element referencing the popup contents.
		* @param {String} id The id of the popup container
		* @return {Boolean} Returns false to allow event handlers to easily stop default browser behavior
		* @private
		*/
		showOfferInfoInLightbox: function(anchor, id) {
			priv.openLightbox(id, {
				container: document.getElementById(id),
				contentUrl: $(anchor).attr('href'),
				width: '500px'
			});
			return false;
		},

		showAirportInfoInLightbox: function(anchor, id) {
			priv.openLightbox(id, {
				container: document.getElementById(id),
				literal: true,
				contentUrl: $(anchor).attr('href'),
				width: '332px'
			});
			return false;
		},

		/**
		* Bind general events for this page
		* @private
		*/
		bindEvents: function() {
			if (location.href.indexOf('personal=') != -1) {
				$('body').addClass('search-personal');
			}

			priv.bindTextSearch();
			priv.bindViewSizeEvents();
			priv.bindPricesBlockEvents();
			priv.bindMoreEvents();
			Main.bindViewedFavoritesEvents();
		},

		bindViewSizeEvents: function() {
			// event for page viewsize
			var cookieKey = Resource.GetText('cookie-prefix') + 'viewsize';
			var viewSize = $.cookie(cookieKey);

			if (viewSize != null && viewSize != "") {
				$('#inp-resultaten').val(viewSize);
			}

			$('#inp-resultaten').bind('change', function() {
				$.cookie(cookieKey, $(this).val(), { expires: 100, path: '/' });

				var newUrl = $.query.REMOVE('No');

				if (newUrl == '') {
					newUrl = window.location.pathname;
				}

				location.href = decodeURIComponent(newUrl);
			});
		},

		bindPricesBlockEvents: function() {
			$('div.offerinfo a.show-prices').each(function(index, value) {
				var height = $(this).closest('div.offerinfo').height();
				$(this).height(height);
				$(this).find('img.transparent').height(height);
			});
		},

		bindMoreEvents: function() {
			// events for more hidden dimension links	    
			$('div.list-top-holder div.box a.morelink').bind('click', function() {
				$('div.hiddenlinks', $(this).parent().parent().parent()).toggle();
				return false;
			});

			$("body").bind("click",
				function() {
					$('div.hiddenlinks').hide();
				}
                );
		},

		/**
		* bind free text search action
		* @private
		*/
		bindTextSearch: function() {
			if ($(priv.freeTextInputElement).length) {
				if ($.query.get('searchtext').toString() != '') {
					$(priv.freeTextInputElement).val($.query.get('searchtext'));
				}

				$(priv.freeTextSubmitElement).bind("click", priv.textSearch);
				if ($(priv.freeTextInputElement).val() != Resource.GetText('search_free_text')) {
					$(priv.freeTextSubmitElement).get(0).disabled = false;
				}
				$(priv.freeTextInputElement).bind("focus", function() {
					$(priv.freeTextSubmitElement).get(0).disabled = false;
					if (this.value == Resource.GetText('search_free_text')) {
						this.value = '';
					}
					else {
						this.select();
					}
				});

				$(priv.freeTextInputElement).bind("keydown", function(evt) {
					if (evt.keyCode == 13) {
						priv.textSearch();
					}
				});

				$(priv.freeTextInputElement).bind("keyup", function(evt) {
					if ($(this).val() == '') {
						$(priv.freeTextSubmitElement).removeClass('btnsearch-enabled');
						$(priv.freeTextSubmitElement).addClass('btnsearch-disabled');
					}
					else {
						$(priv.freeTextSubmitElement).addClass('btnsearch-enabled');
						$(priv.freeTextSubmitElement).removeClass('btnsearch-disabled'); ;
					}
				});

				// autocomplete functionality
				$(priv.freeTextInputElement).autocomplete(Resource.GetText('path_prefix') + "/js/ajax/get_searchsuggestions.ashx", {
					selectFirst: false,
					delay: 10,
					width: 244,
					max: 15,
					matchSubset: false
				}).result(function(event, item) {
					priv.textSearch();
				});
			}
		},

		/**
		* Redirects the page with the correct free text search parameter
		* @private
		*/
		textSearch: function() {
			$input = $(priv.freeTextInputElement);
			if ($input.val() != '' && $input.val() != Resource.GetText('search_free_text')) {
				var searchpage = location.href.indexOf(Resource.GetText('offerspage')) > -1 ? Resource.GetText('offerspage') :
					Resource.GetText('searchpage');
				var redirectUrl = Resource.GetText('path_prefix') + '/' + searchpage + "?searchtext=" +
					encodeURIComponent($input.attr("value"));

				location.href = redirectUrl;
			}
		},

		buildCalendar: function() {
			priv.initCalendar();

			$('a.btnSelectDate, a.btnSelectDateAnimate').bind('click', function(e) {
				if (priv.calendarObj) {
					priv.calendarObj.show();
				}
			});
		},

		/**
		* @private
		*/
		initCalendar: function() {
			if (typeof (Calendar) != "undefined" && Calendar) {
				var calendarTime = new Timer();
				var datesObject = priv.getDatesObject();
				// global variables like reloadWithAjax, showImageLink coming from user controls should be checked for existence before using
				priv.calendarObj = new Calendar({
					inputElement: priv.calendarInputElement,
					showImageLink: typeof (showImageLink) != "undefined" && showImageLink == 'true',
					updateInputOnSelect: false,
					hideDatePickerOnSelect: false,
					datesObject: datesObject,
					numberOfMonths: typeof (departureMonthSelected) != "undefined" && departureMonthSelected == 'True' ? 1 : 3,
					hideIfNoPrevNext: typeof (departureMonthSelected) != "undefined" && departureMonthSelected == 'True' ? true : false
				});

				var curSelDate = $('#hidSelDate').length ? $('#hidSelDate').val() : $.query.get('seldate').toString();
				var daterange = $.query.get('daterange') != '' ? $.query.get('daterange') : $('select.daterange').val();
				var addDays = priv.getAddDays(daterange);
				priv.calendarObj.build(curSelDate, addDays);

				Log.Info("Main: Calendar Javascript init time was: " + (calendarTime.Stop()) + "ms ", -1);
			}
		},

		getDatesObject: function() {
			if (typeof (firstDate) == "undefined" || typeof (lastDate) == "undefined" || typeof (departDates) == "undefined") {
				return null;
			}

			return {
				firstDate: firstDate,
				lastDate: lastDate,
				departDates: departDates
			};
		},

		getAddDays: function(daterange) {
			var addDays = 0;

			if (daterange == '2') {
				addDays = 3;
			} else if (daterange == '3') {
				addDays = 7;
			} else {
			}

			return addDays;
		},

		showParticipantSelection: function() {
			if (location.href.indexOf('personal=') == -1 && Occupancy.getOccupancy() <= 0 && (location.href.indexOf('aanbiedingen.htm') != -1 ||
			location.href.indexOf('zoeken.htm') != -1)) {
				Occupancy.showTravelersPopup();
				/** Set default number of adults (2) **/
				$('#nr-adults').val("2");
				Occupancy.changeNrAdults();
			}
		}
	};

	/** @scope SearchMain */
	return {

		changeDateRange: function(parDaterange) {
			if (reloadDates == 'True') {
				var type = 'type=search&';
				if (Resource.GetText('isofferspage') == 'true') {
					type = 'type=offers&';
				}
				$.getJSON(Resource.GetText('path_prefix') + '/js/ajax/departure-dates.aspx?' + type + location.href.split('?')[1], function(data) {
					firstDate = data.firstDate;
					lastDate = data.lastDate;
					departDates = data.departDates;
					SearchMain.doChangeDateRange(parDaterange);
				});
				reloadDates = 'False';
			} else {
				SearchMain.doChangeDateRange(parDaterange);
			}
		},

		doChangeDateRange: function(parDaterange, reloadDates) {
			var daterangeVal = parDaterange;
			if (daterangeVal == null)
				daterangeVal = $('select.daterange').val();
			var nValues = $.query.get('N').toString();
			if (daterangeVal == '-1') {
				location.href = location.href.split('?')[0] + SearchMain.getQueryStringWithoutDates();
			} else {
				if (location.href.indexOf('?') == -1) {
					location.href = location.href + '?daterange=' + daterangeVal;
				} else {
					var curSelDate = $.query.get('seldate').toString();
					if (curSelDate != '' && nValues != '') {
						var addDays = 0;
						if (daterangeVal == '2') {
							addDays = 3;
						} else if (daterangeVal == '3') {
							addDays = 7;
						}
						// get the selected date and get the mindate and maxdate in the range
						var minDate = 0;
						var maxDate = 0;
						if (curSelDate != '') {
							var dtCurSelDate = Date.fromString(curSelDate.substring(6, 8) + '/' + curSelDate.substring(4, 6) + '/' + curSelDate.substring(0, 4));
							minDate = parseInt(dtCurSelDate.addDays(addDays * -1).asString2());
							maxDate = parseInt(dtCurSelDate.addDays(addDays * 2).asString2());
						}
						var newNvalues = '';
						var selectQuery = '';
						var selNValues = '';
						// loop through the date range and build the string with the nvalues to select
						// - and build the string with all the querystrings
						for (var i = minDate; i <= maxDate; i++) {
							if (departDates['d' + i] != null && departDates['d' + i] != '') {
								var queryString = departDates['d' + i].split(',')[1];
								var nValue = departDates['d' + i].split(',')[2];
								selNValues += selNValues == '' ? nValue : '+' + nValue;

								var startIndex = queryString.indexOf('N=');
								if (startIndex != -1) {
									var endIndex = queryString.indexOf('&', startIndex);
									if (endIndex == -1) {
										endIndex = queryString.length + 1;
									}
									selectQuery += '||' + queryString.substring(startIndex + 2, endIndex).replace(/\+/g, '||');
								}
							}
						}
						selectQuery += '|';

						// remove the departuredays nvalues, so only the other nvalues are left over
						for (var key in departDates) {
							var nValue2 = departDates[key].split(',')[2];
							if (selectQuery.indexOf('|' + nValue2 + '|') != -1) {
								selectQuery = selectQuery.replace(new RegExp('/|' + nValue2 + '|/', 'g'), '');
							}
						}

						// combine the to selected departuredays nvalues with the other selected nvalues
						var splitOtherNvalues = selectQuery.split('|');
						for (var j = 0; j < splitOtherNvalues.length; j++) {
							if (splitOtherNvalues[j] != '' && ('+' + selNValues + '+').indexOf('+' + splitOtherNvalues[j] + '+') == -1) {
								selNValues += '+' + splitOtherNvalues[j];
							}
						}

						newNvalues = selNValues;
						if (newNvalues == '') {
							newNvalues = '0';
						}
						var newUrl = $.query.REMOVE('No').set('N', newNvalues).set('daterange', daterangeVal);
						location.href = decodeURIComponent(newUrl.toString());
					} else {
						location.href = $.query.empty().set('daterange', daterangeVal);
					}
				}
			}
		},

		getQueryStringWithoutDates: function() {
			var nValues = $.query.get('N').toString().replace(/ /gi, '+');

			if (location.href.indexOf('?') != -1) {
				// undo departure filter
				var queryString = location.href.split('?')[1];
				var arrnValues = nValues.split('+');
				var newNvalues = '';
				for (var key in departDates) {
					var nValue = departDates[key].split(',')[2];
					for (var i = 0; i < arrnValues.length; i++) {
						if (nValue == arrnValues[i]) {
							arrnValues[i] = '';
						}
					}
				}
				for (var j = 0; j < arrnValues.length; j++) {
					if (arrnValues[j] != '') {
						// Do not use '+' as the separator which gets url encoded, use '_' instead.
						newNvalues += newNvalues == '' ? arrnValues[j] : '_' + arrnValues[j];
					}
				}
				if (newNvalues == '') {
					newNvalues = '0';
				}
				var newUrl = $.query.load(queryString).REMOVE('seldate').REMOVE('No').set('N', newNvalues);
				// Replace back above separator by the normal nValue separator +
				return newUrl.toString().replace(/_/gi, '+');
			}
		},

		clearNdp: function(newSearchText) {
			var newUrl = $.query.REMOVE('ndp').REMOVE('Ndp');

			if (typeof (newSearchText) != 'undefined') {
				if (newSearchText == '') {
					$.query.REMOVE('searchtext');
				} else {
					$.query.SET('searchtext', newSearchText);
				}
			}

			location.href = decodeURIComponent(newUrl.toString() == '' ? '?' : newUrl.toString());
		},

		/**
		* Initializes the logic for the current page
		* to be called on $(document).ready
		*/
		OnReady: function() {
			priv.bindEvents();
			priv.showParticipantSelection();
		}
	};
} (jQuery);
