﻿/**
 * @author: Jeremy Manoto
 */


var StepView = base2.Base.extend({
	constructor: function(options) {
		
	},
	
	ShowStep: function(number) {
		var step = this.Container.find(".step" + number);
		var targetHeight = step.css({ display: "block"}).find(".window").outerHeight();
		step.stop(true, false).animate({ height: targetHeight, marginBottom: 20});
		//jQuery.scrollTo(step, 800);
	},

	HideStep: function(number) {
		var step = this.Container.find(".step" + number);
		var targetHeight = 0;
		var previousStep = this.Container.find(".step" + (number - 1));
		//jQuery.scrollTo(previousStep, 800);
		step.stop(true, false).animate({ height: targetHeight, marginBottom: 0});
		
	},

	ResizeStep: function(number) {
		var step = this.Container.find(".step" + number);
		var targetHeight = step.find(".window").outerHeight();
		step.stop(true, false).animate({ height: targetHeight });
	},
	
	ShowStepLoader: function(number) {
		var loader = this.Container.find(".step" + number + " .loading");
		loader.show();
		this.ShowStep(number);
	},
	
	HideStepLoader: function(number){
		var loader = this.Container.find(".step" + number + " .loading");
		loader.hide();
		this.ShowStep(number);
	},
	
	/// Visually activate the specified node
	ActivateNode: function(node) {
		node.stop(true, false).animate({opacity: 1});
	},
	
	DeactivateNode: function(node) {
		node.stop(true, false).animate({opacity: 0.4});
	}
	
	
})




var PackageSelectionManager = StepView.extend({
	constructor: function(options) {
		this.SetOptions(options);
		this.LoadTemplates();
		this.SetEvents();
		this.Initialize();

	},
	
	Defaults: {
		Container: 						"#packages",
		LocationSelector:				"#ddlLocation",
		PackageSelector: 				"#ddlPackages",
		TemplatePackagePerformance: 	"/tessitura/templates/package_performance.html",
		TemplatePriceTypeSelection:		"/tessitura/templates/package_pricetype_selection.html",
		TemplatePackageSelection:		"/tessitura/templates/package_selection.html",
		StepPackageSelection:			"#packageSelection",
		StepPackageOptions:				"#packageOptions",
		StepPackagePerformances:		"#packagePerformances",
		StepPackagePrices:				"#packagePrices",
		StepPackageCart:				"#packageCart",
		StepPackageContinue:			"#packageContinue",
		PackageTotalSelector:			"#packageTotal",
		PackagePriceTypeSelector:		"#packagePrices .tblPriceTypes tbody"
	},

	Options: {},

	Container: null,
	
	Templates: {},
	
	Package: null,
	
	
/**
 * OPTIONS
 */
	SetOptions: function(options) {
		this.Options = jQuery.extend({}, this.Defaults, options);
		this.Container = jQuery(this.Options.Container);
		
	},

/** 
 * TEMPLATES
 */
	LoadTemplates: function() {
		this.Templates.PackagePerformance = new Template({ Path: this.Options.TemplatePackagePerformance }).Html;
		this.Templates.PackagePriceTypeSelection = new Template({ Path: this.Options.TemplatePriceTypeSelection }).Html;
		this.Templates.PackageSelection = new Template({ Path: this.Options.TemplatePackageSelection }).Html;
	},
	
/**
 * EVENTS
 */
	SetEvents: function() {
		
		/// Change Package Location Selection
		jQuery(this.Options.LocationSelector).change(jQuery.proxy(function(event) {
		//this.Container.delegate(this.Options.LocationSelector, "change", jQuery.proxy(function(event) {
			var selectedOption = jQuery(event.currentTarget);
			var seasonID = selectedOption.val();
			if (seasonID != "") {
				this.GetPackages(seasonID);
			} else {
				this.HideStep(4);
				this.HideStep(3);
				this.HideStep(2);
			}
			
		}, this));
		
		
		// Change Package Selection
		jQuery(this.Options.PackageSelector).change(jQuery.proxy(function(event) {
			var selectedOption = jQuery(event.currentTarget);
			var packageNumber = selectedOption.val();
			var packageData = selectedOption.find("option[selected]").data("package");
			this.LoadPackage(packageData);
			
		}, this));
		
		
		// Set the Performance Dates
		jQuery(".performance-venues select").livequery("change", jQuery.proxy(function(event) {
			var selectedOption = jQuery(event.currentTarget);  
			var facilityNumber = selectedOption.val();
			var performanceContainer = selectedOption.parents(".performance");
			var performanceData = performanceContainer.data("performanceGroup");
			this.LoadPerformanceDatesByFacility(facilityNumber, performanceData, performanceContainer);
			
		}, this));
		
		
		// Trigger the ticket type selection (on date change)
		jQuery(".performance-dates select").livequery("change", jQuery.proxy(function(event) {
			var selectedOption = jQuery(event.currentTarget);
			var performanceNumber = selectedOption.val();
			
			var performanceNumberArray = new base2.Array2();
			var performanceDates = jQuery(".performance-dates select");
			base2.Array2.forEach(performanceDates, function(performanceDate) {
				var value = jQuery(performanceDate).val();
				if (value != "") {
					performanceNumberArray.push(value);
				}
			});
			this.ValidatePackageSelections();

			this.LoadTicketTypes(performanceNumberArray);

		}, this));


		// Calculate the total prices
		jQuery(this.Options.StepPackagePrices + " select.quantity").livequery("change", jQuery.proxy(function(event) {
			var selectedOption = jQuery(event.currentTarget);
			var selectedQty = selectedOption.val();

			var row = selectedOption.parents("tr");
			var unitPrice = new Price(row.find(".unit-price").val());

			var totalPrice = unitPrice.Value * selectedQty;

			row.find(".subtotal-price").val(new Price(totalPrice).ToString());
			
		}, this));
		
		
		// Add the performance to the temporary cart
		jQuery(this.Options.StepPackagePrices + " .add.button").live("click", jQuery.proxy(function(event) {
			
			var button = jQuery(event.currentTarget);
			var row = button.parent().parent();
			var packageData = button.data("priceType");
			
			var quantity = row.find(".quantity").val();
			var totalPrice = new Price(row.find(".subtotal-price").val()).Value;
			
			if (quantity > 0) {
			
				var packageSelection = this.Container.find(this.Options.PackageSelector)
				var packageNumber = packageSelection.val();
				var packageDescription = packageSelection.find("option[selected]").html();
				
				packageData.quantity = quantity;
				packageData.totalPrice = totalPrice;
				packageData.packageNumber = packageNumber;
				packageData.packageDescription = packageDescription;
				
				this.AddPackage(packageData);
			}
		
			return false;
		}, this));
		
		
		// Remove the package selection from the temporary cart.
		jQuery(this.Options.StepPackageCart + " .remove").live("click", jQuery.proxy(function(event) {
			
			var row = jQuery(event.currentTarget).parent().parent();
			var packageData = row.data("packagePriceData");
			
			this.RemovePackage(packageData, row);
			
			
			return false;
			
		}, this));
		
		// Continue (Add to Cart)
		jQuery(this.Options.StepPackageContinue + " #btnContinue").live("click", jQuery.proxy(function(event) {
			
			this.AddPackagesToCart();
			
			return false;
			
		}, this)); 
		
	},
	
	
/**
 * INITIALIZE
 */
	Initialize: function() {

		// Hide the steps
		this.HideStep(2);
		this.HideStep(3);
		this.HideStep(4);
		this.HideStep(5);
		this.HideStep(6);
		this.HideStep(7);

		// Load the package locations to start with
		this.GetPackageLocations();
		
		
		this.UpdateSummary();
	},

/**
 * LOCATIONS
 */
	// Handle the package locations
	GetPackageLocations: function() {

		var response = new WSHandler({
			Url: "/services/Packages.asmx/GetPackageLocations",
			onSuccess: jQuery.proxy(function(response) {
							this.GetPackageLocationsHandler(response)
						}, this)
		});
	},


	GetPackageLocationsHandler: function(response) {
		if (response.result) {

			this.LoadPackageLocations(response.value);

		} else {
			alert("Problem retrieving the package locations");
		}
	},

	// Load the package locations into the drop down
	LoadPackageLocations: function(drPackageLocations) {
		var locationContainer = jQuery(this.Options.LocationSelector).empty();

		locationContainer.append("<option value=''>Please Select...</option>");
		base2.Array2.forEach(drPackageLocations, function(row) {
			var option = jQuery("<option />", {
							html: row.packagelocation_title,
							value: row.packagelocation_seasonid
						});

			locationContainer.append(option);	
			
		});
	},
	
/**
 * PACKAGES
 */
	// Get packages for a given seasonID (ie: Location!)
	GetPackages: function(seasonID) {
		
		var data = {
			seasonID: seasonID
		}
		
		var response = new WSHandler({
			Url: "/services/Packages.asmx/GetPackages",
			Data: JSON.stringify(data),
			onSuccess: jQuery.proxy(function(response) {
							this.GetPackagesHandler(response)
						}, this)
		});
	},
	
	
	GetPackagesHandler: function(response) {
		if (response.result) {
			
			this.LoadPackages(response.value);
			
		} else {
			alert("Problem retrieving the packages for the given location");
		}
	},
	
	
	LoadPackages: function(packages) {
		var packageContainer = jQuery(this.Options.PackageSelector).empty();
		
		this.HideStep(3);
		// Add Please Select... entry
		packageContainer.append("<option value=''>Please Select...</option>");
		base2.Array2.forEach(packages, function(packageItem) {
			
			var packageTitle = GetWebContent(packageItem.WebContent, "BSC Cart Production Title");
			
			if (packageTitle.length > 0) {
				packageTitle = packageTitle[0].ContentValue;
			} else {
				packageTitle = packageItem.ProductionTypeDescription
			}
			
			/*
			packageTitle = packageTitle.replace("<br>", " ");
			packageTitle = packageTitle.replace("<br/>", " ");
			packageTitle = packageTitle.replace("<br />", " ");
			packageTitle = packageTitle.replace("<br>", " ");
			*/
			var option = jQuery("<option />", {
							html: packageTitle,
							value: packageItem.PackageNumber
						});
			option.data("package", packageItem);
			
			packageContainer.append(option);	
			
		});
		
		packageContainer.change();
	},
	
/**
 * PACKAGE
 */

	// Load the Package with its Performances
	LoadPackage: function(packageData) {

		var performanceContainer = jQuery(this.Options.StepPackagePerformances);
		var packageOptionsContainer = jQuery(this.Options.StepPackageOptions);

		// Set Package Data
		packageOptionsContainer.data("package", packageData);
		this.Package = packageData;

		if (packageData == null) {
			this.HideStep(2);
			return;
		}

		// Set Package Name
		var packageTitle = GetWebContent(packageData.WebContent, "BSC Cart Production Title");
		packageOptionsContainer.find(".package-name").html(packageTitle[0].ContentValue);
		
		// Set Package Description
		var packageDescription = GetWebContent(packageData.WebContent, "BSC Package Intructions");
		packageOptionsContainer.find(".package-description").html(packageDescription[0].ContentValue);

		// Clear out the performances
		performanceContainer.empty();

		// Load in the new packages performance groups
		var counter = 1;
		base2.Array2.forEach(packageData.PerformanceGroups, jQuery.proxy(function(performanceGroup, index) {
			var performanceTemplate = jQuery(this.Templates.PackagePerformance);

			// Set the Performance Index
			performanceTemplate.find("h5").html("Performance " + (index + 1));

			// Set the Performance title
			var performanceTitle = GetWebContent(performanceGroup.WebContent, "BSC Cart Production Title");
			//performanceTemplate.find(".production-title").html(performanceGroup.Description);
			performanceTemplate.find(".production-title").html(performanceTitle[0].ContentValue);
			
			// Set the Performance Colour
			var performanceColour = GetWebContent(performanceGroup.WebContent, "BSC Colour");
			performanceColour = performanceColour[0].ContentValue;
			performanceTemplate.find(".production-title").addClass(performanceColour);
			
			// Set the Performance Info
			var performanceInfoText = GetWebContent(performanceGroup.WebContent, "BSC Production Info Tool Tip");
			var performanceInfo = performanceTemplate.find(".performance-info");
			performanceInfo.addClass(performanceColour);
			performanceInfo.attr({ title: performanceInfoText[0].ContentValue });
			


			// TODO: Set the Performance Image
			var performanceImage = GetWebContent(performanceGroup.WebContent, "BSC Production Image 215x96");
			performanceTemplate.find(".thumb").attr({
				src: performanceImage[0].ContentValue
			})

			// TODO: Populate Performance Venues
			var performanceVenuesContainer = performanceTemplate.find(".performance-venues select").empty();
			//performanceVenuesContainer.append("<option value=''>Please Select...</option>");
			if (performanceGroup.Facilities.length > 1) {
				base2.Array2.forEach(performanceGroup.Facilities, jQuery.proxy(function(facility){
					var option = jQuery("<option />", {
						html: facility.Description,
						value: facility.FacilityNumber
					});
					option.data("facility", facility);
					performanceVenuesContainer.append(option);
					
				}, this));
			} else {
				// Show a simple label instead
				var facility = performanceGroup.Facilities[0];
				
				var performanceVenueLabel = jQuery("<span />", { 
					html: facility.Description
				});
				performanceVenueLabel.addClass("venue");
				performanceVenuesContainer.replaceWith(performanceVenueLabel);
				
			}



			// TODO: Populate Performance Dates


			performanceTemplate.data("performanceGroup", performanceGroup);

			performanceContainer.append(performanceTemplate);

			if (performanceGroup.Facilities.length > 1) {
				performanceVenuesContainer.change();
			}
			else {
				this.LoadPerformanceDatesByFacility(facility.FacilityNumber, performanceGroup, performanceTemplate);
			}
			
			// DIFR
			performanceTemplate.find("h5, .production-title, .performance-info").DiFR({
	                DiFRPath: VirtualDirectory + "/services/difr.ashx",
					fontFamily: "AkzidenzGroteskBE-Bold"
	        });
			
			performanceTemplate.find(".field label.difr").DiFR({
				DiFRPath: VirtualDirectory + "/services/difr.ashx"
			})
			
			
			//TIPTIP
			performanceTemplate.find("a.performance-info").tipTip({ maxWidth:"400px", defaultPosition: "right", delay:200 });
			

		}, this));


		this.ShowStep(2);

	},



/**
 * PERFORMANCE VENUES / DATES
 */
	LoadPerformanceDatesByFacility: function(facilityNumber, performanceGroupData, performanceContainer) {

		// Find the dates for the performance using the facilityNumber
		var performances = base2.Array2.filter(performanceGroupData.Performances, function(performance) {
			return performance.FacilityNumber == facilityNumber;
		});

		// Populate the dates dropdown with the dates found.
		var performanceDatesContainer = performanceContainer.find(".performance-dates select").empty();
		performanceDatesContainer.append("<option value=''>Please Select...</option>");
		base2.Array2.forEach(performances, function(performance) {
			if (performance.PerformanceStatus == 1) {
				var date = Date.parse(performance.PerformanceDateTime);
				var option = jQuery("<option />", {
					html: date.toString("ddd d MMMM yyyy h:mm tt"),
					value: performance.PerformanceNumber
				});
				
				option.data("performance", performance);

				performanceDatesContainer.append(option);
			}
		});
	},

/**
 * PERFORMANCE TICKET TYPES
 */



	ValidatePackageSelections: function() {
		var result = true;
		
		this.HideStep(3);
		
		// number of performance selections should be >= minimum or <= maximum
		this.Package.MinimumPerformances
		
		var performanceDates = jQuery(".performance-dates select", this.Container);
		var numberSelected = 0;
		base2.Array2.forEach(performanceDates, jQuery.proxy(function(performanceDate){
			performanceDate = jQuery(performanceDate);
			var value = performanceDate.val();
			
			if (value != "") {
				numberSelected ++;
				
				// visually activate performance
				performanceNode = performanceDate.parents(".performance");
				this.ActivateNode(performanceNode);
				
			}
		}, this));
		
		if (numberSelected < this.Package.MinimumPerformances) result = false;
		if (numberSelected > this.Package.MaximumPerformances) result = false;
	
		// disable unselected nodes 
		if (result) {
			base2.Array2.forEach(performanceDates, jQuery.proxy(function(performanceDate) {
				performanceDate = jQuery(performanceDate);
				var value = performanceDate.val();
				
				if (value == "") {
					performanceNode = performanceDate.parents(".performance");
					this.DeactivateNode(performanceNode);
					
					performanceNode.addClass("inactive");
					performanceNode.find(".count").html(numberSelected);
					performanceNode.find(".max").html(this.Package.MaximumPerformances);
				}
				
			}, this))
		} else {
			// Show everything
			this.Container.find(".performance").removeClass("inactive");
			var performanceDates = this.ActivateNode(this.Container.find(".performance"));
			
			
		}
		
		return result;
	},
	
	

	LoadTicketTypes: function(performanceNumberArray) {

		var performanceDates = jQuery(".performance-dates select", this.Container);
		
		var canProceed = this.ValidatePackageSelections();
		

		if (canProceed) {
			// Open up the Ticket Types
			
			this.ShowStepLoader(2);
			
			var data = {
				packageNumber: this.Package.PackageNumber,
				performanceIDs: performanceNumberArray
			}
			
			var response = new WSHandler({
				Url: "/services/Packages.asmx/GetPackagePrices",
				Data: JSON.stringify(data),
				onSuccess: jQuery.proxy(this.LoadTicketTypesHandler, this),
				Async: true
			});
		}
	},


	LoadTicketTypesHandler: function(response) {
		this.HideStepLoader(2);
		var object = this;
		if (response.result) {

			this.ShowStep(3);

			var priceTypeData = response.value;

			var priceTypeContainer = this.Container.find(this.Options.PackagePriceTypeSelector).empty();

			var priceTemplate = object.Templates.PackagePriceTypeSelection;

			base2.Array2.forEach(priceTypeData, jQuery.proxy(function(priceType) {
				var priceTypeContainer = object.Container.find(this.Options.PackagePriceTypeSelector);

						
				var template = jQuery(priceTemplate);
				var typeName = priceType.priceTypeDescription.replace(this.Package.Description, "")
				typeName = typeName.split(" ")[typeName.split(" ").length - 1];
				template.find(".name").html(typeName);
				template.find(".unit-price").val(new Price(priceType.unitPrice).ToString());
				template.find(".add").data("priceType", priceType);

				priceTypeContainer.append(template);
				
			}, this));
			priceTypeContainer.find(".quantity").change();

			this.ShowStep(3);
		}

	},

/** 
 * SELECTED PERFORMANCES
 */
	GetSelectedPerformances: function() {
		var performances = new base2.Array2();

		var performanceDates = this.Container.find(".field.performance-dates");
		base2.Array2.forEach(performanceDates, function(performance) {
			performance = jQuery(performance);
			var performanceID = performance.val();
			performances.add(performanceID);
		});

		return performances;
	},
	
	/*
	 * Add a package to the temporary cart.
	 * 
	 */
	AddPackage: function(packagePriceData) {
		
		var data = {
			packagePriceType: packagePriceData
		}
		
		var response = new WSHandler({
			Url: "/services/Packages.asmx/AddPackageItem",
			Data: JSON.stringify(data),
			onSuccess: jQuery.proxy(this.AddPackageHandler, this),
			Async: true
		})
	},
	
	AddPackageHandler: function(response) {
		if (response.result) {
			
			var packageData = response.value;
			
			var template = jQuery(this.Templates.PackageSelection);
			
			var container = this.Container.find(this.Options.StepPackageCart + " .tblPriceTypes tbody");
			
			template.find(".name").html(packageData.packageDescription);
			var typeName = packageData.priceTypeDescription.replace(this.Package.Description, "");
			typeName = typeName.split(" ")[typeName.split(" ").length - 1];
			template.find(".type").html(typeName);
			template.find(".quantity").html(packageData.quantity);
			template.find(".price").html(new Price(packageData.totalPrice).ToString());
			template.data('packagePriceData', packageData);
			
			container.append(template);
			
			this.ShowStep(4);
			
			// Update the Summary
			this.UpdateSummary();
			
		} else {
			alert("could not add to temporary cart");
		}
	},
	
	RemovePackage: function(packagePriceData, element) {
		
		var data = {
			packagePriceType: packagePriceData
		}
		
		var response = new WSHandler({
			Url: "/services/Packages.asmx/RemovePackageItem",
			Data: JSON.stringify(data),
			onSuccess: jQuery.proxy(function(response) {
				if (response.result) {
					element.remove();
					this.ShowStep(4);
					this.UpdateSummary();
				} else {
					// Couldn't remove package item
				}
				
			}, this),
			Async: true
		})
	},
	
/**
 * CART SUMMARY
 */
	
	UpdateSummary: function() {
		
		var response = new WSHandler({
			Url: "/services/Packages.asmx/GetSelectedPackages",
			Async: true,
			onSuccess: jQuery.proxy(this.UpdateSummaryHandler, this)
		})
	},
	
	UpdateSummaryHandler: function(response) {
		
		if (response.result) {
			
			// Calculate total price
			var totalPrice = 0;
			base2.Array2.forEach(response.value, function(packageData) {
				totalPrice += packageData.totalPrice;
			})
			
			// Only show if total price > 0
			if (totalPrice > 0) {
				var ticketPrice = new Price(totalPrice);
				
				var handlingFee = 6;
				totalPrice += handlingFee;
				totalPrice = new Price(totalPrice);
				
				var container = jQuery(this.Options.PackageTotalSelector);
				container.find(".ticket-price").html(ticketPrice.ToString());
				container.find(".total-price").html(totalPrice.ToString());
				
				this.ShowStep(5);
				this.ShowStep(6);
				this.ShowStep(7);
			} else {
				// There's no selections ...
				this.HideStep(4);
				this.HideStep(5);
				this.HideStep(6);
				this.HideStep(7)
			}
		} else {
			this.HideStep(5);
			this.HideStep(6);
			this.HideStep(7);
		}
		
	},


/**
 * CONTINUE TO CART
 */

	AddPackagesToCart: function() {
		
		var response = new WSHandler({
			Url: "/services/Packages.asmx/AddPackagesToCart",
			Async: false,
			onSuccess: jQuery.proxy(function(response) {
				if (response.result) {
					// redirect to cart page
					window.location.href = "/cart";
				} else {
					alert("problem adding to cart");
				}
			})
			
		})
		
	}
})



/**
 * Gets
 * @param {Object} id
 */
	function GetWebContent(array, id) {
		var match = base2.Array2.filter(array, function(item) {
			return item.ContentTypeDescription == id;
		});
		
		return match;
	}

