

//http://plugins.jquery.com/project/HJS

AlpSystems.Transport.QuickQuote = new Class({
											
	Implements: [Events],

	initialize: function(config) {
		$.extend(this, {
			makeBookingUrl: "MakeBooking.php"
		});
		$.extend(this, config);
	},
	
	onDatePicked: function() {
		for(var i=1; i <= 2; i++) {
			//TODO parse date
			//display weekday
		}
	},
	
	flightArrives: "Flight arrives",
	flightDeparts: "Flight departs",
	dateTime: "Date/time",
	returnDateTime: "Returning",
	defaultDate1Text: "flightDeparts",
	defaultDate2Text: "flightArrives",
	
	getPlaceById: function(placeId) {
		//INEFF:
		for(var i=0; i < this.data.Places.length; i++) {
			var place = this.data.Places[i];
			if(place.PlaceId == placeId) {
				return place;
			}
		}
		
		return null;
	},
	
	isAdvanced: false,
	
	addJourney: function(e, number) {
		
		if(this.currentNumbers.length >= this.maxJournies) {
			alert("We can only accept up to " + this.maxJournies + " journies using this form.");
			return;
		}
		
		if(typeof(number) == "undefined") {
			//use next available:
			number = this.highestNumber+1;
			this.highestNumber++;
		}
		this.currentNumbers.push(number);
		
		if(number > this.highestNumber) {
			this.highestNumber = number;
		}
		
		$("#JourneyNumbers")[0].value = this.currentNumbers.join(",");
		
		var tpl = $("#JourneyTemplate")[0].innerHTML;
		tpl = tpl.replace(/XXX/g, number);
		
		var journeyDiv = document.createElement("div");
		journeyDiv.id = "Journey" + number;
		journeyDiv.innerHTML = tpl;
		
		$("#Journies")[0].appendChild(journeyDiv);
		
		AlpSystems.Util.setHtml($(".Number" + number), this.currentNumbers.length);
		
		this.initPlace($("#From" + number)[0], number);
		this.initPlace($("#To" + number)[0], number);

		this.initPassengers($("#Passengers" + number)[0]);
		
		$(".Delete" + number).bind("click", this.removeJourney.bind(this, number));

		
		$("#From" + number).bind("change", this.onChangeRoute.bind(this, number));
		$("#To" + number).bind("change", this.onChangeRoute.bind(this, number));

		this.fireEvent("OnAddJourney", number);

		//date text, handler on date change.
	},
	
	removeJourney: function(number) {
		
		if(this.currentNumbers.length == 1) {
			alert("Your booking must have at least one journey.");
			return;
		}
		
		var div = $("#Journey" + number)[0];
		div.parentNode.removeChild(div);

		var newNumbers = [];
		var haveFound = false;
		var newNumber = 1;
		for(var i=0; i < this.currentNumbers.length; i++) {
			var existingNumber = this.currentNumbers[i];
			if(number != existingNumber) {
				if(haveFound) {
					AlpSystems.Util.setHtml($(".Number" + existingNumber), newNumber);
				}
				
				newNumbers.push(existingNumber);
				newNumber++;
			} else {
				haveFound = true;
			}
		}
		
		this.currentNumbers = newNumbers;
		$("#JourneyNumbers")[0].value = this.currentNumbers.join(",");
	},
	
	maxJournies: 8,
	
	currentNumbers: [],
	highestNumber: 0,

	init: function() {
		if(this.isAdvanced) {
			var numbers = AlpSystems.Util.getUrlParam("JourneyNumbers");
			if(numbers == "") {
				//default to round trip since no info on the QS:
				numbers = "1,2";
			}
			
			var iaNumbers = numbers.split(",")
			for(var i=0; i < iaNumbers.length; i++) {
				var number = iaNumbers[i];
				this.addJourney(null, parseInt(number));
				AlpSystems.Util.setValue($("#From" + number)
					, this.setDefault(AlpSystems.Util.getUrlParam("From" + number), this.defaults.from)
				);
				AlpSystems.Util.setValue($("#To" + number), 
					this.setDefault(AlpSystems.Util.getUrlParam("To" + number), this.defaults.to)
				);
				this.onChangeRoute(number);
			}
			
			$(".AddJourney").bind("click", this.addJourney.bind(this));
			$(".Journey" + number + "Delete").bind("click", this.removeJourney.bind(this, number));
			
		} else {
			//simple version.
			this.currentNumbers = [1,2];
		
			///populate dropdowns with transport data:
			this.initPlace($("#From")[0], "");
			this.initPlace($("#To")[0], "");
			
			if($("#Passengers").length > 0) {
				this.initPassengers($("#Passengers")[0]);
			} else {
				this.initPassengers($("#Passengers1")[0]);
				this.initPassengers($("#Passengers2")[0]);
			}
			
			var typeSelects = $("#TransferType");
			if(typeSelects.length > 0) {
				this.initTransferType($("#TransferType")[0]);
			}
			
			///if one-way radio clicked, should hide second text input:
			$("input[name=IsReturn]").bind("click", this.isReturnChanged.bind(this));

			///for convenience, trigger radio click if click words too:
			$("#SingleText").bind("click", { newValue: "False"  }, this.clickedRadioText.bind(this));
			$("#ReturnText").bind("click", { newValue: "True"  }, this.clickedRadioText.bind(this));

			//set any search in progress from query string:
			$("#From")[0].value = this.setDefault(AlpSystems.Util.getUrlParam("From"), this.defaults.from);
			$("#To")[0].value = this.setDefault(AlpSystems.Util.getUrlParam("To"), this.defaults.to);
			if($("#Passengers").length > 0) {
				$("#Passengers")[0].value = this.setDefault(AlpSystems.Util.getUrlParam("Passengers"), this.defaults.passengers);
			}
				
			if($("#TransferType").length > 0) {
				$("#TransferType")[0].value = AlpSystems.Util.getUrlParam("TransferType");
			}
			
			if(AlpSystems.Util.getUrlParam("IsReturn") != "") {
				AlpSystems.Util.setValue($("[name=IsReturn]"), AlpSystems.Util.getUrlParam("IsReturn"));
			}
			
			this.isReturnChanged();
		}

		for(var i=0; i < this.currentNumbers.length; i++) {
			var number = this.currentNumbers[i];
			
			AlpSystems.Util.setValue($("#Passengers" + number), 
				this.setDefault(
					AlpSystems.Util.getUrlParam("Passengers" + number), this.defaults["passengers" + number]
				)
			);

			AlpSystems.Util.setValue($("#Date" + number + "Date"),
				AlpSystems.Util.getUrlParam("Date" + number + "Date")
			);
			AlpSystems.Util.setValue($("#Date" + number + "Hour"),
				AlpSystems.Util.getUrlParam("Date" + number + "Hour")
			);
			AlpSystems.Util.setValue($("#Date" + number + "Minute"),
				AlpSystems.Util.getUrlParam("Date" + number + "Minute")
			);
			AlpSystems.Util.setValue($("#Date" + number + "HourMinute"),
				AlpSystems.Util.getUrlParam("Date" + number + "HourMinute")
			);
			
			this.onDatePicked(number);
		}

		///hook up get quote button
		$("#GetQuoteButton").bind("click", function() { $("#QuickQuoteForm")[0].submit(); });
		
		if(!this.isAdvanced) {
			//if Date1Text is defined, that means we should adjust "Flight arrives" / "Flight departs" / "Pickup time"
			//depending on if airports are in from/to.
			$("#From").bind("change", this.onChangeRoute.bind(this, ""));
			$("#To").bind("change", this.onChangeRoute.bind(this, ""));
			this.onChangeRoute("");
			
			$("#Date1Date").bind("change", this.onDateChange.bind(this));
			$("#Date2Date").bind("change", this.onDateChange.bind(this));
			this.onDateChange();
		}
	},
	
	onDateChange: function() {
		for(var i=1; i <= 2; i++) {
			var date = Date.parseExact($("#Date" + i + "Date")[0].value, ["d/M/yyyy", "d/M/yy"]);
			if(date == null) {
				AlpSystems.Util.setHtml($(".Date" + i + "Day"), "");
			} else {
				AlpSystems.Util.setHtml($(".Date" + i + "Day"), date.toString("dddd"));
			}
		}
	},
	
	setDefault: function(value, defaultValue) {
		if(value == "") {
			return defaultValue;
		} else {
			return value;
		}
	},
	
	onChangeRoute: function(index) {
		
		if(typeof(index) == "undefined") {
			index = "";	
		}
		
		if($("#From" + index)[0].value == "") {
			//no from, can't begin to guess.
			return;
		}
		
		var from = AlpSystems.Transport.getPlaceById(this.data.Places, $("#From" + index)[0].value);
		
		if(from.IsAirport) {
			//assume airport to resort:
			AlpSystems.Util.setHtml($("#DateLabel" + (index == "" ? "1" : index)),
				this.flightArrives.replace("Flight", from.TransitModeName)
			);
			if(index == "") {
				//simple search mode. Set date2 to assume return:
				AlpSystems.Util.setHtml($("#DateLabel2"),
					this.flightDeparts.replace("Flight", from.TransitModeName)
				);
			}
		} else if($("#To" + index)[0].value == "") {
			//assume they're doing resort to airport for now:
			AlpSystems.Util.setHtml($("#DateLabel" + (index == "" ? "1" : index)), this[this.defaultDate1Text]);
			if(index == "") {
				AlpSystems.Util.setHtml($("#DateLabel2"), this[this.defaultDate2Text]);
			}
		} else {
			var to = AlpSystems.Transport.getPlaceById(this.data.Places, $("#To" + index)[0].value);
			
			if(to.IsAirport) {
				//resort to airport:
				AlpSystems.Util.setHtml($("#DateLabel" + (index == "" ? "1" : index)), this.flightDeparts.replace("Flight", to.TransitModeName));
				if(index == "") {
					AlpSystems.Util.setHtml($("#DateLabel2"), this.flightArrives.replace("Flight", to.TransitModeName));
				}
			} else {
				//looks like resort to resort transfer:
				AlpSystems.Util.setHtml($("#DateLabel" + (index == "" ? "1" : index)), this.dateTime);
				if(index == "") {
					AlpSystems.Util.setHtml($("#DateLabel2"), this.returnDateTime);
				}
			}
		}

	},
	
	clickedRadioText: function(context) {
		AlpSystems.Util.setValue(document.forms.QuickQuoteForm.elements.IsReturn, context.data.newValue);
		this.isReturnChanged();
	},
	
	isReturnChanged: function() {
		if(AlpSystems.Util.getValue(document.forms.QuickQuoteForm.elements.IsReturn) == "False") {
			$("#Date2Wrapper").addClass("hidden");
			$("#Passengers2Wrapper").addClass("hidden");
			$(".ReturnInput").addClass("hidden");
		} else {
			$("#Date2Wrapper").removeClass("hidden");
			$("#Passengers2Wrapper").removeClass("hidden");
			$(".ReturnInput").removeClass("hidden");
		}
	},
	
	getQuoteClicked: function() {
		document.location.href = this.makeBookingUrl + "?" + this.getParams("qs");
	},
	
	addGroup: function(groupId, groupName, input) {
		var group = $.create("optgroup", {attributes: {label: groupName}});
		for(var i=0; i < qqData.Places.length; i++) {
			var place = qqData.Places[i];
			if(place.DisplayOrder <= 0 || typeof(place.Groups[groupId]) == "undefined") {
				continue;
			}
			
			var option = $.create("option", {attributes: {value: place.PlaceId}, children: place.Name});
			option.appendTo(group);
		}

		group.appendTo(input);
	},
	
	initPlace: function(input, number) {
		
		//want e.g. "From" and "To" 
		var eventSuffix = input.id.replace(number, "");
		
		///let the client change the ordering of places. Note than any changes are permanent!
		this.fireEvent("BeforeRender" + eventSuffix, {
			Places: this.data.Places
		});
		
		if((eventSuffix == "From" && this.fromGroups != null)
			|| (eventSuffix == "To" && this.toGroups != null)){
			//group mode - output the indicated groups of places:
			var groups = eventSuffix == "From" ? this.fromGroups : this.toGroups;
			
			for(var i=0; i < groups.length; i++) {
				this.addGroup(groups[i].groupId, groups[i].label, input);
			}
		} else {
			//norlam mode - all places with display order  > 0:
			for(var i=0; i < this.data.Places.length; i++) {
				var place = this.data.Places[i];
				if(place.DisplayOrder <= 0) {
					continue;
				}
				
				var option = $.create("option", {attributes: {value: place.PlaceId}, children: place.Name});
				option.appendTo(input);
			}
		}
		
		this.fireEvent("OnRender" + eventSuffix, {
			Select: input,
			Places: this.data.Places
		});
	},
	
	defaults: {
		passengers: null,
		from: null,
		to: null,
		passengers1: null,
		passengers2: null
	},

	initPassengers: function(input) {
		for(var i=1; i <= this.data.MaxPassengers; i++) {
			$.create("option", {attributes: {value: i}, children: i}).appendTo(input);
		}
	},
	
	initTransferType: function(input) {
		for(var i=0; i < this.data.TransferTypes.length; i++) {
			var type = this.data.TransferTypes[i];
			var option = $.create("option", {attributes: {value: type.TransferTypeId}, children: type.Name});
			option.appendTo(input);
		}
	},
	
	isPreventing: false,
	preventCalCutoffHack: function() {
		if(!this.isPreventing) {
			window.setInterval(this.preventCalCutoffHack.bind(this), 100);
			this.isPreventing = true;
		}
		
		var popup = $("#ui-datepicker-div");
		if(popup.length == 0) {
			return;
		}
		
		popup = popup[0];
		if(popup.style.position == "absolute" && popup.style.display != "none") {
			var popupBottom = popup.offsetTop + popup.offsetHeight;
			var frame = $("#QuickQuoteForm")[0];
			var frameBottom = frame.offsetTop + frame.offsetHeight;
			
			if(popupBottom > frameBottom) {
				var topPixels = parseInt(popup.style.top, 10); //http://stackoverflow.com/questions/395163/get-css-top-value-as-number-not-as-string
				var fudge = 6;
				//$("#AirportLabel")[0].innerHTML = (topPixels - (popupBottom - frameBottom) - fudge) + "px";return;
				popup.style.top = (topPixels - (popupBottom - frameBottom) - fudge) + "px";
			}
			
		}
	}
});

AlpSystems.Transport.TransformPlaceOrder = new Class({
	initialize: function(config) {
		$.extend(this, config);
	},
	
	transforms: [],
	
	filter: function(context) {
		
		///swap display order of those if group1 with group2, then reorder the places by display order:
		for(var i=0; i < context.Places.length; i++) {
			var place = context.Places[i];
			for(var j=0; j < this.transforms.length; j++) {
				var transform = this.transforms[j];
				if(place.DisplayOrder >= transform.from && place.DisplayOrder < transform.to) {
					place.DisplayOrder += transform.offset;
					break; //only apply one rule to avoid chaining effects between rules.
				}
			}
		}
		
		context.Places.sort(function(a, b) {
			if(a.DisplayOrder < b.DisplayOrder) {
				return -1;
			} else if(a.DisplayOrder == b.DisplayOrder) {
				return 0;
			} else {
				return 1;
			}
		 });
	}
});
	
AlpSystems.Transport.GroupPlaces = new Class({

	initialize: function(config) {
		$.extend(this, config);
	},
	
	groupBy: 1,
	
	filter: function(context) {
		
		var nextDivAt = this.groupBy*2;
		var placeId = null;
		for(var i=0; i < context.Select.options.length; i++) {
			if(context.Select.options[i].value == "") {
				//for websites that default from/to to blank, ignore this one.
				continue;
			}
			
			var placeId = context.Select.options[i].value;
			
			var place = AlpSystems.Transport.getPlaceById(context.Places, placeId);
			if(place.DisplayOrder >= nextDivAt) {
				///output a divider option in between groups of places:
				var sep = $.create("option", {
					attributes: {value: ""}, children: "------------------------"});
				
				context.Select.insertBefore(sep[0], context.Select.options[i]);
				nextDivAt += this.groupBy;
				i += 1;
			}
		}
	}
});


