﻿/**
 * static object that handles page logic for the accommodation prices page
 * @class 
 * @constructor
 * @param {jQuery} $ Reference to the jQuery object
 */
var AccoPrices = function($) {
	/**
	* @namespace Private methods and variables
	*/
	var priv = {

		/**
		* Image with loading animation.
		* @type jQuery
		* @private
		*/
		$loader: null,

		/**
		* Container to load price table into. Has attached data('url') with url where to load it from.
		* @type jQuery
		* @private
		*/
		$container: null,

		$wrapperDataContainer: null,

		$wrapperDataPointers: null,

		showPriceTable: function() {
			priv.$container.show();
			priv.$loader.hide();
		},

		initializeWrappers: function() {
			if (pricesWrapper) {
				priv.$wrapperDataContainer = pricesWrapper.newDataConfiguration();
				priv.$wrapperDataPointers = pricesWrapper.newPointerConfiguration();
				//new definition for the following pointers:
				priv.$wrapperDataPointers.month = { pointer: '#months', selectedPointer: null, fieldId: null, hasEvents: true, eventValue: true, falseExit: true, eventId: 'change' };
				priv.$wrapperDataContainer.occupancy = "";
				priv.$wrapperDataPointers.occupancy = { pointer: '#occupancy', selectedPointer: null, fieldId: null, hasEvents: true, eventValue: true, falseExit: true, eventId: 'change', afterEventCallback: function() { priv.saveOccupancy(this); } };
				priv.$wrapperDataContainer.transporttype = "";
				priv.$wrapperDataPointers.transporttype = { pointer: '#transport-type input', selectedPointer: '#transporttype input:checked', fieldId: null, hasEvents: true, eventValue: true, falseExit: true, eventId: 'change' };
				priv.$wrapperDataPointers.airport = { pointer: '#departure-airport', selectedPointer: null, fieldId: null, hasEvents: true, eventValue: true, falseExit: true, eventId: 'change' };
				//modification of the current default definition for pointer vtype:
				priv.$wrapperDataPointers.vtype.pointer = '#vacationlength input';
				priv.$wrapperDataPointers.vtype.selectedPointer = '#vacationlength input:checked';
				priv.$wrapperDataPointers.vtype.fieldId = null;
				priv.$wrapperDataPointers.vtype.hasEvents = true;
				priv.$wrapperDataPointers.vtype.eventValue = true;
				priv.$wrapperDataPointers.vtype.falseExit = true;
				priv.$wrapperDataPointers.vtype.eventId = 'change';
			}
		},

		sincronizeWrappers: function() {
			if (pricesWrapper) {
				pricesWrapper.configure(priv.$wrapperDataContainer, priv.$wrapperDataPointers);
			}
		},

		/**
		* Load price table using ajax from specified url.
		* @private
		*/
		loadPrices: function(url) {
			location.href = url;
			return false;
		},

		saveOccupancy: function(dataPointer) {
			var occupancy = priv.$wrapperDataContainer.occupancy;
			if (occupancy != null && occupancy != Occupancy.getOccupancy()) {
				Occupancy.disableAutoRefresh();
				Occupancy.saveTotalTravelers(occupancy);
			}
		},

		/**
		* Bind click event to the airport radio buttons, but only when there
		* are multiple airports to choose from.
		* @private
		*/
		bindAirportButtons: function() {
			$('#departure-airport').bind('change', function() {
				$.query.load(location.search);
				priv.url = $.query.set('airport', $(this).val()) + location.hash;
				return !priv.loadPrices(priv.url);
			});
		},

		/**
		* Bind click event to the transport type radio buttons
		* @private
		*/
		bindTransportTypeButtons: function() {
			$('#transport-type input').bind("change",
				function() {
					$.query.load(location.search);
					priv.url = $.query.set('transporttype', $(this).val()) + location.hash;
					return !priv.loadPrices(priv.url);
				}
			);
		},

		/**
		* Bind events on the links to questions popups in the main content area each time table is reloaded.
		* @private
		*/
		bindTableQuestionPopups: function() {
			// Bind methods to show popups for questions in main area
			$("div.questions div.item a").bind('click', function() {
				return priv.loadInLightbox(this, "questionPopup", true);
			});
		},

		/**
		* @private
		*/
		bindDurationLinks: function() {
			$("#vacationlength input").bind("change",
				function(evt) {
					priv.url = $(this).val();
					return !priv.loadPrices(priv.url);
				}
			);
			priv.bindLinks($("#prices .to-available a"));
		},

		/**
		* @private
		*/
		bindMonthLinks: function() {
			$("#months").bind("change",
				function(evt) {
					priv.url = $(this).val();
					return !priv.loadPrices(priv.url);
				}
			);

			priv.bindLinks($("#prices .soonerlater a"));
			priv.bindLinks($("#prices-bottom a"));
		},

		/**
		* @private
		*/
		bindLinks: function(links) {
			links.click(function() {
				priv.url = $(this).attr('href');
				return !priv.loadPrices(priv.url);
			});
		},

		/**
		* Bind events on the links to questions popups, both in the left sidebar and in the main content area.
		* @private
		*/
		bindQuestionPopups: function() {
			// add container for question popups
			$('body').append("<div id=\"questionPopup\"></div>");

			// Bind methods to show popups for questions in main area
			$("#questions div.item a, #prices div.item a").bind('click', function() {
				return priv.loadInLightbox(this, "questionPopup");
			});

			// Bind methods to show popups for questions in left sidebar
			$("#questions-left ul.questions li a").not(".more-questions").bind('click', function() {
				return priv.loadInLightbox(this, "questionPopup");
			});

			// Open faq in new window
			$("#questions-left ul.questions li a.more-questions").bind('click', function() {
				Utils.newWindow(this, 800, 640);
				return false;
			});
		},


		adjustLastminutesPopup: function($listItem, $lastminutePopup) {
			var top = $listItem.position().top;
			var topOffset = $listItem.offset().top;
			var winheight = $(window).height();
			var height = $lastminutePopup.height();
			if (topOffset - $(window).scrollTop() + height > winheight) {
				if (winheight > height) {
					$lastminutePopup.css('top', (top - $lastminutePopup.height() + 10) + 'px');
				}
				else {
					// default behaviour
				}
			}

		},

		bindLastminuteTooltip: function() {
			$("td.lastminute-trip").hover(
                function() {
                	var $listItem = $(this);
                	var $lastminutePopup = $("div.lastminuteTooltip", this);

                	var $informationBlock = $("#lastminute-tooltip-popup");
                	$informationBlock.css({ 'height': 'auto', 'border': 'none', 'padding': '5px' })
                	$informationBlock.height($informationBlock.get(0).offsetHeight + 20);
                	priv.adjustLastminutesPopup($listItem, $lastminutePopup);
                	$lastminutePopup.html($informationBlock.html());

                	$lastminutePopup.show();

                	return false;
                },
                function() {
                	var $lastminutePopup = $("div.lastminuteTooltip", this);
                	$lastminutePopup.hide();
                	$lastminutePopup.css('top', ($(this).position().top + $(this).height() + 2) + 'px');
                	return false;
                }
            )
		},

		/**
		* Actions to do when price table is loaded through ajax
		* @private
		*/
		onTableLoaded: function() {
			priv.bindQuestionPopups();
			if (priv.ajaxWrapperEnabled()) {
				priv.initializeWrappers();
				priv.sincronizeWrappers();
			}
			else {
				priv.bindTransportTypeButtons();
				priv.bindAirportButtons();
				priv.bindDurationLinks();
				priv.bindMonthLinks();
			}
			ExtendedPricesTooltip.InitTooltips();
			Occupancy.OnReady();
			priv.showPriceTable();
		},

		ajaxWrapperEnabled: function() {
			return (typeof (pricesWrapper) !== "undefined");
		},

		/**
		* Load the contents of the href of the anchor in a lightbox, wrapped in standard popup markup
		* @param {HTMLElement} anchor The anchor
		* @param {String} id ID to set on the popup container
		* @return {Boolean} false, to use in event handler and stop browser default behavior
		* @private
		*/
		loadInLightbox: function(anchor, id, newInstance) {
			var $anchor = $(anchor);

			var options = {
				container: document.getElementById(id),
				literal: false,
				title: $anchor.text(),
				contentUrl: $anchor.attr('href'),
				width: '643px',
				clone: false
			};
			var lightbox;
			if (newInstance) {
				lightbox = new Lightbox(options);
			}
			else {
				lightbox = Lightbox.CreateCached($anchor.attr('href'), options);
			}
			lightbox.Show();
			return false;
		},

		setFocus: function() {
			var endPricesFocus = $('#endPrices');
			if (endPricesFocus.length > 0) {
				$(endPricesFocus).focus();
			}
		},

		bindNoAvailablePrices: function() {
			var element = $("[id*='AvailableDurationAction']");
			if (element && element.length > 0) {
				element.each(function() {
					$(this).bind('click', function() {
						Occupancy.deleteCookie();							
					});
				});
			}
		}
	};

	/** @scope AccoPrices */
	return {

		/**
		* Initializes the logic for the current page
		* to be called on $(document).ready
		*/
		OnReady: function() {
			priv.$loader = $('#prices-loader');
			priv.$container = $('#prices-container');

			$("#acco-details-navigation aside").fixate({ align: "bottom", offset: 5, log: Log },
				function() {
					//IE7 hack
					$("#prices").css({ "zoom": "0" }).css({ "zoom": "1" });
				}
			);

			$(window).bind("ui-loaded",
				function() {
					$("#price-filters").css({ "opacity": 0, "visibility": "visible" }).animate({ "opacity": 1 }, 200);
				}
			);

			priv.url = location.href.replace(/#.*$/, '');
			priv.onTableLoaded();
			ExtendedPricesTooltip.OnReady();
			priv.bindLastminuteTooltip();
			Basket.OnReady();
			priv.bindNoAvailablePrices();
			if (priv.ajaxWrapperEnabled()) {
				pricesWrapper.setAfterPricesUpdateCallback(function() {
					AccoPrices.afterPricesUpdate();
				});
			}
			priv.setFocus();
		},

		afterPricesUpdate: function() {
			AccoPrices.OnReady();
			$("#tooltip-extra-info").hide();
			initPage();
		},

		/**
		* Add a newly selected price to the basket. Several parameters are used.
		*/
		AddToBasket: function(packageid, packagecode, duration, roomtype, departuredate, transportcode, airportcode, price, accommodationid, $curobj, evt) {
			//wiggle the scrollTop to make sure that the legend and basket are positioned correctly ($.fixate())
			ExtendedPricesTooltip.Hide();
			$("#legend").hide();
			$(window).scrollTop($(window).scrollTop() + 1).scrollTop($(window).scrollTop() - 1);
			Basket.AddToBasket(packageid, packagecode, duration, roomtype, departuredate, transportcode, airportcode, price, accommodationid, '', $curobj, evt, "281px", 281);
		},

		/*
		* Redraw the basket box. There are 2 possible situations:
		* 1. A price has been selected from the table, it will be added to the box
		* 2. The user closed the box. All parameters and previously selected prices will be cleared and the basket will be removed.
		* @param {Integer} height (Optional) The offset height of the basket. Used to determine whether to close or expand the basket.
		*/
		ReDraw: function(height) {
			Basket.ReDraw(height,
				function() {
					var $basketElem = $("#acco-details-navigation aside");
					//scroll to "book now" button
					if ($basketElem.offset().top + $basketElem.height() > $(window).scrollTop() + $(window).height()) {
						//$(window).scrollTop($basketElem.offset().top + $basketElem.height() - $(window).height());
						var scrollPos = $basketElem.offset().top + $basketElem.height() - $(window).height();
						$("html, body").animate({ scrollTop: scrollPos }, 300);
					}
					else {
						$(window).scrollTop($(window).scrollTop() + 1).scrollTop($(window).scrollTop() - 1);
					}
				}
			);
		},

		/**
		* Remove the basket; clear all parameters
		*/
		RemoveBasket: function(evt) {
			$('#basket-container').fadeOut(200,
				function() {
					$(this).find("iframe").attr("src", "about:blank");
					$("#legend").fadeIn(200);
					$(window).scrollTop($(window).scrollTop() + 1).scrollTop($(window).scrollTop() - 1);
					Basket.RemoveBasket();
				}
			);
		},

		/**
		* Get whether it is currently possible to open the tooltip
		* @return {Boolean} True if nothing prevents the tooltip from showing
		*/
		CanShowTooltip: function() {
			return !Basket.IsAnimating();
		},

		/**
		* Perform certain actions when starting animation of the basket
		*/
		StartingAnimation: function() {
			ExtendedPricesTooltip.Hide();
		}
	};
} (jQuery);
