String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}

Oasys.QuickQuote = function() {
	
	this.init = function() {
		$("QuickQuoteForm").action = this.oasysUrl;
		$("QuickQuoteForm").method = "POST";
		
		Event.observe($("QQ_From"), "change", this.initialSelected.bindAsEventListener(this, "QQ_From"));
		Event.observe($("QQ_To"), "change", this.initialSelected.bindAsEventListener(this, "QQ_To"));
		Event.observe($("QQ_Passengers"), "change", this.initialSelected.bindAsEventListener(this, "QQ_Passengers"));
		Event.observe($("QQ_Hour1"), "change", this.initialSelected.bindAsEventListener(this, "QQ_Hour1"));
		Event.observe($("QQ_Minute1"), "change", this.initialSelected.bindAsEventListener(this, "QQ_Minute1"));
		Event.observe($("QQ_Hour2"), "change", this.initialSelected.bindAsEventListener(this, "QQ_Hour2"));
		Event.observe($("QQ_Minute2"), "change", this.initialSelected.bindAsEventListener(this, "QQ_Minute2"));

		Event.observe($("QQ_Date1"), "focus", this.dateFocus.bindAsEventListener(this, "QQ_Date1"));
		Event.observe($("QQ_Date1"), "blur", this.dateBlur.bindAsEventListener(this, "QQ_Date1"));

		Event.observe($("QQ_Date1_Cal"), "click", this.datePickerClicked.bindAsEventListener(this, "QQ_Date1"));
		Event.observe($("QQ_Date2_Cal"), "click", this.datePickerClicked.bindAsEventListener(this, "QQ_Date2"));

		Event.observe($("QQ_Date2"), "focus", this.dateFocus.bindAsEventListener(this, "QQ_Date2"));
		Event.observe($("QQ_Date2"), "blur", this.dateBlur.bindAsEventListener(this, "QQ_Date2"));

		Event.observe($("QQ_Single"), "click", this.isReturnChanged.bindAsEventListener(this, false));
		Event.observe($("QQ_Return"), "click", this.isReturnChanged.bindAsEventListener(this, true));

		Event.observe($("QQ_From"), "change", this.fromChanged.bind(this));

		Event.observe($("QQ_SubmitButton"), "click", this.getQuote.bind(this));

		this.isChanged = {
			QQ_Date1: false,
			QQ_Date2: false
		};

		this.makeTimePicker(1);
		this.makeTimePicker(2);

		this.initials = {
			QQ_Date1: $("QQ_Date1").value,
			QQ_Date2: $("QQ_Date2").value
		};
		
		Ext.onReady(this.extReady.bind(this));
		
		document.onclick = this.documentClick.bind(this);
	}
	
	this.fromChanged = function() {
		var isAirport = placeInfo[$("QQ_From").value].isAirport;
		
		var text1;
		var text2;
		if(isAirport) {
			text1 = Oasys.QuickQuote.strings["Arrival date..."];
			text2 = Oasys.QuickQuote.strings["Departure date..."];
		} else {
			text2 = Oasys.QuickQuote.strings["Arrival date..."];
			text1 = Oasys.QuickQuote.strings["Departure date..."];
		}
		
		if(!this.isChanged["QQ_Date1"]) {
			$("QQ_Date1").value = text1;	
		}

		if(!this.isChanged["QQ_Date2"]) {
			$("QQ_Date2").value = text2;	
		}
	}
	
	this.makeTimePicker = function(id) {
		$("QQ_Hour" + id).options[$("QQ_Hour" + id).options.length] = new Option("", "");
		for(var i=0; i < 24; i++) {
			if(i < 10) {
				text = "0" + i;
			} else {
				text = i;
			}
			$("QQ_Hour" + id).options[$("QQ_Hour" + id).options.length] = new Option(text, i);
		}

		$("QQ_Minute" + id).options[$("QQ_Minute" + id).options.length] = new Option("", "");
		for(var i=0; i < 60; i+=5) {
			if(i < 10) {
				text = "0" + i;
			} else {
				text = i;
			}
			$("QQ_Minute" + id).options[$("QQ_Minute" + id).options.length] = new Option(text, i);
		}		
	}
	
	this.documentClick = function(e) {
		
		if(e == null) {
			element = event.srcElement;
		} else {
			element = e.element();
		}

		for( ; element.tagName != "BODY"; element = element.parentNode) {
			if(element.id == "QQ_Date1_Cal"
			   || element.id == "QQ_Date1_CalPopup"
			   || element.id == "QQ_Date2_Cal"
			   || element.id == "QQ_Date2_CalPopup"
			) {
				return;
			}
		}
		
		this.datePickers["QQ_Date1"].hide();
		this.datePickers["QQ_Date2"].hide();
	}
	
	this.datePickerClicked = function(e, dateId) {
		for(var i=0; i < this.datePickerKeys.length; i++) {
			key = this.datePickerKeys[i];
			if(key == dateId) {
				var picker = this.datePickers[key];
				
				if(this.parseDate(key) != null) {
					//value already set in text field. use it.
					picker.setValue(this.parseDate(key));
				} else if(key == "QQ_Date2"
					&& this.parseDate("QQ_Date1") != null) {
					//popping up date2. no date2 set yet, so use default of date1:
					picker.setValue(this.parseDate("QQ_Date1"));
				} // else, no dates to guess so use whatever ext defaults (today)
				
				picker.show();
			} else {
				this.datePickers[key].hide();
			}
		}
	}
	
	this.datePickers = [];
	this.datePickerKeys = [];
	
	this.extReady = function() {
		this.addDatePicker("QQ_Date1");
		this.addDatePicker("QQ_Date2");
		
		this.setInitialDate(1);
		this.setInitialDate(2);
		
		if(getUrlParam("fromPlaceId") != "") {
			$("QQ_From").value = getUrlParam("fromPlaceId");
			this.fromChanged();
			this.initialSelected(null, "QQ_From");
		}

		if(getUrlParam("toPlaceId") != "") {
			$("QQ_To").value = getUrlParam("toPlaceId");
			this.initialSelected(null, "QQ_To");
		}
		
		if(getUrlParam("isRoundTrip") != "") {
			var isRoundTrip = (getUrlParam("isRoundTrip") == "true");
			$("QQ_Return").checked = isRoundTrip
			$("QQ_Single").checked = !isRoundTrip;
			this.isReturnChanged(null, isRoundTrip);
		}
		
		if(getUrlParam("passengers") != "") {
			$("QQ_Passengers").value = getUrlParam("passengers");
			this.initialSelected(null, "QQ_Passengers");
		}
	}
	
	this.setInitialDate = function(index) {
		if(getUrlParam("sDate" + index) != "") {
			var date1 = Date.parseDate(getUrlParam("sDate" + index), "Y-m-d H:i");
			if(!isNaN(date1)) {
				$("QQ_Date" + index).value = date1.format("d/m/Y");
				this.onDateSet("QQ_Date" + index);
			
				$("QQ_Hour" + index).value = date1.getHours();
				$("QQ_Minute" + index).value = date1.getMinutes();
				
				this.initialSelected(null, "QQ_Hour" + index);
				this.initialSelected(null, "QQ_Minute" + index);
			}
		}
	}
	
	this.addDatePicker = function(dateId) {
		
		datePicker = this.datePickers[dateId] = new Ext.DatePicker({
			minDate: new Date(),
			listeners: {
				"select": this.onDatePicked.bindAsEventListener(this, dateId)
			}
		});
		
		datePicker.render(dateId + "_CalPopup");
		datePicker.hide();
		
		this.datePickerKeys.push(dateId);
	}
	
	this.onDatePicked = function(e, dateId) {
		$(dateId).value = this.datePickers[dateId].getValue().format('d/m/Y');
		this.datePickers[dateId].hide();
		this.onDateSet(dateId);
		//IE zindex bug:
		$("QQ_Date2_Cal").style.visibility = "visible";
	}
	
	this.parseDate = function(dateId) {
		formats = [
			"d/m/y",
			"d/m/Y",
			"j/m/y",
			"j/m/Y",
			"d/n/y",
			"d/n/Y",
			"j/n/y",
			"j/n/Y" ];

		for(var i=0; i < formats.length; i++) {
			date = Date.parseDate($(dateId).value, formats[i]);
			if(date) {
				return date;
			}
		}
		
		return null;
	}
	
	this.isReturnChanged = function(e, newValue) {
		$("QQ_Date2_Elements").style.display = newValue ? "" : "none";
	}
	
	this.getQuote = function() {
		errors = [];
		
		/// Do type level error validation before sending to server:
		
		if($("QQ_From").value == "") {
			errors["fromPlaceId"] = Oasys.QuickQuote.strings.PleaseSelect.replace(/@field/g, Oasys.QuickQuote.strings.FromPlace);
		}

		if($("QQ_To").value == "") {
			errors["toPlaceId"] = Oasys.QuickQuote.strings.PleaseSelect.replace(/@field/g, Oasys.QuickQuote.strings.ToPlace);
		}

		if($("QQ_Passengers").value == "") {
			errors["passengers"] = Oasys.QuickQuote.strings.PleaseSelect.replace(/@field/g, Oasys.QuickQuote.strings.PassengersField);
		}

		if(!this.isChanged["QQ_Date1"]) {
			errors["date1"] = Oasys.QuickQuote.strings.PleaseSelect.replace(/@field/g, Oasys.QuickQuote.strings.Date1);
			date1 = null;
		} else {
			date1 = this.parseDate("QQ_Date1");
	
			if(date1 == null) {
				errors["date1"] = Oasys.QuickQuote.strings.DateInvalid.replace(/@field/g, Oasys.QuickQuote.strings.Date1);
			}
		}

		if(typeof(this.dropdownsSelected["QQ_Hour1"]) == "undefined" 
			|| typeof(this.dropdownsSelected["QQ_Minute1"]) == "undefined" ) {
			errors["time1"] = Oasys.QuickQuote.strings.PleaseSelect.replace(/@field/g, Oasys.QuickQuote.strings.Time1);
		} else if(date1 != null) {
			date1.setHours($("QQ_Hour1").value);
			date1.setMinutes($("QQ_Minute1").value);
		}
		
		
		if($("QQ_Return").checked) {
			if(!this.isChanged["QQ_Date2"]) {
				errors["date2"] = Oasys.QuickQuote.strings.PleaseSelect.replace(/@field/g, Oasys.QuickQuote.strings.Date2);
				date2 = null;
			} else {
				date2 = this.parseDate("QQ_Date2");
				if(date2 == null) {
					errors["date2"] = Oasys.QuickQuote.strings.DateInvalid.replace(/@field/g, Oasys.QuickQuote.strings.Date2);
				}
			}
			
			if(typeof(this.dropdownsSelected["QQ_Hour2"]) == "undefined" 
				|| typeof(this.dropdownsSelected["QQ_Minute2"]) == "undefined" ) {
				errors["time2"] = Oasys.QuickQuote.strings.PleaseSelect.replace(/@field/g, Oasys.QuickQuote.strings.Time2);
			} else if(date2 != null) {
				date2.setHours($("QQ_Hour2").value);
				date2.setMinutes($("QQ_Minute2").value);
			}
		} else {
			date2 = null;
		}
		
		if(Oasys.hasItems(errors)) {
			Oasys.showErrors(errors);
			return;
		}
		
		document.location.href = Oasys.root + Oasys.language + "/booking-form?" + this.getParams("qs");
	}
	
	this.getParams = function(format) {
		
		keys = ["language", "sDate1", "sDate2", "fromPlaceId", "toPlaceId", "passengers", "isRoundTrip", "swClientId"];
		values = [
			Oasys.language,
			date1.format("Y-m-d H:i"),
			date2 == null ? "" : date2.format("Y-m-d H:i"),
			$("QQ_From").value,
			$("QQ_To").value,
			$("QQ_Passengers").value,
			$("QQ_Return").checked, 
			"1"
		];
		
		if(format == "json") {
			json = {};
			for(var i=0; i < keys.length; i++) {
				json[keys[i]] = values[i];
			}
			return json;
		} else {
			// name value:
			params = [];
			for(var i=0; i < keys.length; i++) {
				params.push(keys[i] + "=" + encodeURIComponent(values[i]));
			}
			params = params.join("&");
			return params;
		}
	}
	
	this.onQuoteFailure = function() {
		$("QQ_Results").hide();
	}

	this.onSuccess = function(jResponse) {
		
		if(jResponse.Options.length > 0) {
			optionsHtml = "<h3 style='text-align:center'>" + Oasys.QuickQuote.strings.AvailableOptions + "</h3>"
				+ "<p>" + Oasys.QuickQuote.strings.WhatsAnOption + "</p>";
			optionsHtml += "<table style='width:312px;margin-left:-5px'>";
			
			for(var i=0; i < jResponse.Options.length; i++) {
				ppp = Math.round(jResponse.Options[i].Price / $("QQ_Passengers").value, 2);
				optionsHtml += "<tr class='option-spacer'><td colspan='99'></td></tr><tr class='qq-option-tr'><td class='qq-option-top-left'></td><td colspan='2'></td><td class='qq-option-top-right'></tr><tr class='qq-option'><td class='qq-option-name'>" + jResponse.Options[i].Name + "</td> <td class='qq-option-info'><img id='QQ_Info_" + i + "' src='" + Oasys.root + "img/question_mark.gif' width='13' height='14'/></td><td class='qq-option-price'>";

				if($("QQ_Return").checked) {
					//show as per way:
					optionsHtml += sprintf(Oasys.QuickQuote.strings.Ppp, ppp/2)
						 + "<br/><span style='font-weight:normal'>" + Oasys.QuickQuote.strings.eachWay + "</span>";
				} else {
					optionsHtml += sprintf(Oasys.QuickQuote.strings.Ppp, ppp);
				}
					
				optionsHtml += "</td><td class='book-button'><div class='but' id='QQ_Book_" + i + "'><div  class='butleft'><div class='butright'><div class='butcenter'>" + Oasys.QuickQuote.strings.BookButton + "</div></div></div></div></td></tr>";
				optionsHtml += "<tr class='qq-option-tr'><td class='qq-option-bottom-left'></td><td colspan='2'></td><td class='qq-option-bottom-right'></tr>";
			}
			
			$("QQ_Results").innerHTML = optionsHtml + "</table>";
			
			window.setTimeout(this.setHandlers.bindAsEventListener(this, jResponse), 0);

		} else {
			$("QQ_Results").innerHTML = "";
		}
		
		var message = jResponse.Message;
		
		if(message == "" && $("QQ_Results").innerHTML == "") {
			message = "We cannot accept resort to resort transfers. Please select an airport for 'from' or 'to'.";
		}
			
		message = message.replace(/##/, "<span class='link qq-send-enquiry'>");
		message = message.replace(/##/, "</span>");

		messageDiv = "<div id='QQ_Message'>" + message + "</div>";
		$("QQ_Results").innerHTML += messageDiv;
		
		$$(".qq-send-enquiry").each(this.initSendEnquiry.bind(this));

		$("QQ_Results").style.display = "block";
		$("VanImage").hide();
	}
	
	this.setHandlers = function(eventId, jResponse) {
		for(var i=0; i < jResponse.Options.length; i++) {
			
			tip = new Ext.ToolTip({
				target: "QQ_Info_" + i,
				showDelay: 0,
				html: jResponse.Options[i].MoreInfo
			});
			
			Ext.QuickTips.init();

			Event.observe($("QQ_Book_" + i), "click", this.bookNow.bindAsEventListener(this, jResponse.Options[i]));
		}
	}
	
	this.initSendEnquiry = function(element) {
		Event.observe(element, "click", this.bookNow.bind(this));
	}
	
	this.dropdownsSelected = { };
	
	this.initialSelected = function(e, initialId) {
		if($(initialId).value != "" && typeof(this.dropdownsSelected[initialId]) == "undefined") {
			$(initialId).remove(0);
			this.dropdownsSelected[initialId] = true;
			if($(initialId).className == "dropdown dropdown-initial") {
				$(initialId).className = "dropdown dropdown-normal";
			}
		}
	}
	
	this.dateFocus = function(e, dateFieldId) {
		if(!this.isChanged[dateFieldId]) {
			$(dateFieldId).value = "";
			$(dateFieldId).className = "calendarInput";
		}
	}

	this.dateBlur = function(e, dateFieldId) {
		if($(dateFieldId).value.trim() == "") {
			$(dateFieldId).value = this.initials[dateFieldId];
			$(dateFieldId).className = "input-initial calendarInput";
			this.isChanged[dateFieldId] = false;
		} else {
			this.onDateSet(dateFieldId);
		}
	}

	this.onDateSet = function(dateId) {
		this.isChanged[dateId] = true;
		$(dateId).className = "calendarInput";
	}
	
	this.bookNow = function(e, option) {
		params = this.getParams("nameValue");
		
		if(typeof(option) != "undefined") {
			params += "&transferTypeId=" + option.OptionId;
		}
		
		document.location = Oasys.root + Oasys.language + "/booking-form?" + params;
	}
}

/**
 * sprintf() for JavaScript v.0.4
 *
 * Copyright (c) 2007 Alexandru Marasteanu <http://alexei.417.ro/>
 * Thanks to David Baird (unit test and patch).
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 */

function str_repeat(i, m) { for (var o = []; m > 0; o[--m] = i); return(o.join('')); }

function sprintf () {
  var i = 0, a, f = arguments[i++], o = [], m, p, c, x;
  while (f) {
    if (m = /^[^\x25]+/.exec(f)) o.push(m[0]);
    else if (m = /^\x25{2}/.exec(f)) o.push('%');
    else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
      if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) throw("Too few arguments.");
      if (/[^s]/.test(m[7]) && (typeof(a) != 'number'))
        throw("Expecting number but found " + typeof(a));
      switch (m[7]) {
        case 'b': a = a.toString(2); break;
        case 'c': a = String.fromCharCode(a); break;
        case 'd': a = parseInt(a); break;
        case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
        case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
        case 'o': a = a.toString(8); break;
        case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
        case 'u': a = Math.abs(a); break;
        case 'x': a = a.toString(16); break;
        case 'X': a = a.toString(16).toUpperCase(); break;
      }
      a = (/[def]/.test(m[7]) && m[2] && a > 0 ? '+' + a : a);
      c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' ';
      x = m[5] - String(a).length;
      p = m[5] ? str_repeat(c, x) : '';
      o.push(m[4] ? a + p : p + a);
    }
    else throw ("Huh ?!");
    f = f.substring(m[0].length);
  }
  return o.join('');
}

