(function(){

	var prevStep = 1,
		history = null;

	function historyHnd(e) {
		var pos = history.get();
		if ( pos === null ) {
			return false;
		} else {
			pos = parseInt(pos, 10);
		}

		if ( pos < history.lastPos ) {
			page.step(pos);
		}
	}

	function selectClear(obj) {
		var options = $$("option", obj);
		for ( var i = options.length; --i >= 0; ) {
			options[i].removeNode();
		}
	}

	function selectOption(value, text, color) {
		var opt = document.createElement("option");

		opt.value = value;
		opt.text = text;
		if ( color ) {
			opt.style.color = color;
		}

		return opt;
	}

	function chkAvl(frm, postName) {
		var xmlDoc = ajax.getXML(postName);

		if ( parseInt(xmlDoc.getAttribute('recordcount'), 10) === 0 ) {
			dom.console(4, "No available transfers have been found with the criteria specified.");
		} else {
			$('trf-results').innerHTML = dom.xmlText(xmlDoc.selectSingleNode("results"));
			//passengers.list(frm,0);
			this.step(2);
		}
	}

	function addHnd() {
		if ( !ajax.checkXMLResult( "trf_bk", true ) ) {
			ajax.checkXMLResult("trf_bk");
			return false;
		}
		nav("cart.cfm");
	}
	
	/*===[ BOOKING ]===*/
	var addFrmId = 'avlFrm',
		authAct = "ajax-auth",
		authId = "auth-modal",
		authFrmId = "auth-form",
		ACSUrl = "",
		Payload = "",
		ajaxId = "ajax-act";
		
	function bkHnd() {
		var result = ajax.getJSON(ajaxId);
		if ( result.flag != 1 ) {
			dom.console(2, result.msg);		
		} else {
			nav('reservation_complete.cfm');
		}
	}
	
	function book(pay) {
		var frm = document.forms[addFrmId];
		ajax.post(frm);
		ajax.queue(bkHnd, ajaxId);
		ajax.loadJSON("trf/book.cfm?p=" + pay, ajaxId, "Booking your stay.");
	}
	
	function mod10(number) {
		var cLen = number.length,
			digits = [],
			n = 0;
	
		digits.length = cLen;
		for( ; n < cLen; n++ ) {
			digits[n] = parseInt(number.charAt(n), 10);
		}
	
		for ( n = cLen - 2; n >= 0; n = n - 2 ) {
			digits[n] *= 2;
			if ( digits[n] >= 10 ) {
				digits[n] -= 9;
			}
		}
		
		return Array.sum(digits) % 10 === 0;
	}
	
	function validateCreditCard(cc, type) {
		var isValid = false, len = 0;
	
		cc = cc.trim().replace(/[\s-]/g, '');
		if ( !(/^[0-9]+$/).test(cc) ) {
			return false;
		}
	
		len = cc.length;
	
		switch ( type ) {
		case "Mastercard":
			isValid = (len == 16) && (/^5[1-5]/).test(cc);
			break;
		case "VISA":
			isValid = (len == 13 || len == 16) && (/^4/).test(cc);
			break;
		case "DINERS":
			isValid = (len == 14) && (/^3/).test(cc);
			break;
		default:
			return false;
		}
	
		return isValid && mod10(cc);
	}
	
	function lookup(frm) {
		var result = ajax.getXML(authAct),
			errorNo = parseInt(dom.xmlText(result.selectSingleNode('/CardinalMPI/ErrorNo')), 10);
			EciFlag = result.selectSingleNode('/CardinalMPI/EciFlag');
	
		EciFlag = EciFlag ? dom.xmlText(EciFlag) : "";
		if ( EciFlag.length ) {
			frm.eci.value = EciFlag;
		} else {
			frm.eci.value = ( frm.card_type.value == 'VISA' ) ? '07' : '01';	// fallback to default values = VISA:07, MasterCard:01
		}
	
		if ( errorNo !== 0 ) {
			if ( dom.confirm('Failed to contact credit card authentication system. Would you like to proceed to booking without authentication?') ) {
				book(true);
			}
		} else {
			var enrolled = dom.xmlText(result.selectSingleNode('/CardinalMPI/Enrolled'));
	
			if ( enrolled == 'Y' ) {
				// launch authentication program
				ACSUrl = dom.xmlText(result.selectSingleNode('/CardinalMPI/ACSUrl'));
				Payload = dom.xmlText(result.selectSingleNode('/CardinalMPI/Payload'));
	
				ajax.queue(function() {
					modal.allowClose(authId, false);
				}, authId);
				ajax.load("pnr/auth.cfc?method=authFrame", authId, "Launching credit card authentication form.");
			} else {
				book(true);	// not enrolled, continue to booking
			}
		}
	}
	
	function authInit() {
		var frm = window.frames[0].document.forms[authFrmId];
		frm.PaReq.value = Payload;
		frm.action = ACSUrl;
		frm.submit();
	}
	
	function authResult(data) {
		if ( data.success ) {
			var frm = document.forms[addFrmId];
			frm.cavv.value = data.cavv;
			if ( data.eci.length ) {
				frm.eci.value = data.eci;
			} else {
				frm.eci.value = ( frm.card_type.value == 'VISA' ) ? '07' : '01';	// fallback to default values = VISA:07, MasterCard:01
			}
			frm.xid.value = data.xid;
			modal.close(authId);
			book(true);
		} else {
			modal.close(authId);
			dom.console(2, data.noauth ? "<strong>Authentication Failed</strong><br/><br/>Your financial institution has indicated that it could not successfully authenticate this transaction. To protect against unauthorized use, this card cannot be used to complete your purchase." : "<strong>Authentication Failed</strong><br/><br/>An error occured while trying to authenticate the transaction. Please try again or contact technical support.");
		}
	}

	page = {

		bind: {
			avlFrm: {
				trf_date: {bind:"ret_date" },
				ret_date: {bind:"trf_date" }
			}
		},

		interceptEnter: function(frm) {
			switch(history.lastPos) {
			case 1:
				this.avl(frm);
				break;
			case 3:
				this.addService(frm);	
				break;
			}
			return false;
		},

		init: function() {
			var frm = document.forms.avlFrm;
			/*if ( frm.rnd.checked ) {
				dom.show('trf-rnd');
			}*/
			if ( frm.trf_type[2].checked ) {
				dom.show('trf-rnd');
			}
			if ( frm.trf_type[1].checked ) {
				$('oneway_title').innerHTML = lang.common.departure;
			}
			
			//Event.on(frm.rnd, 'click', this.trfToggle);
			Event.on(frm.trf_type, 'click', this.trfTypeChange);
			
			Event.on([frm.fzone_id,frm.tzone_id], 'change', this.getPups);
			if( hasValue(frm.fzone_id) ) { this.getPups.call(frm.fzone_id); }
			if( hasValue(frm.tzone_id) ) { this.getPups.call(frm.tzone_id); }
			
			Event.on([frm.arr_trans_type,frm.dep_trans_type], 'change', function(e) {
				var label = this.name == 'arr_trans_type' ? 'arr_trans_code_label' : 'dep_trans_code_label';
				switch (this.value) {
					case 'FLT' :
						$(label).innerHTML = 'Flight number';
						break;
					case 'BOAT' :
						$(label).innerHTML = 'Ferry Boat Name';
						break;
					default:
						$(label).innerHTML = 'Service Code/Name';
				}
			});
			
			history = new History(historyHnd, 1, this);

			if ( isset(app.uri.queryKey.quick) ) {
				this.avl(frm);
			}
		},

		trfToggle: function(e) {
			dom[this.checked ? "show" : "hide"]('trf-rnd');
		},
		
		trfTypeChange: function(e) {
			dom[this.value == 2 ? "show" : "hide"]('trf-rnd');
			this.value == 2 ? this.form.rnd.checked=1 : this.form.rnd.checked=0;
			$('oneway_title').innerHTML = this.value == 1 ? lang.common.departure : lang.common.arrival;
		},
		
		getPups: function(e) {
			$(this.name == 'fzone_id' ? 'fpup_loading' : 'tpup_loading').style.display = 'inline';
			ajax.queue(page.getPupsHnd.callback(this.name), this.name + '_get');
			ajax.loadJSON("?action=getPups&zone_id="+this.value + "&fromto="+this.name, this.name + '_get');
		},
		
		getPupsHnd: function(fromTo) {
			var response = ajax.getJSON(fromTo + '_get');
			var terminals = document.createElement("optgroup");
			terminals.label = 'Terminals';
			var rest = document.createElement("optgroup");
			rest.label = 'Pickups';
			var opt = "";
			var opt_txt = "";
			var sel = fromTo == 'fzone_id' ? $('fpup_code') : $('tpup_code');
			sel.disabled = true;
			sel.innerHTML = "";
			
			for(i=0; i != response.options.length; i++) {
				opt = document.createElement("option");
				opt_txt = document.createTextNode(response.options[i].pup_desc);
				opt.appendChild(opt_txt);
				opt.setAttribute("value", response.options[i].pup_code);
				if(response.options[i].selected) { opt.setAttribute("selected", true); }
				//if(!response.options[i].terminal) { opt.style.color = '#444'; }
				//sel.appendChild(opt);
				if(response.options[i].terminal) { terminals.appendChild(opt); } else { rest.appendChild(opt); }
			}
			if(terminals.children.length) { sel.appendChild(terminals) };
			if(rest.children.length) { sel.appendChild(rest) };
			/*if( (terminals.children.length && !rest.children.length) ||
				(!terminals.children.length && rest.children.length) ) { 
				terminals.label = ''; 
				rest.label = '';
			}*/
			
			dom.hide( fromTo == 'fzone_id' ? 'fpup_loading' : 'tpup_loading' );
			sel.disabled = false;
		},

		step: function(num) {
			if ( prevStep == num ) {
				return false;
			}

			dom.hide('step-'+prevStep);

			// next step
			history.set(num);
			dom.show('step-'+num);
			prevStep = num;
		},

		// AVAILABILITY
		avl: function(frm) {
			if ( !hasValue(frm.trf_date) ) { return form.error("Please type the arrival date.", frm.trf_date); }
			if ( app.today.dayDiff(getValue(frm.trf_date).toDate()) < 1 ) { return form.error("Please select a date after " + app.today.format()); }
			if ( frm.rnd.checked ) {
				if ( !hasValue(frm.ret_date) ) { return form.error("Please type the departure date.", frm.ret_date); }
			}
			if ( !hasValue(frm.fzone_id) ) { return form.error("Please select a departure zone.", frm.fzone_id); }
			if ( !hasValue(frm.tzone_id) ) { return form.error("Please select a destination zone.", frm.tzone_id); }
			if ( !hasValue(frm.fpup_code) ) { return form.error("Please select departure pick up location.", frm.fpup_code); }
			if ( !hasValue(frm.tpup_code) ) { return form.error("Please select destination location.", frm.tpup_code); }
			if ( getValue(frm.fzone_id) == getValue(frm.tzone_id) ) { return form.error("Destination zone cannot be the same as departure zone."); }

			if ( parseInt(frm.adults.value, 10) + parseInt(frm.children.value, 10) + parseInt(frm.infants.value, 10) === 0 ) {
				return form.error("At least one passenger must be specified.", frm.adults);
			}

			var postName = "trf_avl";
			ajax.queue(chkAvl, postName, this, [frm,postName]);
			//ajax.post(frm, 'trf_date,rnd,ret_date,fzone_id,fpup_code,tzone_id,tpup_code,adults,children,infants,vehicle');
			ajax.post(frm);
			ajax.loadXML("?action=avl", postName, "Searching for available transfers.");
			return false;
		},

		// TRANSFER SELECTION
		srvSel: function(trf_code,vch_type,vhc_id,status,units,price, downpayment, btn) {
			var frm = document.forms.avlFrm;
			frm.srv_code.value = trf_code;
			frm.vhc_id.value = vhc_id;
			frm.vch_type.value = vch_type == "0" ? 0 : 1;
			frm.status.value = ( status == 'AV' ) ? 'AVL' : status;
			frm.units.value = units;
			frm.price.value = price.parseCurrency();
			//frm.downpayment.value = parseFloat(price) * parseFloat(downpayment) / 100;
			frm.downpayment.value = parseFloat(downpayment);
			
			frm.time.value = frm.time_hour.value + ':' + frm.time_min.value;
			frm.time_rnd.value = frm.time_hour_rnd.value + ':' + frm.time_min_rnd.value;
			
			//$('arr-date').innerHTML = frm.trf_date.value;
			//$('dep_pup').innerHTML = frm.fpup_code[frm.fpup_code.selectedIndex].innerHTML;
			//$('dst_pup').innerHTML = frm.tpup_code[frm.tpup_code.selectedIndex].innerHTML;

			/*if ( frm.rnd.checked ) {
				dom.show('dep-info');
				$('rnd-date').innerHTML = frm.ret_date.value;
			} else {
				dom.hide('dep-info');
			}*/
			
			//show status msg
			if(frm.status.value == 'AVL') {
				$('ORmsg').innerHTML = lang.common.status + ': <span style="color:green">'+lang.common.available+'</span><br />';
				$('bkServiceBtn').style.display = '';
			} else if(frm.status.value == 'OR') {
				$('ORmsg').innerHTML = lang.common.status + ': <span style="color:orange">'+lang.common.or+'</span><br />';
				$('bkServiceBtn').style.display = 'none';
			} else if(frm.status.value == 'NA') {
				$('ORmsg').innerHTML = lang.common.status + ': <span style="color:red">'+lang.common.not_available+'</span><br />';
				$('bkServiceBtn').style.display = 'none';
			}
			
			$('sel_trf').innerHTML = btn.parentNode.parentNode.innerHTML;
			frm.rnd.checked ? dom.show('departing_info') : dom.hide('departing_info');
			
			this.step(3);
		},

		// BOOKING
		addService: function(frm) {
			// validate form
			if ( !hasValue(frm.vhc_id) ) { return form.error("Please select a transfer to continue."); }
			if ( !hasValue(frm.time) ) { return form.error("Please input departure time to continue.", frm.time); }
			if ( frm.rnd.checked ) {
				if ( !hasValue(frm.time_rnd) ) { return form.error("Please input departure time of your return.", frm.time_rnd); }
			}
			//if ( !frm.accept.checked ) { return form.error("Please read and accept our Booking Conditions &amp; Privacy Policy to continue.", frm.accept); }
			
			ajax.queue(addHnd, "trf_bk");
			ajax.post(frm);
			ajax.loadXML("bookings/add_service.cfm", "trf_bk", "Adding service to shopping cart.");
		},
		
		showBook: function(frm) {
			frm.action='trf_book.cfm'.urlFormat(true);
			frm.submit();
		},
		
		book: function(frm, pay) {
			if ( !hasValue(frm.first_name) ) { return form.error("Please type your first name.", frm.first_name); }
			if ( !hasValue(frm.last_name) ) { return form.error("Please type your last name.", frm.last_name); }
			if ( !hasValue(frm.email) || !frm.email.value.isEmail() ) { return form.error("Please type a valid email address.", frm.email); }
			if ( frm.email.value != frm.email_again.value ) { return form.error("email addresses don't match.", frm.email_again); }
			if ( !hasValue(frm.cnt_code) ) { return form.error("Please select a country.", frm.cnt_code); }			
			if ( !hasValue(frm.tel) ) { return form.error("Please type your telephone number.", frm.tel); }
			if ( !hasValue(frm.location) ) { return form.error("Please type your location.", frm.location); }
			if ( !hasValue(frm.address) ) { return form.error("Please type your mailing address.", frm.address); }
			if ( !hasValue(frm.zip) ) { return form.error("Please type your postal code.", frm.zip); }
			
			if(!frm.accept.checked) { return form.error(lang.accept_err, frm.accept); }
			
			if(pay) {
				// validate credit card
				var cc_year = parseInt(getValue(frm.card_year), 10),
					cc_month = parseInt(getValue(frm.card_month), 10);
		
				if ( frm.card_number.value.length < 13 || !validateInt(frm.card_number.value) ) { return form.error("Please input credit's card number", frm.card_number); }
				if ( !validateCreditCard(frm.card_number.value, frm.card_type.value) ) {
					return form.error("Please input a valid credit card number", frm.card_number);
				}
				if ( !hasValue(frm.card_name) ) { return form.error("Please input the full name as it appears on the credit card.", frm.card_name); }
				if ( cc_year == app.today.getFullYear() && cc_month < app.today.getMonth()+1 ) {
					return form.error("Please input a valid expiration date", frm.card_year);
				}
				if ( frm.card_cvv2.value.length < 3 || !validateInt(frm.card_cvv2.value) ) { return form.error("Please input credit's card CVV2 number", frm.card_cvv2); }
		
				frm.cavv.value = frm.eci.value = frm.xid.value = "";
				
				if ( dom.confirm(lang.common.book_confirm) ) {
					//no 3d secure
					book(true);
					/*ajax.post(frm, "cavv,eci,xid,card_number,card_name,card_cvv2,card_type,card_month,card_year");
					ajax.queue(lookup.callback(frm), authAct);
					ajax.loadXML("pnr/auth.cfc?method=lookup", authAct, "Looking up eligibility for credit card payer authentication programs.");*/
				}
			} else {
				//Enable online OR booking?
				//book(false);	// no payment, continue to booking
				frm.action = "email_request.cfm";
				frm.submit();
			}
			
			return false;
		}

	};

})();