//-----------------------------------------------------------------------------
//	cbFSErr.js
//-----------------------------------------------------------------------------
//
//      FSErr
//
//      JS Class to perform flight search control checks and display the errors.
//
//      Methods
//
//      fsc_check( )
//          performs a flight search criteria k fsv_check( )
//          performs a flight search criteria and vacancy check
//
//      Synopsis
//
//      function init_FSErr( dater1, dater2  ) {
//          var fse = new FSErr( {
//      
//              daters: {
//                  // DateMgr objects provide read and write methods
//                  d1:    dater1,
//                  d2:    dater2,
//                  // fn_chk_both - optional function that returns, whether
//                  // checks should be performed against both dates( default )
//                  // or just against the first date
//                  fn_chk_both: function() { return ibe.LBP.getLocMode() === 'RT'; }
//                  fn_chk_both: function() { return true; }
//              },
//              
//              locs: {     // optional
//                  // DOM ids or nodes of TLC fields, optionally the id/node of
//                  // the field to focus on error
//                  origTLC: { id: "origTLC", focus: "origName" },
//                  destTLC: { id: "destTLC", focus: "destName" },
//                  // fn_locByTLC - function to provide loc object by TLC
//                  fn_locByTLC: function( tlc ) { return ibe.LBP.loc( tlc ); }
//                  fn_locByTLC: function( tlc ) { return Locations[ LocIndex[ tlc ] ]; }
//              },
//              
//              party: {    // optional
//                  adults_id:   "adultId",
//                  children_id: "childId",
//                  infants_id:  "infantId"
//              },
//              
//              vacancies: {// optional
//                  form_name:                 "searchform",
//                  outboundSegmentGroup_name: "outboundFlightSegmentRadioGroupName",
//                  inboundSegmentGroup_name:  "inboundFlightSegmentRadioGroupName"
//              },
//              
//              error: {
//                  div: 'messages',   // div to write errors into
//                  txt: {
//                      NO_DATE_ORIG: 	[ " ... und wann geht's los?" ],
//                      NO_DATE_DEST: 	[ " ... und wann geht's zur�ck?" ],
//                      BAD_DATE_ORIG:	[ "Das Wegfliegen is ja vor heute,", "mach das mal anders!" ],
//                      BAD_DATE_DEST:	[ "Das R\374ckflugdatum ist vorbei.", "Bitte anders machen!" ],
//                      BAD_DATE_SEQ: 	[ "Das R\374ckflugdatum liegt vor dem Hinflugdatum.",
//                                       "Bitte korrigieren Sie Ihre Reisedaten." ],
//                      NO_ORIG:      	[ "Bitte w\344hlen Sie einen Abflugort." ],
//                      NO_DEST:      	[ "Bitte w\344hlen Sie einen Zielort." ],
//                      BAD_PARTY:    	[ "Bitte beachten Sie:",
//                                       "1. nicht mehr als 6 Teilnehmer pro Buchung",
//                                       "2. pro reisendem Erwachsenen nur ein Baby",
//                                       "3. pro reisendem Erwachsene max. 2 Kinder" ],
//                      NO_OUTBOUND_FLIGHT:	[ "Bitte w\344hlen Sie einen Hinflug." ],
//                      NO_INBOUND_FLIGHT:	[ "Bitte w\344hlen Sie einen R\374ckflug." ]
//                  }
//                  //hideIds:   	[ "id1", "id2" ],    // optional
//              }
//          });
//          return fse;
//      }
//
//      ibe.FSE = init_FSErr(dater1, dater2 );
//
//      var errObject = new FSErr( specification_minimal );
//
//      ... and later ...
//
//      ibe.FSE.fsc_check( );
//      ibe.FSE.fsv_check( );
//
//      or as an attribute to the submit button's html tag
//      onSubmit="errObject.fsc_check( )";
//
//-----------------------------------------------------------------------------
//      rg      May 04 2010
//-----------------------------------------------------------------------------

function FSErr(cfg) {
	if (!cfg)
		return null;

	var that = this;

	// --------------------------------------------------------------------------
	// ... DateMgr objects
	// --------------------------------------------------------------------------
	this.dater_t1 = null;
	this.dater_t2 = null;
	this.chk_both = null;

	if (cfg.daters) {
		if (cfg.daters.d1) {
			this.dater_t1 = cfg.daters.d1;
		}
		if (cfg.daters.d2) {
			this.dater_t2 = cfg.daters.d2;
		}
		if (cfg.daters.fn_chk_both) {
			this.chk_both = cfg.daters.fn_chk_both;
		}
	}

	if (this.dater_t1 === null) {
		alert("No Date Manager Object passed in daters:out ");
		return null;
	}

	if (typeof this.chk_both !== 'function') {
		this.chk_both = function() {
			return true;
		};
	}

	// --------------------------------------------------------------------------
	// ... locs
	// --------------------------------------------------------------------------

	this.origNode = null;
	this.origNodeFocus = null;
	this.destNode = null;
	this.destNodeFocus = null;
	this.locByTLC = null;

	// read the configuration
	if (cfg.locs) {
		var l = cfg.locs;
		if (l.origTLC) {
			this.origNode = xGetElementById(l.origTLC.id);
			this.origNodeFocus = l.origTLC.focus ? xGetElementById(l.origTLC.focus)
					: this.origNode;
		}
		if (l.destTLC) {
			this.destNode = xGetElementById(l.destTLC.id);
			this.destNodeFocus = l.destTLC.focus ? xGetElementById(l.destTLC.focus)
					: this.destNode;
		}
		if (l.fn_locByTLC) {
			this.locByTLC = l.fn_locByTLC;
		}
	}

	this.hasLocs = function() {
		return this.origNode !== null && this.destNode !== null
				&& this.locByTLC !== null;
	};

	// --------------------------------------------------------------------------
	// ... Party
	// --------------------------------------------------------------------------

	this.party_ad = null;
	this.party_ch = null;
	this.party_in = null;
	this.party_focus = null;

	if (cfg.party) {
		var p = cfg.party;
		if (p.adults_id) {
			this.party_ad = xGetElementById(p.adults_id);
		}
		if (p.children_id) {
			this.party_ch = xGetElementById(p.children_id);
		}
		if (p.infants_id) {
			this.party_in = xGetElementById(p.infants_id);
		}
	}

	this.hasParty = function hasParty() {
		return this.party_ad !== null && this.party_ch !== null
				&& this.party_in !== null;
	};

	// --------------------------------------------------------------------------
	// ... Vakanzen
	// --------------------------------------------------------------------------

	if (cfg.vacancies) {
		var v = cfg.vacancies;
		if (v.form_name) {
			if (v.outboundSegmentGroup_name) {
				this.vacancies_outbound_group = document.forms[v.form_name].elements[v.outboundSegmentGroup_name];
			}
			if (v.inboundSegmentGroup_name) {
				this.vacancies_inbound_group = document.forms[v.form_name].elements[v.inboundSegmentGroup_name];
			}
		}
	}

	this.hasVacancies = function hasVacancies() {
		return this.vacancies_outbound_group !== undefined
				|| this.vacancies_inbound_group !== undefined;
	};

	this.hasInboundVacancies = function hasInboundVacancies() {
		return this.vacancies_inbound_group !== undefined;
	};

	// --------------------------------------------------------------------------
	// ... Errors
	// --------------------------------------------------------------------------

	this.errDiv = null;
	this.errTxt = FSErr.errors;
	this.idsToHideOnError = [];

	if (cfg.error) {
		if (cfg.error.div) {
			this.errDiv = xGetElementById(cfg.error.div);
		}
		if (cfg.error.txt) {
			for (p in cfg.error.txt) {
				this.errTxt[p] = cfg.error.txt[p];
			}
		}
		if (cfg.error.hideIds) {
			this.idsToHideOnError = cfg.error.hideIds;
		}
	}

	if (!this.errDiv) {
		var divmsg = xGetElementById("messages");
		if (divmsg) {
			this.errDiv = divmsg;
			// alert( "Use existing div messages");
		} else {
			divmsg = document.createElement("div");
			divmsg.id = "messages";
			document.body.appendChild(divmsg);
			// alert( "Created errDiv messages");
		}
	}

	this.hasErrors = function() {
		return this.errList.length > 0;
	};

	// --------------------------------------------------------------------------
	// ... build the errdiv content
	// --------------------------------------------------------------------------

	this.errKeys = {};
	this.errList = []; // gathers FSErr.errors before displaying
	this.errFocus = null; // form field to get focus

	this.hideIds = function() {
		xHideAllOf(this.idsToHideOnError);
	};

	this.build_ul = function() {
		var msgs = that.errList;
		var ul = document.createElement("ul");
		for ( var i = 0; i < msgs.length; i++) {
			var txt_arr = msgs[i];
			for ( var j = 0; j < txt_arr.length; j++) {
				var li = document.createElement("li");
				if (j > 0) {
					xAddClass(li, "sub");
				}
				var txt = document.createTextNode(txt_arr[j]);
				li.appendChild(txt);
				ul.appendChild(li);
			}
		}
		return (ul);
	};

	this.addErrList = function(key, focus, ptxt) {
		var txt = ptxt ? ptxt : this.errTxt[key];
		if (!this.errKeys[key]) {
			this.errKeys[key] = 1;
			this.errList.push(txt);
			if (!that.errFocus) {
				that.errFocus = focus;
			}
		}
	};

	this.cleanErrorDiv = function() {
		while (this.errDiv.hasChildNodes()) {
			this.errDiv.removeChild(this.errDiv.firstChild);
		}
	};

	this.cleanErrors = function() {
		this.errKeys = {};
		this.errList = [];
	};

	this.showErrTxt = function() {
		this.cleanErrorDiv();

		var ul = that.build_ul();
		this.errDiv.appendChild(ul);

		if (this.errFocus) {
			this.errFocus.focus();
			this.errFocus = null;
		}
		this.cleanErrors();
	};

	// --------------------------------------------------------------------------
	// ... check functions
	// --------------------------------------------------------------------------

	this.fsc_check = function() {
		var checkSearchCriteria = true;
		var checkVacancySelection = false;
		return this.fsx_check(checkSearchCriteria, checkVacancySelection);
	};

	this.fsv_check = function() {
		var checkSearchCriteria = false;
		var checkVacancySelection = true;
		return this.fsx_check(checkSearchCriteria, checkVacancySelection);
	};

	this.fsx_check = function(checkSearchCriteria, checkVacancySelection) {

		this.cleanErrorDiv();
		this.cleanErrors;

		var hasReturn = this.chk_both() === true && this.dater_t2 !== null;
		var now = new Date().normalize();

		if (checkSearchCriteria) {
			// --------------------------------------------------------------------------
			// ... Departure Date
			// --------------------------------------------------------------------------

			var t_dep = this.dater_t1.read();
			if (!t_dep) {
				this.addErrList("NO_DATE_ORIG");
			}
			if (t_dep < now) {
				this.addErrList("BAD_DATE_ORIG");
			}

			// --------------------------------------------------------------------------
			// ... Return Date
			// --------------------------------------------------------------------------

			if (hasReturn) {
				var t_arr = this.dater_t2.read();
				if (!t_arr) {
					this.addErrList("NO_DATE_DEST");
				}
				if (t_arr < now) {
					this.addErrList("BAD_DATE_DEST");
				}
				if (t_dep > t_arr) {
					this.addErrList("BAD_DATE_SEQ");
				}
			}

			// --------------------------------------------------------------------------
			// ... Origin Location
			// --------------------------------------------------------------------------

			if (!this.hasErrors() && this.hasLocs()) {
				if (!this.origNode.value) {
					this.addErrList("NO_ORIG", this.origNodeFocus);
				}
				if (!this.destNode.value) {
					this.addErrList("NO_DEST", this.destNodeFocus);
				}

				if (this.origNode.value && this.destNode.value) {
					try {
						var orig_loc = this.locByTLC(this.origNode.value);
						var dest_loc = this.locByTLC(this.destNode.value);
					} catch (err) {
						alert("Problems with loc readers ...getLocByTLC ");
					}

					if (orig_loc && orig_loc.from && dest_loc && dest_loc.from) {
						var loc1_t1 = d8_to_date(orig_loc.from);
						var loc1_t2 = d8_to_date(orig_loc.until);
						if (!(loc1_t1 <= t_dep && t_dep <= loc1_t2)) {
							this.addErrList("LOC_ORIG", this.origNodeFocus,
									[ orig_loc.repr() ]);
						}

						var loc2_t1 = d8_to_date(dest_loc.from);
						var loc2_t2 = d8_to_date(dest_loc.until);
						if (!(loc2_t1 <= t_dep && t_dep <= loc2_t2)) {
							this.addErrList("LOC_DEST", this.destNodeFocus,
									[ dest_loc.repr() ]);
						}

						if (hasReturn) {
							if (!(loc1_t1 <= t_arr && t_arr <= loc1_t2)) {
								this.addErrList("LOC_ORIG", this.origNodeFocus,
										[ orig_loc.repr() ]);
							}
							if (!(loc2_t1 <= t_arr && t_dep <= loc2_t2)) {
								this.addErrList("LOC_DEST", this.destNodeFocus,
										[ dest_loc.repr() ]);
							}
						}
					} else {
						if (!orig_loc || !orig_loc.from) {
							this.addErrList("NO_ORIG", this.origNodeFocus);
						}
						if (!dest_loc || !dest_loc.from) {
							this.addErrList("NO_DEST", this.destNodeFocus);
						}
					}
				}

			}

			// --------------------------------------------------------------------------
			// ... Party
			// --------------------------------------------------------------------------

			if (this.hasParty() === true) {
				this.fsc_check_party();
			}

		}

		// --------------------------------------------------------------------------
		// ... Vakanz
		// --------------------------------------------------------------------------

		if (this.hasVacancies() === true) {
			if (checkVacancySelection) {
				this.fsv_check_outbound();
				if (hasReturn) {
					this.fsv_check_inbound();
				}
			}
		}

		if (this.errList.length > 0) {
			this.showErrTxt();
			return false;
		} else {
			return true;
		}
	};

	this.fsc_check_party = function() {
		if (this.hasParty()) {
			var ad = parseInt(this.party_ad.value, 10) || 0;
			var ch = parseInt(this.party_ch.value, 10) || 0;
			var bb = parseInt(this.party_in.value, 10) || 0;
		}
		if (ad + ch + bb < 1 || ad + ch + bb > 6 || ad < bb || ad * 2 < ch) {
			this.addErrList("BAD_PARTY", this.party_ad);
		}
	};

	this.fsv_check_outbound = function() {
		var indexOutbound = ibeUtil.getCheckedIndex(this.vacancies_outbound_group);
		if (indexOutbound == null) {
			this.addErrList("NO_OUTBOUND_FLIGHT");
		}
	};

	this.fsv_check_inbound = function() {
		var indexInbound = ibeUtil.getCheckedIndex(this.vacancies_inbound_group);
		if (indexInbound == null) {
			this.addErrList("NO_INBOUND_FLIGHT");
		}
	};

	function d8_to_date(d8) {
		var d = new Date().normalize();
		d.setDate(1);
		d.setFullYear(+d8.substr(0, 4));
		d.setMonth(d8.substr(4, 2) - 1);
		d.setDate(+d8.substr(6, 2));
		return d;
	}

	return that;
}

// -----------------------------------------------------------------------------
// ... our data
// -----------------------------------------------------------------------------

FSErr.errors = {
	NO_DATE_ORIG : [ "Bitte geben Sie ein Abflugdatum ein." ],
	NO_DATE_DEST : [ "Bitte geben Sie ein R\374ckflugdatum ein." ],
	BAD_DATE_ORIG : [
			"Das eingegebene Abflugdatum liegt in der Vergangenheit.",
			"Bitte geben Sie ein anderes Abflugdatum ein." ],
	BAD_DATE_DEST : [
			"Das eingegebene R\374ckflugdatum liegt in der Vergangenheit.",
			"Bitte geben Sie ein anderes R\374ckflugdatum ein." ],
	BAD_DATE_SEQ : [ "Das R\374ckflugdatum liegt vor dem Hinflugdatum.",
			"Bitte korrigieren Sie Ihre Reisedaten." ],
	NO_ORIG : [ "Bitte w\344hlen Sie einen Abflugort." ],
	NO_DEST : [ "Bitte w\344hlen Sie einen Zielort." ],
	BAD_PARTY : [
			"Bitte beachten Sie:",
			"Die Summe der Teilnehmer pro Buchung darf 6 Personen nicht "
					+ "\374berschreiten. Wenn Sie mehr als 6 Personen buchen "
					+ "m\366chten, sind mehrere Buchungsvorg\344nge notwendig.",
			"Sie k\366nnen pro reisendem Erwachsenen nur ein Baby mit "
					+ "an Bord nehmen.  Der Hintergrund f\374r diese "
					+ "Einschr\344nkung ist die Anzahl der Sauerstoffmasken "
					+ "pro Sitzreihe. Dies dient der Sicherheit Ihrer Kinder.",
			"Jeder reisende Erwachsene darf max. 2 Kinder (bei "
					+ "Abflug unter 12 Jahren) und ein Baby (bei Abflug unter "
					+ "2 Jahren) zu erm\344\337igten Tarifen mit an Bord nehmen. "
					+ "Weitere Kinder zahlen den Erwachsenen-Tarif." ],
	NO_OUTBOUND_FLIGHT : [ "Bitte w\344hlen Sie einen Hinflug." ],
	NO_INBOUND_FLIGHT  : [ "Bitte w\344hlen Sie einen R\374ckflug." ]
};

// -----------------------------------------------------------------------------
// ... the end of cbFSErr.js
// -----------------------------------------------------------------------------

