function Page() {

	/** @private */ var prevStep = 1;
	/** @private */ var history = new History(historyHnd, 1, this);

	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 {
			var pupSelect = frm.dep_pup_code;
			selectClear(pupSelect);
			pupSelect.options.add(selectOption("", ""));
			var pups = xmlDoc.selectSingleNode("pups/departure").getElementsByTagName("pup");
			for ( var i = 0; i < pups.length; i++ ) {
				pupSelect.options.add(selectOption(pups[i].getAttribute("code"), pups[i].firstChild.nodeValue));
			}

			pupSelect = frm.dst_pup_code;
			selectClear(pupSelect);
			pupSelect.options.add(selectOption("", ""));
			pups = xmlDoc.selectSingleNode("pups/destination").getElementsByTagName("pup");
			for ( i = 0; i < pups.length; i++ ) {
				pupSelect.options.add(selectOption(pups[i].getAttribute("code"), pups[i].firstChild.nodeValue));
			}

			$('trf-results').innerHTML = dom.xmlText(xmlDoc.selectSingleNode("results"));
			this.step(2);
		}
	}

	function bkHnd() {
		if ( !ajax.checkXMLResult( "trf_bk", true ) ) {
			ajax.checkXMLResult("trf_bk");
			return false;
		}
		nav("cart.cfm");
	}

	return {

		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');
			}
			Event.on(frm.rnd, 'click', this.trfToggle);

			// if quick search, init form and run avl
			if ( isset(app.uri.queryKey.quick) ) {
				this.avl(frm);
			}

		},
		trfToggle: function(e) {
			dom[this.checked ? "show" : "hide"]('trf-rnd');
		},

		// Steps
		step: function(num) {
			if ( prevStep == num ) {
				return false;
			}
			var steps = $$('div', 'steps');

			// previous step
			steps[prevStep-1].className = "";
			dom.hide('step-'+prevStep);

			// next step
			history.set(num);
			dom.show('step-'+num);
			steps[num-1].className = "on";
			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 ( 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,tzone_id,adults,children,infants,vehicle');
			ajax.loadXML("?action=avl", postName, "Searching for available transfers.");
			return false;
		},

		// TRANSFER SELECTION
		srvSel: function(trf_code,vch_type,vhc_id,status,units,price) {
			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();
			$('arr-date').innerHTML = frm.trf_date.value;

			if ( frm.rnd.checked ) {
				dom.show('dep-info');
				$('rnd-date').innerHTML = frm.ret_date.value;
			} else {
				dom.hide('dep-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 ( !hasValue(frm.dep_pup_code) ) { return form.error("Please select departure pick up location.", frm.dep_pup_code); }
			if ( !hasValue(frm.dst_pup_code) ) { return form.error("Please select destination location.", frm.dst_pup_code); }

			ajax.queue(bkHnd, "trf_bk");
			ajax.post(frm);
			ajax.loadXML("bookings/add_service.cfm", "trf_bk", "Adding service to shopping cart.");
		}

	};

}