/**
 * @author Jeremy Manoto
 * @param {Object} options
 */


	/** 
	 * Displays a table of rates for a given product
	 * @param {Object} options
	 */
	var RateProductSelector = ProductSelector.extend({
		constructor: function(options){
			//this.base(options);
			this.SetOptions(options);
			this.LoadTemplates();
			this.LoadRateTemplates();
			this.Load();
			//this.SetEvents();
			this.SetRateEvents();
		},
		
		/**
		 * Overlay Product Selector
		 * @param {Object} options
		 */
		productSelector: null,

		Table: null,

		Container: null,

		RateDefaults: {
				ProductCode: "",
				Context: "",
				APIRates: GBPServiceUrl + "/{channelID}/rates",
				APIBestAvailableRate: true,
				Channel: GBPChannel,
				DateFormat: "yyyy/MM/dd",
				Container: "#GBPRates",
				RenderContainer: ".Holder-bkg",
				SelectedDate: new Date(),
				MaxDailyDetails: 9,
				Template: "/gbp/templates/gbp_productselector.html",
				TemplateRatesTable: "/gbp/templates/gbp_rates_table_options.html",
				TemplateSalesConfig: "/gbp/templates/gbp_productselector_salesconfig.html",
				TemplateDailyDetail: "/gbp/templates/gbp_productselector_dailydetail.html",
				TemplateOption: "/gbp/templates/gbp_productselector_option.html",
				TemplateOptionsRow: "/gbp/templates/gbp_productselector_optionsrow.html",
				Cart: null, //required
				ShowDates: true,
				ReplaceSalesConfigName: false
			},
			
		Dodgy: false,

		SetOptions: function(options) {
		
			this.Options = jQuery.extend({}, this.Defaults, this.RateDefaults, options);
			
			this.Options.ContainerSelector = this.Options.Container;
			
			this.ProductData = this.Options.ProductData;
			
			this.Cart = this.Options.Cart
		},
		
		LoadRateTemplates: function() {
			this.Templates.RatesTable = LoadTemplate(this.Options.TemplateRatesTable);
		},
		
		SetRateEvents: function() {
			var object = this;
			
			this.Table.delegate(".tbody .day:not(.inactive)", "click", function() {
				var MAXREQUESTS = 3;
				var day = jQuery(this);

				if (object.Table.find(".day.loading").length <= MAXREQUESTS 
					&& !day.hasClass("loading")
					&& !day.hasClass("inactive")) {

					day.addClass("loading");

					//Determine if addon
					var isAddon = day.parent().hasClass("addon");
					var salesConfigHasAddons = day.parent().next().hasClass("addon");	
					
					if (salesConfigHasAddons && !day.parent().hasClass("open")){
						//if this sales configuration has addons, automatically expand them
						day.parent().children().eq(0).click();
					}				

					/***********************************************************
					 * ADD/REMOVE FROM CART
					 */
					var salesConfig = day.parent().data("salesConfiguration");
					var productData = object.Table.data("product");
					var criteria = object.CriteriaDefinitions();
					//var date = object.SelectedDate().toString("yyyy/MM/dd");
					
					var parent = day.parent();
					var index = parent.find(".day").index(day);
					
					var date = Date.parse(day.data("dailyDetail").Date).toString(object.Options.DateFormat);
					
					var callback = function(purchase) {
						day.removeClass("loading");
						//day.toggleClass("active");
						object.Cart.Purchase = purchase;
						object.MapPurchase(purchase);
					}
					
					
					//Addon Sales ConfigurationID
					var addonSalesConfigurationID = null;
					if (isAddon) {
						var addonData = day.parent().data("addonConfiguration");
						addonSalesConfigurationID = addonData.SalesConfigurationID
					}
					if (!day.hasClass("active")) {
						//Add to Cart
						//var result = object.Cart.Add(object.OrderGuid, productData.ProductCode, salesConfig.SalesConfigurationID, date, criteria, callback);
						var result = object.Cart.Add(object.OrderGuid, productData.ProductCode, salesConfig.SalesConfigurationID, date, criteria, addonSalesConfigurationID, callback);
					}
					else {
						//Remove from Cart
						var component = day.data("component");
						//var result = object.Cart.Remove(object.OrderGuid, productData.ProductCode, salesConfig.SalesConfigurationID, date, criteria, callback)
						var result = object.Cart.Remove(component, productData.ProductCode, salesConfig.SalesConfigurationID, date, criteria, callback)
					}
				} else {
					// Too many requests...wait for others to finish
				}
			});
			
			
			
			this.SetEvents_NiceForms();

			
		},

		GetRates: function(date) {

			//this.InitializeLoadingRates();

			var data = {
				ProductIDs: new base2.Array2(),
				StartDate: date.toString(this.Options.DateFormat),
				BestAvailableRate: this.Options.APIBestAvailableRate,
				Criteria: this.CriteriaDefinitions(),
				MinimalBAR: this.Options.APIBestAvailableRate
			}
			data.ProductIDs.push(this.Options.ProductCode);

			var apiHandler = new APIHandler({
				Url: this.Options.APIRates.replace("{channelID}", this.Options.Channel),
				Method: APIMETHODS.POST,
				Async: true,
				Data: JSON.stringify(data),
				Callback: jQuery.proxy(this.GetRatesPost, this)
			})
			
			//this.FinalizeLoadingRates();
		},

		GetRatesPost: function(response) {
			if (response.Result) {
				var ratesData = response.Value;
				this.SetRates(ratesData);
				if (this.Cart.Purchase) {
					this.MapPurchase(this.Cart.Purchase);
				}

			} else {
				
			}
			
			this.FinalizeLoadingRates();
		},


		SetDate: function(year, month, day) {
			this.InitializeLoadingRates();
			var dateObj = {
				year: parseInt(year),
				month: parseInt(month),
				day: parseInt(day)
			}
			
			this.Options.SelectedDate = new Date().set(dateObj);
			
			this.GetRates(this.Options.SelectedDate);
			
			if (this.Options.ShowDates) {
				this.SetDates(this.Options.SelectedDate);
			}
			else {
				this.Table.find('.thead .th').hide();
			}
		},

		/**
		 * Sets the date labels for the Rates Table
		 * @param {Object} startDate DateJS object
		 */
		SetDates: function(startDate) {
			var object = this;
			var ratesTable = this.Table;
			
			var ratesHead = ratesTable.find(".thead");
			
			var limit = this.Options.MaxDailyDetails;
			
			var day = ratesHead.find(".day:first");
			if (day.length > 0) {
				for (i = 0; i < limit; i++) {
					day.removeClass("weekend");
					var dayOfWeek = startDate.toString("ddd");
					day.html(dayOfWeek + "<br/>" + startDate.toString("d MMM"));
					
					if (dayOfWeek == "Sat" || dayOfWeek == "Sun") {
						day.addClass("weekend");
					}
					var dayDate = Date.parse(startDate.toString(this.Options.DateFormat));
					day.data("date", dayDate);
					
					startDate.add({
						days: 1
					});
					//Increment
					day = day.next();
				}
			}
		},

		SetRates: function(ratesData) {
			var object = this;

			var ratesTable = this.Table;
			var ratesBody = ratesTable.find(".tbody");
			ratesBody.empty();		
			
			var itemTemplate = this.Templates.DailyDetail;
			var salesConfigTemplate = this.Templates.SalesConfig;

			if (!ratesData.Products || ratesData.Products.length == 0) {
				return;
			}
			
			var product = ratesData.Products[0];
			ratesTable.data("product", product);
			


			
			var replaceSalesConfigName = this.Options.ReplaceSalesConfigName;
			
			base2.Array2.forEach(product.SalesConfigurations, function(salesConfig) {
				var salesTemplate = salesConfigTemplate;
				var hasAddons = salesConfig.Addons.length > 0;

				var name = salesConfig.Name;
				
				if (replaceSalesConfigName) {
					name = product.ProductName;
				}

				salesTemplate = salesTemplate.replace("%LABEL%", name);
				salesTemplate = salesTemplate.replace("%SELECTIONLABEL%", "No selection");

				salesTemplate = jQuery(salesTemplate);

				var col1 = salesTemplate.find(".col1");
				var col2 = salesTemplate.find(".col2");
				
				if (salesConfig.MouseOverText != null && salesConfig.MouseOverText != "") {
					col1.attr({ title: salesConfig.MouseOverText});
					col1.tipTip({
							maxWidth: "150px",
							defaultPosition: "top",
							delay: 0
						});
				}

				// Render the Daily Rates
				var count = 0
				base2.Array2.forEach(salesConfig.DailyDetails, function(dailyDetail) {
						var item = itemTemplate;
						var price = new Price(dailyDetail.DisplayAmount, {Precision: 0});

						item = item.replace("%PRICE%", price.Price());
						item = jQuery(item);
						item.data("dailyDetail", dailyDetail);
						item.attr("title", dailyDetail.MouseOverText);
						item.find(".NFCheck").attr("src", "/gbp/" + item.find(".NFCheck").attr("src"));
						item.tipTip({
							maxWidth: "150px",
							defaultPosition: "top",
							delay: 0
						})

						if (dailyDetail.Inactive) {
							item.empty();
							item.html("<span>" + price.Price() + "</span>");
							item.addClass("inactive");
						} else {
							
						}
						
						col2.before(item);
						count = count + 1;
				});
				salesTemplate.data("salesConfiguration", salesConfig);
				var salesTemplateID = "sc" + salesConfig.SalesConfigurationID;
				salesTemplate.attr("id", salesTemplateID);
				salesTemplate.addClass("sales-config");
				if (hasAddons) {
					salesTemplate.addClass("expandable");

					//Set Addon Rates expand/hide event
					salesTemplate.find(".col1").click(function() {
						var addonRows = jQuery(".addon[rel=" + salesTemplateID + "], ");

						var salesTemplateRow = jQuery(this).parent();
						var action = "open";
						if (salesTemplateRow.hasClass("open")) {
							action = "close";
						} 

						switch(action) {
							case "open":
								addonRows.show();
								salesTemplateRow.addClass("open");
								break;
							case "close":
								addonRows.hide();
								salesTemplateRow.removeClass("open");
								break;
						}
					});


				}
				
				
				ratesBody.append(salesTemplate);
				
				
				// Addons				
				if (hasAddons) {
					//display heading
					
					var headingRow = "<div  class='tr addon-heading addon' rel='" + salesTemplateID + "'><div colspan='11'><span>Extras</span></div></div>"
					ratesBody.append(headingRow);
					
					//Show daily details
					base2.Array2.forEach(salesConfig.Addons, function(addon) {
						var addonTemplate = salesConfigTemplate;
						
						addonTemplate = addonTemplate.replace("%LABEL%", addon.Name);
						addonTemplate = addonTemplate.replace("%SELECTIONLABEL%", "No selection");
						
						addonTemplate = jQuery(addonTemplate);
						
						var col1 = addonTemplate.find(".col1");
						var col2 = addonTemplate.find(".col2");
						
						if (addon.MouseOverText != null && addon.MouseOverText != "") {
							col1.attr({ title: addon.MouseOverText});
							col1.tipTip({
									maxWidth: "150px",
									defaultPosition: "top",
									delay: 0
								});
						}
						
						// Render the Addon Daily Rates
						var count = 0
						base2.Array2.forEach(addon.DailyDetails, function(dailyDetail) {
								var item = itemTemplate;
								var price = new Price(dailyDetail.DisplayAmount, {Precision: 0});
		
								item = item.replace("%PRICE%", price.Price());
								item = jQuery(item);
								item.data("dailyDetail", dailyDetail);
								item.attr("title", dailyDetail.MouseOverText);
								item.tipTip({
									maxWidth: "150px",
									defaultPosition: "top",
									delay: 0
								});
								
								//var isActive = price.IsPrice();
								if (dailyDetail.Inactive) {
									item.empty();
									item.html("<span>" + price.Price() + "</span>");
									item.addClass("inactive");
								} else {

								}
								col2.before(item);
								count = count + 1;
						});
						addonTemplate.data("salesConfiguration", salesConfig);
						addonTemplate.data("addonConfiguration", addon);
						addonTemplate.attr("id", "sc" + salesConfig.SalesConfigurationID + "-" + addon.SalesConfigurationID);
						addonTemplate.attr("rel", salesTemplateID);
						addonTemplate.addClass("addon");
						ratesBody.append(addonTemplate);

					})

					var footerRow = "<div class='tr addon-footer addon' rel='" + salesTemplateID + "'><div colspan='11'>&nbsp;</div></div>";
					ratesBody.append(footerRow);

				}

			});

		},

		Load: function() {
			//Table container
			var container = jQuery(this.Options.Container);

			//Load the Rates Table Template
			this.Container = jQuery(this.Templates.RatesTable);
			this.Container.attr("id", this.Options.ContainerSelector.replace("#", ""));
			
			if (!this.Options.ReplaceSalesConfigName)
				this.Container.find(".productTitle").text(this.Options.ProductData.ProductName);
			else
				this.Container.find(".productTitle").text('');
				
			container.append(this.Container);

			this.Popup = this.Container;
			//this.Container.find(".productTitle").html(this.Options.ProductData.ProductName);

			this.Table = this.Container.find(".bookingRates");
			this.Table.data("RateProductSelector", this);
			
			this.LoadCriteriaDefinitions(this.Options.ProductData);
		},

		ResizeContainer: function() {
			
		}

	});
	
	
	
	/** 
	 * Best Available Rate Product Selector
	 * Specific type of rate selector that only retrieves the best available rate and redirects users to the 
	 * corresponding product page 
	 * @param {Object} options
	 */
	var BARateProductSelector = RateProductSelector.extend({
		constructor: function(options) {
			this.base(options);
			this.SetStyles();
			this.SetEvents_Url();
		},
		
		SetOptions: function(options) {
			
			this.Options = jQuery.extend({}, this.Defaults, this.RateDefaults, options);
			
			this.Options.ContainerSelector = this.Options.Container + "_" + this.Options.ProductCode;
			
			this.ProductData = this.Options.ProductData;
			
			this.Cart = this.Options.Cart
		},
		
		SetStyles: function() {
			this.Container.addClass("BAR");
		},
		
		SetEvents_Url: function() {
			
			this.Container.delegate(".sales-config", "click", jQuery.proxy(function(event) {
				var productData = this.Options.ProductData;
				
				var redirectUrl = GetContent(productData.Content, "Website").Media[0].Url;
				
				var date = this.RateProductManager.SelectedDate();
				window.location = redirectUrl + "&date=" + date.toString(this.Options.DateFormat);
				
			}, this));
		},
		
		CriteriaDefinitions: function() {
			return this.DefaultCriteriaDefinitions();
		}
	})
	
	
	

	/**
	 * Manages the products displayed on a product rates page
	 * @param {Object} options
	 */
	var RateProductManager = base2.Base.extend({
		constructor: function(options) {
			this.SetOptions(options);
			this.LoadTemplates();
			this.DiscoverProductCode();

			
			//this.LoadProductData();
			this.SetRateEvents();
			//this.Initialize();
		},
		
		/**
		 * Rates table product table
		 * @param {Object} options
		 */
		RateProductSelectors: new base2.Array2(),
		
		ProductData: null,
		
		Container: null,
		
		Cart: null,

		SetOptions: function(options) {
			this.Defaults = {
				DiscoverProductCode:	true,
				APIProductPage: GBPServiceUrl + "/{channelID}/page/{pageID}/product",
				PageID:	null,
				ProductCode: "",
				Context: "",
				APIProductsRelated: "",
				Channel: GBPChannel,
				DateFormat: "yyyy/MM/dd",
				DateJumpSize: 9,
				Container: "#rates",
				SelectedDate: new Date(),
				TransferUrl: "https://www.tasmanianbookings.com.au/Transfer/?c={context}",
				APIProductsOther: GBPServiceUrl + "/{channelID}/product/{productid}/related/{date}/{count}",
				MaxProductsOther: 30,
				TemplateRates: "/gbp/templates/gbp_rates.html",
				Upsell: "",
				Cart: null
				
			}

			this.Options = jQuery.extend({}, this.Defaults, options);
			
			this.Container = jQuery(this.Options.Container);
			this.Cart = this.Options.Cart;
		},
		
		
		LoadTemplates: function() {			
			var mainTemplate = LoadTemplate(this.Options.TemplateRates);
			this.Container.append(mainTemplate);
		},
		
		DiscoverProductCode: function() {
			if (this.Options.DiscoverProductCode) {
				var url = this.Options.APIProductPage.replace("{channelID}", this.Options.Channel).replace("{pageID}", this.Options.PageID);
				
				var response = new APIHandler({
					Url: url,
					Method: APIMETHODS.GET,
					Async: false
				}).Response;
				
				if (response.Result) {
					this.Options.ProductCode = response.Value.ProductCode;
					this.ProductData = response.Value;
					this.Container.addClass(this.ProductData.ProviderColour);
					this.Load();
				} else {
					this.LoadProductData();
				}
			} else {
				this.LoadProductData();
			}
		},
		
		SetRateEvents: function() {
			var object = this;
			// Set the date picker
			this.Container.find('.datepicker').each(function(){
				var a = jQuery('.trigger', this);
				jQuery(this).append('<div class="datepopup"></div><input type="hidden" name="' + a[0].id + '" value="' + a[0].innerHTML + '"/>');
				jQuery('.datepopup', this).datepicker({
					inline: true,
					dateFormat: 'dd MM yy',
					onSelect: function(date, inst){
						a.find('span').html(date).end().
							parents('.datepicker').
								removeClass('datepicker-active').
								find('input[type="hidden"]').val(date).end();
						
						//GBP Set Date
						object.SetDate(inst.selectedYear, inst.selectedMonth, inst.selectedDay);
						
					}
				});
				jQuery('.trigger', this).click(function(){
					jQuery(this.parentNode).toggleClass('datepicker-active');
					object.Container.find(".NFSelectTarget").hide();
					
					return false;
				});
			});
			
			
			// Transfer to Cart
			this.Container.delegate("#transferToCart a, #transferToCart a span", "click", function() {
				if (object.Cart.Purchase.Products && object.Cart.Purchase.Products.length > 0) {
					object.TransferToGBP();
				}
				
				return false;
			})
			
			
			
			// Prev
			this.Container.delegate(".bookingRates .prev", "click", function() {
				
				var date = object.SelectedDate();

				var newDate = date.add({days: -object.Options.DateJumpSize});

				var year = newDate.toString("yyyy");
				var month = parseInt(newDate.toString("M")) - 1; // for 0 based index
				var day = newDate.toString("d");

				//object.InitializeLoadingRates();
				object.SetDate(year, month, day);
				//object.MapPurchase(object.Cart.Purchase);

				return false;
			});
			// Next
			this.Container.delegate(".bookingRates .next", "click", function() {
				
				var date = object.SelectedDate();

				var newDate = date.add({days: object.Options.DateJumpSize});

				var year = newDate.toString("yyyy");
				var month = parseInt(newDate.toString("M")) - 1; // for 0 based index
				var day = newDate.toString("d");

				//object.InitializeLoadingRates();
				object.SetDate(year, month, day);
				//object.MapPurchase(object.Cart.Purchase);

				return false;
			});
			
		},
		
		
		Initialize: function() {
			// Set the date to today
			var selectedDate = this.Options.SelectedDate;
			this.Container.find(".datepopup").datepicker("setDate", selectedDate);
			this.Container.find(".datepicker .trigger span").text(selectedDate.toString("dd MMM yyyy"))
			
			this.SetDate(selectedDate.toString("yyyy"), parseInt(selectedDate.toString("M")) - 1, selectedDate.toString("d"));
			
			
			
		},
		
		SetDate: function(year, month, day) {
			var dateObj = {
				year: parseInt(year),
				month: parseInt(month),
				day: parseInt(day)
			}

			var date = new Date().set(dateObj);

			this.Container.find(".datepopup").datepicker("setDate", date);
			this.Container.find(".datepicker .trigger span").text(date.toString("dd MMM yyyy"));


			// Set the date for each product selector
			base2.Array2.forEach(this.RateProductSelectors, function(rateProductSelector) {
				rateProductSelector.SetDate(year, month, day);
			});
		},

		Load: function() {
			var object = this;
			if (this.Options.ProductCode != null && this.Options.ProductCode != "") {
				
				//Load the primary rates table
				var rateProductSelectorOptions = {
					APIBestAvailableRate: false,
					ProductCode: 	this.Options.ProductCode,
					Context: 		this.Options.Context,
					Channel: 		GBPChannel,
					DateFormat: 	this.Options.DateFormat,
					SelectedDate: 	this.Options.SelectedDate,
					ProductData: 	this.ProductData,
					Container:		"#primaryRates"
				}

				var rateProductSelector = new RateProductSelector(rateProductSelectorOptions);
				rateProductSelector.Cart = this.Cart;
				rateProductSelector.RateProductManager = this;
				this.RateProductSelectors.push(rateProductSelector);


				// Load the other products

				var url = this.Options.APIProductsOther.replace("{channelID}", this.Options.Channel).replace("{productid}", this.Options.ProductCode).replace("{date}", this.Options.SelectedDate.toString("yyyy-MM-dd")).replace("{count}", this.Options.MaxProductsOther);

				var response = new APIHandler({
					Url: url, 
					Method: APIMETHODS.GET,
					Async: true,
					Callback: jQuery.proxy(this.LoadOtherProducts, object)

				});


			}
		},

		LoadProductData: function() {
			var call = new ProductContent(this.Options.ProductCode, {
				Callback: jQuery.proxy(this.LoadProductDataContent, this)
			});
		},

		LoadProductDataContent: function(response) {
			if (response.Result) {
				this.ProductData = response.Value;
				this.Container.addClass(this.ProductData.ProviderColour);
				this.Load();
			}
		},
		
		LoadOtherProducts: function(response) {
			
			if (response.Result) {
			    var productCount = 0;

			    if (response.Value.length == 0) {
			        //there are no related products, hide the 'other options' container
			        jQuery("#otherRates").hide();
			    }
				
				base2.Array2.forEach(response.Value, jQuery.proxy(function(product) {
					//Load the primary rates table
					var rateProductSelectorOptions = {
						APIBestAvailableRate: true,
						ProductCode: 		product.ProductCode,
						Context: 			this.Options.Context,
						Channel: 			GBPChannel,
						DateFormat: 		this.Options.DateFormat,
						SelectedDate: 		this.Options.SelectedDate,
						ProductData: 		product,
						TemplateRatesTable: "/gbp/templates/gbp_rates_table.html",
						Container: 			"#otherRates",
						ReplaceSalesConfigName: true,
						ShowDates: productCount++ == 0
					}
	
					var rateProductSelector = new BARateProductSelector(rateProductSelectorOptions);
					rateProductSelector.Cart = this.Cart;
					rateProductSelector.RateProductManager = this;
					this.RateProductSelectors.push(rateProductSelector);
	
						
				},this));
				
			}
			
			this.Initialize();
			
		},



		TransferToGBP: function() {
			var url = this.Options.TransferUrl.replace("{context}", contextID);

			window.location.href = url;
		},
		
		SelectedDate: function() {
			var dateContainer = this.Container.find(".datepopup");
			var dateData = dateContainer.data("datepicker");
			
			var dateObj = {
				year: dateData.selectedYear,
				month: dateData.selectedMonth,
				day: dateData.selectedDay
			}
			
			var date = new Date().set(dateObj).clearTime();
			
			return date;
		}

		
	});
	
	
	

