var JSON;
if (!JSON) {
    JSON = {};
}

(function () {
    'use strict';

    function f(n) {
        // Format integers to have at least two digits.
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return isFinite(this.valueOf())
                ? this.getUTCFullYear() + '-' +
                    f(this.getUTCMonth() + 1) + '-' +
                    f(this.getUTCDate()) + 'T' +
                    f(this.getUTCHours()) + ':' +
                    f(this.getUTCMinutes()) + ':' +
                    f(this.getUTCSeconds()) + 'Z'
                : null;
        };

        String.prototype.toJSON =
            Number.prototype.toJSON =
            Boolean.prototype.toJSON = function (key) {
                return this.valueOf();
            };
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"': '\\"',
            '\\': '\\\\'
        },
        rep;


    function quote(string) {

        // If the string contains no control characters, no quote characters, and no
        // backslash characters, then we can safely slap some quotes around it.
        // Otherwise we must also replace the offending characters with safe escape
        // sequences.

        escapable.lastIndex = 0;
        return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
            var c = meta[a];
            return typeof c === 'string'
                ? c
                : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
        }) + '"' : '"' + string + '"';
    }


    function str(key, holder) {

        // Produce a string from holder[key].

        var i,          // The loop counter.
            k,          // The member key.
            v,          // The member value.
            length,
            mind = gap,
            partial,
            value = holder[key];

        // If the value has a toJSON method, call it to obtain a replacement value.

        if (value && typeof value === 'object' &&
                typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }

        // If we were called with a replacer function, then call the replacer to
        // obtain a replacement value.

        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }

        // What happens next depends on the value's type.

        switch (typeof value) {
            case 'string':
                return quote(value);

            case 'number':

                // JSON numbers must be finite. Encode non-finite numbers as null.

                return isFinite(value) ? String(value) : 'null';

            case 'boolean':
            case 'null':

                // If the value is a boolean or null, convert it to a string. Note:
                // typeof null does not produce 'null'. The case is included here in
                // the remote chance that this gets fixed someday.

                return String(value);

                // If the type is 'object', we might be dealing with an object or an array or
                // null.

            case 'object':

                // Due to a specification blunder in ECMAScript, typeof null is 'object',
                // so watch out for that case.

                if (!value) {
                    return 'null';
                }

                // Make an array to hold the partial results of stringifying this object value.

                gap += indent;
                partial = [];

                // Is the value an array?

                if (Object.prototype.toString.apply(value) === '[object Array]') {

                    // The value is an array. Stringify every element. Use null as a placeholder
                    // for non-JSON values.

                    length = value.length;
                    for (i = 0; i < length; i += 1) {
                        partial[i] = str(i, value) || 'null';
                    }

                    // Join all of the elements together, separated with commas, and wrap them in
                    // brackets.

                    v = partial.length === 0
                    ? '[]'
                    : gap
                    ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
                    : '[' + partial.join(',') + ']';
                    gap = mind;
                    return v;
                }

                // If the replacer is an array, use it to select the members to be stringified.

                if (rep && typeof rep === 'object') {
                    length = rep.length;
                    for (i = 0; i < length; i += 1) {
                        if (typeof rep[i] === 'string') {
                            k = rep[i];
                            v = str(k, value);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                } else {

                    // Otherwise, iterate through all of the keys in the object.

                    for (k in value) {
                        if (Object.prototype.hasOwnProperty.call(value, k)) {
                            v = str(k, value);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                }

                // Join all of the member texts together, separated with commas,
                // and wrap them in braces.

                v = partial.length === 0
                ? '{}'
                : gap
                ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
                : '{' + partial.join(',') + '}';
                gap = mind;
                return v;
        }
    }

    // If the JSON object does not yet have a stringify method, give it one.

    if (typeof JSON.stringify !== 'function') {
        JSON.stringify = function (value, replacer, space) {

            // The stringify method takes a value and an optional replacer, and an optional
            // space parameter, and returns a JSON text. The replacer can be a function
            // that can replace values, or an array of strings that will select the keys.
            // A default replacer method can be provided. Use of the space parameter can
            // produce text that is more easily readable.

            var i;
            gap = '';
            indent = '';

            // If the space parameter is a number, make an indent string containing that
            // many spaces.

            if (typeof space === 'number') {
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }

                // If the space parameter is a string, it will be used as the indent string.

            } else if (typeof space === 'string') {
                indent = space;
            }

            // If there is a replacer, it must be a function or an array.
            // Otherwise, throw an error.

            rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
                    (typeof replacer !== 'object' ||
                    typeof replacer.length !== 'number')) {
                throw new Error('JSON.stringify');
            }

            // Make a fake root object containing our value under the key of ''.
            // Return the result of stringifying the value.

            return str('', { '': value });
        };
    }


    // If the JSON object does not yet have a parse method, give it one.

    if (typeof JSON.parse !== 'function') {
        JSON.parse = function (text, reviver) {

            // The parse method takes a text and an optional reviver function, and returns
            // a JavaScript value if the text is a valid JSON text.

            var j;

            function walk(holder, key) {

                // The walk method is used to recursively walk the resulting structure so
                // that modifications can be made.

                var k, v, value = holder[key];
                if (value && typeof value === 'object') {
                    for (k in value) {
                        if (Object.prototype.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }


            // Parsing happens in four stages. In the first stage, we replace certain
            // Unicode characters with escape sequences. JavaScript handles many characters
            // incorrectly, either silently deleting them, or treating them as line endings.

            text = String(text);
            cx.lastIndex = 0;
            if (cx.test(text)) {
                text = text.replace(cx, function (a) {
                    return '\\u' +
                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }

            // In the second stage, we run the text against regular expressions that look
            // for non-JSON patterns. We are especially concerned with '()' and 'new'
            // because they can cause invocation, and '=' because it can cause mutation.
            // But just to be safe, we want to reject all unexpected forms.

            // We split the second stage into 4 regexp operations in order to work around
            // crippling inefficiencies in IE's and Safari's regexp engines. First we
            // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
            // replace all simple value tokens with ']' characters. Third, we delete all
            // open brackets that follow a colon or comma or that begin the text. Finally,
            // we look to see that the remaining characters are only whitespace or ']' or
            // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

            if (/^[\],:{}\s]*$/
                    .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
                        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
                        .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

                // In the third stage we use the eval function to compile the text into a
                // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
                // in JavaScript: it can begin a block or an object literal. We wrap the text
                // in parens to eliminate the ambiguity.

                j = eval('(' + text + ')');

                // In the optional fourth stage, we recursively walk the new structure, passing
                // each name/value pair to a reviver function for possible transformation.

                return typeof reviver === 'function'
                    ? walk({ '': j }, '')
                    : j;
            }

            // If the text is not JSON parseable, then a SyntaxError is thrown.

            throw new SyntaxError('JSON.parse');
        };
    }
} ());
if (!window.console) console = { log: function () { } };

(function () {
	/** @id _FC */
	var _FC = (function () {
		var initializing = 0,
			fnTest = /xyz/.test(function () { xyz; }) ? /\b_super\b/ : /.*/;
		// create private static attributes and methods here
		var _isIE = /*@cc_on!@*/0;
		var _xhr = window.XMLHttpRequest ? 1 : 0;

		var _isSelectorAble = (document.querySelectorAll) ? 1 : 0;
		var _isGetClassAble = (document.getElementsByClassName) ? 1 : 0;

		var _isLteIE6 = /*@cc_on@*//*@if (@_jscript_version <= 5.6)1; /*@end@*/0;
		var _isIE6 = /*@cc_on@*//*@if (@_jscript_version == 5.6)1; /*@end@*/0;
		var _isLteIE7 = /*@cc_on@*//*@if (@_jscript_version <= 5.7)1; /*@end@*/0;
		var _isIE7 = (_isLteIE7 && window.XMLHttpRequest) ? 1 : 0;

		_isIE6 = (_isLteIE7 && !window.XMLHttpRequest) ? 1 : _isIE6;
		_isLteIE6 = (_isLteIE7 && !window.XMLHttpRequest) ? 1 : _isLteIE6;

		//safari 2 detection
		var _detect = navigator.userAgent.toLowerCase();
		var _safari_2_x = (_detect.indexOf("safari") >= 0 && _detect.indexOf("412") >= 0) ? 1 : 0;

		var _appName = navigator.appName.toLowerCase();

		var _isIFrame = (window.location != window.parent.location) ? 1 : 0;

		var _name = 'FC JavaScript Library.\n\nv. 0.3.7\n\n\u00A9 2010 Fortune Cookie UK';

		if (_isLteIE7) {// ie7 and below flicker fix
			try { document.execCommand('BackgroundImageCache', false, true); } catch (e) { }
		}

		if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) {
			var viewportmeta = document.querySelector('meta[name="viewport"]');
			if (viewportmeta) {
				viewportmeta.content = 'width=device-width, user-scalable=no';
				document.body.addEventListener('gesturestart', function (e) {
					//viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6';
					//Adding fix for mobile input zoom bug
					e.preventDefault();
				}, false);
			}
		}

		return function () {
			// create private privileged properties and methods with 'this.'
			// create private private properties and methods with 'var' and 'function'
			/** @id hasQuerySelector */
			this.hasHasQuerySelector = (function () { return _isSelectorAble; })();
			/** @id hasIE */
			this.hasIE = (function () { return _isIE; })();
			/** @id hasLteIE6 */
			this.hasLteIE6 = (function () { return _isLteIE6 })();
			/** @id hasIE6 */
			this.hasIE6 = (function () { return _isIE6 })();
			/** @id hasLteIE7 */
			this.hasLteIE7 = (function () { return _isLteIE7 })();
			/** @id hasIE7 */
			this.hasIE7 = (function () { return _isIE7 })();
			/** @id hasSafari2 */
			this.hasSafari2 = (function () { return _safari_2_x })();
			/** @id FC */
			this.FC = (function () { return _name })();
			/** @id isInIFrame */
			this.isInIFrame = (function () { return _isIFrame })();

			/** @id getIdOrClass */
			this.getIdOrClass = function (el, win) {
				var win = win || window;
				var __id, __cls, __char = el.charAt(0), doc = win.document;

				if (__char === "#") __id = el
				else if (__char === ".") __cls = el
				else return false;

				if (_isSelectorAble) return (__id) ? doc.querySelector(__id) : doc.querySelectorAll(__cls)
				else if (__cls)
					if (_isGetClassAble) return doc.getElementsByClassName(__cls) // remove dot
					else return this.getElementsByClassName(__cls) // remove dot
				else return doc.getElementById(__id) // remove hash
			}

			/** @id isInKnownIFrame */
			this.isInKnownIFrame = function (el) {
				if (_isIFrame) return this.getIdOrClass(el, window.parent)
				else return false
			}

			/** @id Class */
			// Nicked from John Resig and then refactored to namespace it
			this.Class = function () { };
			this.Class.subclass = function (prop) {
				var _super = this.prototype;
				initializing = 1;
				var prototype = new this();
				initializing = 0;

				for (var name in prop) {
					prototype[name] = typeof prop[name] == "function" &&
					typeof _super[name] == "function" &&
					fnTest.test(prop[name]) ? (function (name, fn) {
						return function () {
							var tmp = this._super;
							this._super = _super[name];
							var ret = fn.apply(this, arguments);
							this._super = tmp;

							return ret;
						};
					})(name, prop[name]) : prop[name];
				}

				function Class() {
					if (!initializing && this.init)
						this.init.apply(this, arguments);
				}

				Class.prototype = prototype;
				Class.constructor = Class;
				Class.subclass = arguments.callee;

				return Class;
			};

			/** @id setCookie */
			this.setCookie = function (name, value, expires, path, domain, secure) {
				var today = new Date();
				today.setTime(today.getTime());

				/*
				if the expires variable is set, make the correct expires time, the current script below will set
				it for x number of days, to make it for hours, delete * 24, for minutes, delete * 60 * 24
				*/
				if (expires) {
					expires = expires * 1000 * 60 * 60 * 24;
				}
				var expires_date = new Date(today.getTime() + (expires));

				document.cookie = name + "=" + escape(value) +
				((expires) ? ";expires=" + expires_date.toGMTString() : "") +
				((path) ? ";path=" + path : "") +
				((domain) ? ";domain=" + domain : "") +
				((secure) ? ";secure" : "");
			};

			/** @id getCookie */
			this.getCookie = function (name) {
				if (document.cookie.length > 0) {
					c_start = document.cookie.indexOf(name + "=");
					if (c_start != -1) {
						c_start = c_start + name.length + 1;
						c_end = document.cookie.indexOf(";", c_start);
						if (c_end == -1) {
							c_end = document.cookie.length;
						}
						return unescape(document.cookie.substring(c_start, c_end));
					}
				}
				return "";
			};


			/** @id showChildren */
			this.showChildren = function (el) {
				var __str = "";

				for (var __j in el) {
					if (el.type || el.hasOwnProperty(__j)) {
						__str += __j + " = " + el[__j] + ", "
					}
				}

				alert(__str);
			};

			/** @id commonEventObject */
			this.commonEventObject = function (e) {
				var __t;

				if (e.target) {
					__t = e.target;
				} else if (e.srcElement) {
					__t = e.srcElement;
				}

				if (__t.nodeType == 3) {// defeat Safari bug
					__t = __t.parentNode;
				}

				return __t;
			};

			/** @id stopReturn */
			this.stopReturn = function (e) {
				if (!e) {
					e = window.event;
				}
				(e.stopPropagation) ? e.stopPropagation() : e.cancelBubble = true;
				(e.preventDefault) ? e.preventDefault() : e.returnValue = false;
				return false;
			};

			/** @id clearTextNodes */
			this.clearTextNodes = function (n) {
				var __j = Number(n.length);
				while (__j--) if (n[__j].nodeType == 3) {
					n.removeChild(n[__j]);
				}
				return n;
			};

			/** @id clearNodes */
			this.clearNodes = function (n) {
				while (n.firstChild) {
					n.removeChild(n.firstChild)
				}
				return n;
			};

			/** @id toDecimalString */
			this.toDecimalString = function (val) {
				__val = Number(val);
				return ((__val * 100) % 100) ? __val.toString() : __val + ".00";
			};

			/** @id getStyle */
			this.getStyle = function (el, styleProp) {
				var x = document.getElementById(el), y;
				if (x.currentStyle)
					y = x.currentStyle[styleProp];
				else if (window.getComputedStyle)
					y = document.defaultView.getComputedStyle(x, null).getPropertyValue(styleProp);
				return y;
			};

			/** @id getElementsByClassName */
			this.getElementsByClassName = function (cl) {
				var retnode = [], myclass = new RegExp('\\b' + cl + '\\b'), elem = document.getElementsByTagName('*');
				var i = elem.length;
				while (i--) {
					if (myclass.test(elem[i].className)) retnode.push(elem[i]);
				}
				return (!retnode.length) ? null : retnode;
			};

			/** @id addEvent */
			this.addEvent = function (obj, evt, fn) {
				if (obj.addEventListener)
					obj.addEventListener(evt, fn, false);
				else
					if (obj.attachEvent)
						obj.attachEvent('on' + evt, fn);

				if (obj.getAttribute) {
					if (obj.getAttribute('href')) {
						obj.onclick = function () {
							return false
						}
					} else if (obj.getAttribute('href') && !obj.getAttribute('onclick')) {
						var func = obj.onclick;
						obj.onclick = function () {
							func();
							return false;
						}
					}
				}
			};

			/** @id removeEvent */
			this.removeEvent = function (obj, type, fn) {
				if (obj.removeEventListener)
					obj.removeEventListener(type, fn, false);
				else if (obj.detachEvent)
					obj.detachEvent('on' + type, fn);
			};

			/** @id testForEventType */
			this.testForEventType = function (e, el) {
				return 'on' + e in el || (function () { // firefox workaround
					var __el = Object(el), __bool;
					__el.setAttribute(e, 'return;');
					__bool = typeof __el['on' + e] == 'function';
					__el = undefined;
					return __bool;
				})();
			}

			/** @id toggle */
			this.toggle = function (el) {
				el.style.display = (el.style.display == 'none') ? 'block' : 'none';
			};

			/** @id setHTML5 */
			this.setHTML5 = function () {
				if (!/*@cc_on!@*/0) return;
				var e = "abbr,article,aside,audio,bb,canvas,datagrid,datalist,details,dialog,eventsource,figure,footer,header,hgroup,mark,menu,meter,nav,output,progress,section,time,video".split(','),
				i = e.length;
				while (i--) {
					document.createElement(e[i])
				}
			};

			/** @id setJS */
			this.setJS = function () {
				document.body.className = (document.body.className) ? document.body.className + " js" : "js";
			};

			/** @id setJQ */
			this.setJQ = function () {
				switch (_appName) {
					case 'playstation':
						break;
					default:
						document.body.className = (document.body.className) ? document.body.className + " jq" : "jq";
				}
			};

			/** @id checkChange */
			this.checkChange = function (str, o) { // receives a unique identifier (ie: an id) and an Object literal
				(o[str]) ? delete o[str] : o[str] = true;

				for (var __j in o) if (o.hasOwnProperty(__j)) { return true }

				return false;
			};

			/** @id beforeUnload */
			this.beforeUnload = function (str) {
				window.onbeforeunload = (str) ? function (e) {
					if (e) {
						e.returnValue = str; // required for FF
					}
					return str;
				} : null;
			};

			/** @id resetForm */
			this.resetForm = function (form) {
				var __input = document.createElement('input');
				__input.setAttribute('type', 'reset');
				form.appendChild(__input);
				__input.click();
				form.removeChild(form.childNodes[form.childNodes.length]);
			};

			/** @id pngFix */
			this.pngFix = function (clear, parent) {
				if (this.hasLteIE6) {
					/*@cc_on
					if (this._clear = clear || this._clear) { parent = parent || document.body; var els = parent.getElementsByTagName("*"); var ip = /\.png/i; var ip8 = /-8bit/i; var i = els.length; while (i--) { var el = els[i]; var es = el.style; if (el.src && el.src.match(ip) && !es.filter) { if (!el.src.match(ip8)) { es.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + el.src + "',sizingMethod='crop')"; el.src = clear } } else { var elb = el.currentStyle.backgroundImage; if (elb.match(ip)) { if (!elb.match(ip8)) { var path = elb.split('"'); var rep = (el.currentStyle.backgroundRepeat == "no-repeat") ? "crop" : "scale"; es.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + path[1] + "',sizingMethod='" + rep + "')"; es.height = el.clientHeight + "px"; es.backgroundImage = "none"; } } } } }
					@*/
				}
			};

		};
	})();

	window.FC = new _FC();

	// create public privileged static properties and methods with
	/*
	_FC.functionName = function (val) {
	}
	*/

	//	_FC.vars = {}; // priviliged runtime properties with access to FC private content go here
	//	_FC.functions = {}; // priviliged runtime methods with access to FC private content go here

	// create public non-privileged properties (like jQuery) and methods with

	/*
	FC.prototype = {
	functionName : function () {}
	}
	*/
})();


FC.vars = {
    selectors: {
        // alert box
        ALERT_BTN: '#openAlert',
        // TABS:
        EXPANDER: 'div.expander',
        TABS_CONTAINER: 'div.tab-container',            // Container ID for the whole tabs section
        PRIMARY_NAV: 'nav.primary',
        PASSWORD_STRENGTH_INPUT: 'input.passwordStrength',
        CONFIRM_PASSWORD_INPUT: 'input.pwConfirm',
        CONFIRM_DELETE: 'input.delete, span.delete-flight input',
        HOMEPAGE_RESERVATIONS_TABS: 'ul.reservation-tabs',
        SHOW_MORE_RESERVATIONS_BUTTON: 'a.show-more-reservations',
        RESERVATION_STEP1: 'div.reservation-step1',
        RESERVATION_STEP2: 'div.reservation-step2',
        CATERING_CATEGORIES: 'ul.catering-categories',
        GROUND_TRANSPORT: 'div.ground-transport',
        REQUEST_RESERVATION: 'div.request-reservation',
        REVEAL: 'div.reveal',
        REVEAL_TRIGGER: '.reveal-trigger',
        REVEAL_PANEL: 'div.reveal-panel',
        REMOVE_PASSENGER_INPUT: 'a.remove-passenger',
        CAROUSEL: 'div.carousel',
        TOOLTIP: 'div.tooltip',
        ACCOUNTS: '#userbar ul.accounts a.trigger',
        BLUESKIES: '[data-blueskies="eligible"]',
        HELP: '#userbar ul li.help a.trigger',
        FLIGHT_DETAILS: 'a.details-link',
        FANCY_SELECT: 'select.fancy-select',
        FANCY_SELECT_GENERAL: '.fancy-select-general',
        FANCY_CHECKBOXES: '.fancy-checkbox',
        LOGIN_USER_NAME: 'div.username input[type="text"]',
        FLIGHT_ACC: 'ul.flight-acc',
        FLIGHT_ACC_HEADER: 'ul.flight-acc .flight-acc-head',
        FLIGHT_ACC_CONTENT_WRAPPER: 'ul.flight-acc .flight-acc-content-wrapper',
        FLIGHT_ACC_CONTENT_INNER: 'ul.flight-acc .flight-acc-content-inner',
        REQUEST_FLIGHT_HEADER: '.request li .flight-head',
	    REVIEW_MODAL: '.review-modal',
        FORM_CHKBOXES: '.basic-details div.checkbox label',
        EXTERNAL_LINK: 'a.external',
        CLOUD_BG: 'div.cloud',
        FURTHER_INSTRUCTIONS: 'div.further-instructions',
        //ACCOUNT > PEOPLE
        PEOPLE: '.profile .people',
        INVOICE: '.invoices-filter',
        //PROFILE > PROFILE NAVIGATION
        PROFILE_NAV: '.profile-nav',
        //PROFILE > EDITING FIELDS
        PROFILE: '.profile',
        //PROFILE SIDE VAN
        SIDE_NAVIGATION: '.sideNav',
        //HOME NAV
        HOME_NAVIGATION: '.homeFlights',
        //EVERY LINK
        EVERY_LINK: 'a',
        //FOOTER
        FOOTER: 'footer',
        //LOGIN PANEL
        LOGIN_PANEL: 'div.login',
        SIMULATE_PLACEHOLDER_TEXT_INPUTS: 'input.simulate-placeholder',
        FLIGHT_TRACKING_MODAL: '.view-flight-progress',
        NOTES: '#reservation-edit-notes',
		// To include notes and blue sky images
		NOTES_PREVIEW: 'span.reservation-notes, span.request-green',
		CALENDAR: 'a.calendar',
		MAGAZINE: 'a.magazine',
		SELF_ENROLL: ".enroll.self-enroll",
		ENROLL: ".enroll.complete-enroll",
		MENUS: 'a.menus-overlay-link',
		INVOICES_TABLE: "#invoicesTable",
		INVOICES_SELECTED_TABLE: "#invoicesSelectedTable",
		INVOICES_TABLE_FILTERS: '.invoice-table-filters',
		PAYMENT_HISTORY_TABLE_FILTERS: '.payment-history-table-filters',
		CUSTOM_SELECT_ARROW: '.custom-select-arrow',
		TERMS_AGREEMENT_PAGINATION: '.terms-agreement',
		SELECT_ALL_INVOICES: 'th.select-all',
		DELETE_SELECTED_INOVICES: '.deleteInvoicesLink',
		AGREE_TERMS_AND_CONDITIONS_CHECKBOX: '#agree-terms-and-conditions-checkbox',
		CONTACT_US_BTN: '.contactUsBtn',
		AUTOPAY_CONTENT: '.autopay-content',
		ACCOUNT_DROPDOWN:'#account-selection-dd',
		OTHER_AMOUNT: '#CustomAmount',
		MANAGE_ACCOUNT_LINKS: '.cancel-autopay, .autopayApplyDeleteBtn',
		WINDOW_PRINT: '.js-print-btn'

	},
	variables: {
		peakDays: new Object,
		numFlightsToRequest: 3,
		sessionExpired: null,
		blurTimer: null,
		trackingMap: null,
		activeElement : null,
		selectedInvoiceNumbers : [],
		creditNoteNumbers: [],
		selectedInvoiceNumbers : []
	}
};

FC.updateNumberOfDraftReservations = function () {
    var setNumberOfWips = function (wipInfo) {
        var infoBox = $(".reservation-tabs").find(".wipInfoBox");
        if (infoBox.length == 0) {
            return;
        }
        var numberOfWips = (wipInfo == null) ? 0 : wipInfo.NumberOfWips,
            toolTip = (wipInfo && wipInfo.NumberOfWips > 0) ? wipInfo.ToolTip : "";
        if (numberOfWips > 0) {
            infoBox.text(numberOfWips);
            infoBox.removeClass("hidden");
        } else {
            infoBox.addClass("hidden");
            infoBox.text("");
        }
        infoBox.parent().attr("title", toolTip);
    };

    $.ajax({
        url: "/Home/GetNumberOfWipReservations",
        success: function (data) {
            setNumberOfWips(data);
        },
        error: function (data) {
            setNumberOfWips(null);
        }
    });
};

FC.viewReservations = function ($el) {
	var anchors = $el.find('a'),
		clickedAnchor,
		clickedAnchorParent,
		selectedParent = $el.find('li.selected'),
		flightContainer = $('div.flight-container'),
		reservationList = $('#reservationList'),
		heading = $el.prev('h2');

	anchors.bind('click', function () {
		clickedAnchor = $(this);
		clickedAnchorParent = clickedAnchor.parent();
		reservationList = $('#reservationList');


		//Check for session expiry before making the call
		$.ajax({
			url: "/Account/Authenticate/SessionTimedOut",
			success: function (data) {

				//If the session hasn't expired
				if (data == false) {

					// remove tooltip
					clickedAnchor.parents(".reservation-tabs").find(".wipInfoBox").parent().attr("title", "");
					resAjaxCall();
					var url = clickedAnchor.attr('data-url');
					if (url && url.toLowerCase().indexOf("draftreservations") < 0) {
						FC.updateNumberOfDraftReservations();
					}
				}
				//If the session has expired
				else {

					document.location.href = "/Account/Authenticate/LogOn?expired=true";

				}

			},
			error: function (data) {
				document.location.href = "/Account/Authenticate/LogOn?expired=true";
			}
		});

		function resAjaxCall() {
			$.ajax({
				url: clickedAnchor.attr('data-url'),
				success: function (data) {

					reservationList.fadeOut('fast', function () {
						reservationList.empty().append(data).fadeIn('fast');
						selectedParent.removeClass('selected');
						clickedAnchorParent.addClass('selected');
						selectedParent = clickedAnchorParent;

						FC.flightDetails($(FC.vars.selectors.FLIGHT_DETAILS));
						FC.notePreview($(FC.vars.selectors.NOTES_PREVIEW));

						FC.showMoreReservations($(FC.vars.selectors.SHOW_MORE_RESERVATIONS_BUTTON));
						FC.confirmDelete($(FC.vars.selectors.CONFIRM_DELETE));
						$('.airport').matchHeight();
						$('.city').matchHeight();
					})
				}
			});
		}

		return false;
	});
};

FC.showMoreReservations = function ($el) {
	var url = $el.attr('data-url'),
		$list = $('#reservationList ul.reservations');

	//request next set of flights via ajax call

	function requestMoreReservations(e) {
		anchorPostion = $list.find('li:last').offset();
		$el.before("<div class='loader'><p>Loading more items</p><img src='/Resources/images/ajax-loader.png' width='40' height='40' alt='loading more flights' /></div>");

		//animate out the loader
		$("div.loader").css({ opacity: 0 });
		$("div.loader").animate({ "height": "100px" }, 500, function () { $("div.loader").css({ opacity: 1 }) });


		//Check for session expiry before making the call
		$.ajax({
			url: "/Account/Authenticate/SessionTimedOut",
			success: function (data) {

				//If the session hasn't expired
				if (data == false) {

					moreResAjaxCall();

				}
				//If the session has expired
				else {

					document.location.href = "/Account/Authenticate/LogOn?expired=true";

				}

			},
			error: function (data) {
				document.location.href = "/Account/Authenticate/LogOn?expired=true";
			}
		});


		function moreResAjaxCall() {
			$.ajax({
				url: url,
				dataType: 'html',
				success: function (data) {

					$('div.loader').remove();
					if (data != "") {
						if (FC.vars.variables.numFlightsToRequest == 1) {
							$list.append($('<div>').append(data).find('li:first'));
						} else {
							$list.append(data);
							FC.flightTracking();
							window.scrollTo(anchorPostion.left, anchorPostion.top);
						}


						//if we have loaded the last reservation (which has the 'last' class)
						//remove the 'show more' button (as their aren't any!)
						if ($(data).find('li.last').length) {
							$el.remove();
						}
						FC.confirmDelete($(FC.vars.selectors.CONFIRM_DELETE));
					} else {
						$('div.loader').remove();
						$el.hide();
					}

					FC.flightDetails($(FC.vars.selectors.FLIGHT_DETAILS))
					$('.airport').matchHeight();
					$('.city').matchHeight();

				},
				error: function (data) {
					$('div.loader').remove();
					alert('An error occurred: ', data);
				}
			});


		}

		return false;
	}


	//bind event handler
	$el.unbind('click').bind('click', requestMoreReservations);
};

FC.confirmDelete = function ($el) {
	//deleting flights requires a confirmation bubble overlay to be displayed
	//with 'confirm' and 'cancel' buttons

    var deleteFlightURL = '/Home/DeleteWipReservation/',
		confirmationOverlay = $('div.confirmation-overlay'),
		confirmButton = confirmationOverlay.find('li.confirm a'),
		cancelButton = confirmationOverlay.find('li.cancel a'),
		reservationId,
		$currentElement,
		yPos,
		xPos;

	//display the overlay vertically and horizontally centered
	function confirmationHandler(e, flightId) {
	    var yPos = $currentElement.offset().top + 14, //14 is the height of the triangle part of the overlay
			xPos = $currentElement.offset().left - 10; //move 10px backwards to match design

	    if (confirmButton && confirmButton.prop("disabled")) {
	        return;
	    }

		if ($currentElement.hasClass('clicked')) {
		    $currentElement.removeClass('clicked');
		    if (confirmButton) {
		        confirmButton.prop("disabled", "disabled");
		    }
		    $.ajax({
			    beforeSend: function (request) {
			        FC.AddAntiForgeryToken(request);
			    },
			    data: JSON.stringify({id: reservationId}),
			    type: 'POST',
			    dataType: 'json',
			    url: deleteFlightURL,
				contentType: "application/json; charset=utf-8",
				success: function (data) {

					//If session hasn't expired
					if (data.SessionExpired == false) {
						if (ga) {
							ga('send', 'event', 'Reservations', 'Drafts', 'Draft Deleted');
						}
						if (data.Response == true) {
							//confirmation of delete received, so remove the flight from the page
							$('#' + reservationId).fadeOut('fast', function () {
								FC.vars.variables.numFlightsToRequest = 1;
								$(FC.vars.selectors.SHOW_MORE_RESERVATIONS_BUTTON).trigger('click');
							});
							FC.updateNumberOfDraftReservations();
						} else {
							//deleting failed
							alert(data.Message);
						}
						overlayClose(e);


					}
					//Session has expired
					else {

						document.location.href = data.RedirectUrl;

					}

				},
				error: function (data) {
					alert('An error occurred: ', data);
				},
				complete: function() {
				    if (confirmButton) {
				        confirmButton.prop("disabled", false);
				    }
				}
			});
		}

		//show confirmation overlay
		else {

			//Move the overlay to the top of the DOM
			$("body").append(confirmationOverlay);
			confirmationOverlay = $("body > div.confirmation-overlay")

			$currentElement.addClass('clicked');

			FC.showModal(confirmationOverlay, 200, 200, true);

			/*
			confirmationOverlay.css({
			'top': yPos + $currentElement.height() + 'px',
			'left': xPos + 'px'
			});*/
		}
		e.preventDefault();
	}

	function confirmDelete(e) {
		e.preventDefault();
		$currentElement.trigger('click');
	}

	function overlayClose(e) {
		$currentElement.removeClass('clicked');
		confirmationOverlay.removeAttr('style');
		FC.hideModal(confirmationOverlay);
		e.preventDefault();
	}

	//bind event handlers
	confirmationOverlay.find('a.close').unbind('click').bind('click', overlayClose);
	cancelButton.unbind('click').bind('click', overlayClose);

	//MOS-258 - Close overlays with ESC key
	$("html").bind("keyup", function (e) {
		if (!confirmationOverlay) { return; }
		if (e.keyCode == 27)
			cancelButton.trigger("click");
	});

	confirmButton.prop("disabled", false);
	confirmButton.unbind('click').bind('click', confirmDelete);

	//more flights can be loaded after initial page load (by clicking 'more flights' button)
	$el.unbind('click').bind('click', function (e) {
		$currentElement = $(this);
		reservationId = $currentElement.parents('li')[0].id;
		confirmationHandler(e, reservationId);
	});
};

FC.trimUsername = function ($el) {
	$el.bind('blur', function (e) {
		var textValue = $el.val();

		$el.val(textValue.trim());
	});
};

FC.triggerReviewPopup = function($el){
	FC.showModal($el, $el.width(), $el.height(), true);

	function overlayClose(e) {
		FC.hideModal($el);
		e.preventDefault();

		//Track Ask Later
		$.ajax({
			url: "/Home/UpdatePopupTracker/",
			type: 'POST',
			data: "{ 'clickedConfirm': false, 'clickedAskMeLater': true }",
			dataType: 'json',
			contentType: 'application/json; charset=utf-8',
			beforeSend: function (request) {
				FC.AddAntiForgeryToken(request);
			},
			success: function (data) {
			},
			error: function (jqXHR, textStatus, errorThrown) {
				alert('An error occurred: ', textStatus);
			}
		});
	}

	$el.find('a.asklater').unbind('click').bind('click', overlayClose);

	function overlayConfirm(e) {
		e.preventDefault();

		//Track Confirm
		$.ajax({
			url: "/Home/UpdatePopupTracker/",
			type: 'POST',
			data: "{ 'clickedConfirm': true, 'clickedAskMeLater': false }",
			dataType: 'json',
			contentType: 'application/json; charset=utf-8',
			beforeSend: function (request) {
				FC.AddAntiForgeryToken(request);
			},
			success: function (data) {

				if (data.Redirect) {
					window.location.href = "/Profile/PersonalDetails";
				}
			},
			error: function (jqXHR, textStatus, errorThrown) {
				alert('An error occurred: ', textStatus);
			}
		});
	}

	$el.find('a.confirmprofile').unbind('click').bind('click', overlayConfirm);
};

FC.mobileNav = function ($el) {

	/*var menuButton = $el.find('li.menu a'),
		completeMenu = $el.find('ul.complete');

	menuButton.bind('click', function () {
		if (completeMenu.hasClass('open')) {
			completeMenu.slideUp();
			completeMenu.removeClass('open');
		} else {
			completeMenu.slideDown();
			completeMenu.addClass('open');
		}
	});*/

	//Setup mobile navigation controls
	var $mobileNavTrigger = $('.mobile-nav-trigger');
	var $mainSiteNav = $('.header--main__navigation nav.primary');
	var $bodyHtml = $('body, html');

	var iconAngleUp = 'icon-angle-up';
	var iconAngleDown = 'icon-angle-down';
	// Toggle Account Sub Nav list
	var $accountSubNav = $('.pop-sub-nav__account-label');
	$accountSubNav.on('click', function() {
		var $accountSubNavList = $('.pop-sub-nav__account-list');
		var $accountChevron = $('.account-chevron');
		var chevronClass;
		if ($accountSubNavList.hasClass('expanded')) {
			$accountSubNavList.removeClass('expanded');
			chevronClass = iconAngleDown;
		} else {
			$accountSubNavList.addClass('expanded');
			chevronClass = iconAngleUp;
		}
		$accountChevron.removeClass(iconAngleDown).removeClass(iconAngleUp).addClass(chevronClass);
	});

	var $switchAccountsSubNav = $('.pop-nav__switch-accounts-label');
	$switchAccountsSubNav.on('click', function() {
		var $switchAccountsSubNavList = $('.pop__wrap-listing-switch-accounts');
		var $switchAccountsChevron = $('.switch-accounts-chevron');
		var chevronClass;

		if ($switchAccountsSubNavList.hasClass('expanded')) {
			$switchAccountsSubNavList.removeClass('expanded');
			chevronClass = iconAngleDown;
		} else {
			$switchAccountsSubNavList.addClass('expanded');
			chevronClass = iconAngleUp;
		}
		$switchAccountsChevron.removeClass(iconAngleDown).removeClass(iconAngleUp).addClass(chevronClass);
	});
	
	// Toggle Account Sub Nav list
	var $profileSubNav = $('.pop-nav__profile-label');
	$profileSubNav.on('click', function() {
		var $profileSubNavList = $('.pop__wrap-listing-profile');
		var $profileChevron = $('.profile-chevron');
		var chevronClass;

		if ($profileSubNavList.hasClass('expanded')) {
			$profileSubNavList.removeClass('expanded');
			chevronClass = iconAngleDown;
		} else {
			$profileSubNavList.addClass('expanded');
			chevronClass = iconAngleUp;
		}
		$profileChevron.removeClass(iconAngleDown).removeClass(iconAngleUp).addClass(chevronClass);
	});
	
	var $contactUsSubNav = $('.pop-nav__contact-us-label');
	$contactUsSubNav.on('click', function() {
		var $contactUsSubNavList = $('.pop__wrap-listing-contact-us');
		var $contactUsChevron = $('.contact-us-chevron');
		var chevronClass;

		if ($contactUsSubNavList.hasClass('expanded')) {
			$contactUsSubNavList.removeClass('expanded');
			chevronClass = iconAngleDown;
		} else {
			$contactUsSubNavList.addClass('expanded');
			chevronClass = iconAngleUp;
		}
		$contactUsChevron.removeClass(iconAngleDown).removeClass(iconAngleUp).addClass(chevronClass);
	});

	//On click of mobile hamburger menu, show hide nav
	$mobileNavTrigger.on('click', function(){
		var $this = $(this);

		if ( $this.hasClass('expanded') ) {
			$this.removeClass('expanded');
			$this.removeClass('header-expanded').addClass('header-collapsed');
			$mainSiteNav.removeClass('expanded');
			$bodyHtml.removeClass('overflow-hidden'); //Makes mobile nav act more like a native app

		} else {
			$this.addClass('expanded');
			$this.addClass('header-expanded').removeClass('header-collapsed');
			$mainSiteNav.addClass('expanded');
			$bodyHtml.addClass('overflow-hidden'); //Makes mobile nav act more like a native app

		}

	});
};

FC.helpDD = function ($el) {
	var parent = $el.parent();
	helpList = parent.find('ul'),
	helpListChildren = helpList.find('li');
	helpListChildren.css('opacity', '0');

	$el.bind('click', function (e) {
		if (!e.originalEvent || !e.target) {
			return;
		}
		var linkParent = $(e.target).parent(),
			linkHelpList = linkParent.find('ul'),
			linkHelpListChildren = linkHelpList.find('li');
		if (linkParent.hasClass('show')) {
			linkHelpListChildren.stop().animate({
				'opacity': 0
			}, 200, function () {
				linkHelpList.slideUp(200)
			});
			linkParent.removeClass('show');
		} else {
			helpList.slideUp(0);
			parent.removeClass('show');
			linkHelpList.slideDown(200, function () {
				linkHelpListChildren.animate({
					'opacity': 1
				});
			});
			linkParent.addClass('show');
		}
	});

	$("body").bind("click", function (e) {
		var shouldClose = true;
		if (e && e.target) {
			var targetParent = $(e.target).parent();
			if (targetParent.hasClass("help") && targetParent.hasClass("show")) {
				shouldClose = false;
			}
		}
		if (shouldClose) {
			helpListChildren.stop().animate({
				'opacity': 0
			}, 200, function () {
				helpList.slideUp(200);
			});
			parent.removeClass('show');
		}
	});
};

FC.accountsDD = function ($el) {
	var parent = $el.parent();
	accountList = parent.find('ul'),
	accountListChildren = accountList.find('li');
	accountListChildren.css('opacity', '0');

	$el.bind('click', function (e) {
		e.preventDefault();
		if (parent.hasClass('show')) {
			accountListChildren.animate({
				'opacity': 0
			}, 200, function () {
				accountList.slideUp(200)
			});
			parent.removeClass('show');
			$el.text('Show accounts');
		} else {
			accountList.slideDown(200, function () {
				accountListChildren.animate({
					'opacity': 1
				});
			});
			parent.addClass('show');
			$el.text('Hide accounts');
		}
	});

	$("body").bind("click", function (e) {
		if (e.target==$el[0] || !parent || !parent.hasClass("show")) {
			return;
		}
		accountListChildren.animate({
			'opacity': 0
		}, 200, function () {
			accountList.slideUp(200)
		});
		parent.removeClass('show');
		$el.text('Show accounts');
	});
};


FC.tabs = function ($el) {
	var $tabControls = $el.find('ul.tabs'),
		$anchors = $tabControls.find('a'),
		$tabContent = $el.find('section'),
		tabReference,
		$selectedTab;

	if ($tabControls.css('display') === 'block') {
		$tabContent.each(function (i) {
			if (i !== 0) {
				$(this).css('display', 'none');
			} else {
				$(this).addClass('selected');
				tabReference = $(this)[0].getAttribute('data-mobile-tab');
				$('section[data-mobile-tab="' + tabReference + '"]').addClass('selected');
			}
		});
	}

	$anchors.bind('click', function (e) {
		var anchor = $(this)[0],
			par = anchor.parentNode;
		tabReference = anchor.getAttribute('data-mobile-tab');
		$selectedTab = $tabContent.filter('.selected');
		$selectedTab.removeClass('selected');
		$selectedTab.fadeOut();

		$('section[data-mobile-tab="' + tabReference + '"]').fadeIn().addClass('selected');
		$tabControls.find('li.selected').removeClass('selected');
		par.className = 'selected';

		e.preventDefault();
	});
};

FC.passwordStrength = function ($el) {
	var $input = $el,
		inputValue,
		minChars = 8,
		maxChars = 25,
		containsNumbers = false,
		containsUpperLetters = false,
		containsLowLetters = false,
		$strength,
		strengthClass = "invalid",
		message = "";

	function PasswordStrengthTest() {
		var self = this;
		self.score = null;

		function testUpperLetters(inputValue) {
			var regexp = /[A-Z]/g,
				letters = inputValue.match(regexp);

			if (letters) {
				if (letters.length === 1) {
					self.score += 15;
				} else {
					self.score += 25;
				}
				return true;
			} else {
				return false;
			}
		}

		function testLowLetters(inputValue) {
			var regexp = /[a-z]/g,
				letters = inputValue.match(regexp);

			if (letters) {
				if (letters.length === 1) {
					self.score += 15;
				} else {
					self.score += 25;
				}
				return true;
			} else {
				return false;
			}
		}

		function testNumbers(inputValue) {
			var regexp = /[0-9]/g,
				numbers = inputValue.match(regexp);

			if (numbers) {
				if (numbers.length === 1) {
					self.score += 15;
				} else {
					self.score += 25;
				}
				return true;
			} else {
				return false;
			}
		}

		// Test for non alpha-numeric chars.

		function testSpecialChars(inputValue) {
			var characters = inputValue.match(/[^\w]/g) || [];

			if (characters.length === 0) {
				self.score += 0;
			} else if (characters.length === 1) {
				self.score += 15;
			} else {

				self.score += 25;
			}
		}

		this.getScore = function () {
			//console.log(self.score)
			return self.score;
		}

		this.test = function (value) {
			if (inputValue.length < minChars) {
				this.message = "Too short";
				strengthClass = "invalid";
			}else if (inputValue.length >= maxChars) {
				this.message = "Too long";
				strengthClass = "invalid";
			}else {
				containsNumbers = testNumbers(value);
				containsUpperLetters = testUpperLetters(value);
				containsLowLetters = testLowLetters(value);
				testSpecialChars(value);

				if (!containsNumbers || !containsUpperLetters || !containsLowLetters) {
					this.message = "Weak";
					strengthClass = "invalid";
				} else if (this.getScore() <= 65) {
					this.message = "OK";
					strengthClass = "ok";
				} else {
					this.message = "Strong";
					strengthClass = "strong";
				}
			}
		}
	}

	//setup field to display the strength;
	$input.after('<span class="strength"></span>');
	$strength = $('span.strength');

	//create our new tester instance
	tester = new PasswordStrengthTest();

	function checkPassword() {
		inputValue = $input.val();
		tester.score = 0;
		tester.test(inputValue);

		$strength.text(tester.message);
		$strength[0].className = "strength strength-" + strengthClass;

		if (tester.getScore() >= 40) {
			$input.addClass('pwValid');
		} else {
			$input.removeClass('pwValid');
		}

	}

	$el.bind('keyup', checkPassword);
	FC.confirmPassword($el);
};

FC.confirmPassword = function ($el) {
	var originalPwInput = $el,
		confirmInput = $el.parents('div.confirm-required').find('input.confirm'),
		$submitButton = $el.parents('fieldset').find('input[type="submit"]'),
		$errMsgContainer = confirmInput.next('.err-msg');

	function checkPassword() {
		// (Un)disable submit button
		if (originalPwInput.val() == confirmInput.val() && originalPwInput.hasClass('pwValid')) {
			$submitButton.removeAttr('disabled', 'disabled');
			$errMsgContainer.hide();
		} else {
			$submitButton.attr('disabled', 'disabled');
			$errMsgContainer.hide();
		}

		// Show error that passwords don't match (only when the first field is strong enough)
		if (originalPwInput.hasClass('pwValid')) {
			if (originalPwInput.val() != confirmInput.val()) {
				$errMsgContainer.show();
			} else {
				$errMsgContainer.hide();
			}

		}

	}

	if (confirmInput.length) {
		$submitButton.attr('disabled', 'disabled');
		confirmInput.bind('keyup.match', checkPassword);
		originalPwInput.bind('keyup.match', checkPassword);
		checkPassword();
	}
};


FC.centralise = function (width, height) {

	if (!width) {
		var width = 100;
	}
	if (!height) {
		var height = 100;
	}

	var leftIndent = $(window).width();
	leftIndent = (leftIndent - width) / 2;
	var screenHeight = $(window).height();
	//if the overlay height is taller than the screen, set topIndent to 0
	//otherwise set it to vertical centre of screen
	var topIndent = screenHeight > height ? (screenHeight - height) / 2 : 0;
	var topScroll = $(window).scrollTop();
	topIndent = topIndent + topScroll;

	var vals = [leftIndent, topIndent];

	return vals;

};


//SHOW CURTAIN
FC.showCurtain = function () {

	if( !$(".curtain").length ) {
		var curtain = '<div class="curtain">&nbsp;</div>';
		$("body").append(curtain);
	}

};

//HIDE CURTAIN
FC.hideCurtain = function () {
	var curtain = $("body .curtain");
	curtain.fadeOut("fast" , function(){
		$(this).remove();
	})
};

//SHOW LOADING GRAPHICS
FC.showLoading = function () {
	FC.showCurtain();
	var spinner = '<div id="spinner" />';
	var indent = FC.centralise(100, 100);

	if( !$("body #spinner").length ){
		$("body").append(spinner);
		//$("body #spinner").css({ "left": indent[0] + "px", "top": indent[1] + "px" });
		FC.loadingAnimation();
	}
};

//REMOVE LOADING GRAPHICS
FC.removeLoading = function (curtain) {
	$("body #spinner").remove();
	if (curtain != false) {
		FC.hideCurtain();
	}
	FC.removeLoadingAnimation($("#spinner"));
};

//Loading animation
FC.loadingAnimation = function (args) {

	if (args == undefined) {
		args = {};

	}
	var settings = {
		xPos: 0,
		yPos: 0,
		index: 0,
		frames: args.frames || 10,
		frameWidth: args.frameWidth || 94,
		el: args.el || $("#spinner"),
		intervalTime: args.intervalTime || 250
	};

	//settings.el.show();

	setInterval(function () {
		animate();
	}, settings.intervalTime);

	var animate = function () {
		settings.el.css({
			"background-position": (-settings.xPos) + "px " + (settings.yPos) + "px"
		});

		settings.xPos += settings.frameWidth;
		settings.index += 1;
		if (settings.index == settings.frames) {
			settings.xPos = 0;
			settings.yPos = 0;
			settings.index = 0;
		}
	};

};


//Remove loading animation
FC.removeLoadingAnimation = function (el) {
	if (el) {
		el.remove();
	}
};

//SHOW MODAL WINDOW
FC.showModal = function (modal, width, height, curtain) {
	if (curtain) {
		FC.showCurtain();
	}
	var indent = FC.centralise(width, height);
	modal.css({ "display": "block", "left": indent[0] + "px", "top": indent[1] + "px" }).addClass('displayed');
};

//SHOW MODAL WINDOW
FC.ShowDialogBox = function (title, content, settings) {
	if (settings && settings.overlay) {
		FC.showCurtain();
	}

	var dialogBoxMarkup = '<div class="dialogBox">' +
							'<div class="dialogBox-header padding clear">' +
								'<h2 class="dialogBox-title">' + title + '</h2>' +
							'</div>' +
							'<div class="dialogBox-content padding clear">' +
								'<p>' + content + '</p>' +
							'</div>' +
							'<div class="dialogBox-footer padding clear text-right">' +
								'<a href="#" class="btn btn-primary" data-dialogBox="close">Close</a>' +
							'</div>' +
					   '</div>';
	var dialogBoxSelector = '.dialogBox';
	if (!$(dialogBoxSelector).length > 0) {
		$('body').append(dialogBoxMarkup);
		$(dialogBoxSelector).show();
	} else if ($(dialogBoxSelector).length > 0 && $(dialogBoxSelector).is(':hidden') === true) {
		$(dialogBoxSelector).find('.dialogBox-title').html(title);
		$(dialogBoxSelector).find('.dialogBox-content').html('<p>' + content + '</p>');
		$(dialogBoxSelector).show();
	} else {
		$(dialogBoxSelector).hide();
		FC.hideCurtain();
	}
	$('[data-dialogbox="close"]').on('click', function () {
		$('.dialogBox').hide();
		FC.hideCurtain();
	});
	return this;
};

//HIDE MODAL WINDOW
FC.hideModal = function (modal, curtain) {
	modal.hide();
	modal.removeClass('displayed');
	if (curtain == false) {
	} else {
		FC.hideCurtain();
	}

};

//HIDE MODAL WINDOW
FC.hideModalOffscreen = function (modal) {
	modal.css({
		'left': '-999px',
		'top': '-999px'
	});
	modal.removeClass('displayed');
	FC.hideCurtain();
};

//ADD MODAL WINDOW
FC.addModal = function (modal, width, height, curtain) {
	if (curtain) { FC.showCurtain(); }
	modal = $(modal);
	$("body").append(modal);
	var indent = FC.centralise(width, height);
	modal.css({ "display": "block", "left": indent[0] + "px", "top": indent[1] + "px" });
}

//REMOVE MODAL WINDOW
FC.removeModal = function( modalClass ) {
	if(!modalClass){
		$("body .modal-window:visible").remove();
	} else {
		$("body").find(modalClass[0]).remove();
	}
	FC.hideCurtain();
}

FC.loading = function (hasConfirmModal) {
	var blackout = "<div class='blackout blackout-loading'></div>",
		$blackout,
		screenWidth = $(window).width(),
		screenHeight = $(window).height(),
		spinner = '<img src ="/Resources/images/icons/loader.gif" width="100" height="100" id="spinner" alt="loading..." />',
		hasConfirmModal = hasConfirmModal,
		$spinner;
	//modalWidth = $modal.width(),
	//modalHeight = $modal.height();

	$blackout = $('body').find('div.blackout');
	$spinner = $('body').find('img#spinner');

	this.hide = function () {
		if (hasConfirmModal) {
			//$('div.blackout').addClass('hidden');
			$spinner.addClass('hidden');
		} else {
			$('div.blackout').addClass('hidden');
			$spinner.addClass('hidden');
		}
	}

	this.showLoadingSpinner = function () {
		if (!$blackout.length) {
			$('body').append(blackout);
			$blackout = $('body').find('div.blackout .blackout-loading');
		} else {
			$blackout.addClass('blackout-loading');
		}

		if (!$spinner.length) {
			$('body').append(spinner);
			$spinner = $('body').find('img#spinner');
		}

		$blackout.removeClass('hidden');
		$spinner.removeClass('hidden');

		//find the values to centralise the spinner
		var indent = FC.centralise(100, 100);
		$spinner.css({ "left": indent[0] + "px", "top": indent[1] + "px" });


	}

	//showLoadingSpinner();
};

FC.genModal = function ($el, confirmClickHandler, state) {

	var $modal = $el,
		$closeButton = $modal.find('a.close'),
		$cancelButton = $modal.find('li.cancel a'),
		$confirmButton = $modal.find('li.confirm a'),
		$bgOverlay = "<div class='bg-overlay'></div>";


	$('body').append($bgOverlay);
	$el.addClass('show');

	$bgOverlay.addclass("show");

	function closeModal() {
		$modal.removeClass('show');
		$modal.removeAttr('style');

		/*if (!$bgOverlay.hasClass('blackout-loading')) {
		$bgOverlay.addClass('hidden');
		}*/

		$el.removeClass('show');

		$closeButton.unbind('click');
		$cancelButton.unbind('click');
		$confirmButton.unbind('click');
	}

	function closeHandler(e) {
		e.preventDefault();
		if ($modal.find('textarea').length) {
			textarea = $modal.find('textarea')[0];
			textarea.textContent = textarea.getAttribute('data-placeholder');
			textarea.innerHTML = textarea.getAttribute('data-placeholder');
		}
		closeModal();
	}

	$closeButton.bind('click', closeHandler);
	$cancelButton.bind('click', closeHandler);

	if ($confirmButton.parents('ul.buttons-confirm').length) {
		$confirmButton.bind('click', function () {
			closeModal();
			return false;
		});
	} else {
		$confirmButton.bind('click', confirmClickHandler);
	}
};

FC.openBG = function () {

	var bg = $("body").find(".bg-overlay");

	if (bg.length == 0) {

		$("body").append("<div class='bg-overlay'></div>");

	}

	var bgOverlay = $("body .bg-overlay");

	bgOverlay.addClass("show");

};

FC.closeBG = function () {

	var bgOverlay = $("body .bg-overlay");

	if (bgOverlay.length > 0) {
		bgOverlay.remove();
	}

};

FC.modal = function ($el, isAM) {


	var $modal = $el,
		closeSelector = "a.close",
		cancelSelector = "li.cancel a",
		confirmSelector = "> div.modal-buttons li.confirm a",
		$closeButton = $modal.find(closeSelector),
		$cancelButton = $modal.find(cancelSelector),
		$confirmButton = $modal.find(confirmSelector),
		blackout = "<div class='blackout'></div>",
		$blackout,
		screenWidth = $(window).width(),
		screenHeight = $(window).height(),
		modalWidth = $modal.width(),
		modalHeight = $modal.height(),
		xPos = (screenWidth - modalWidth) / 2 + 'px',
		yPos = $('html').scrollTop();

	$blackout = $('body').find('div.blackout');

	if (!$blackout.length) {
		//$('body').append(blackout);
		//$blackout = $('body').find('div.blackout');
	}

	/*
	if ($modal.hasClass('save-order-modal')) {
	var top = (screenHeight - modalHeight) / 2;

	if (top < 0) {
	top = 10;
	}

	$modal.css({
	'left': (screenWidth - modalWidth) / 2 + 'px',
	'top': top + 'px',
	'display': 'block',
	'bottom': 'auto'
	});
	}
	*/

	if (modalHeight >= screenHeight) {
		yPos = yPos + 10 + 'px';
	} else {
		yPos = (screenHeight - modalHeight) / 2 + yPos / 2 + 'px';
	}

	if ($modal.hasClass('calendar')) {
		$modal.css({
			'display': 'block'
		});
	} else {
		$modal.css({
			'display': 'block',
			'top': yPos,
			'left': xPos
		});
	}

	$el.addClass('show');

	$blackout.removeClass('hidden');

	function closeModal() {
		$modal.removeClass('show');
		$modal.removeAttr('style');

		$blackout.addClass('hidden');

		$modal.off("click");
	}

	function closeHandler(e) {
		e.preventDefault();
		if ($modal.find('textarea').length) {
			textarea = $modal.find('textarea')[0];
			textarea.textContent = textarea.getAttribute('data-placeholder');
			textarea.innerHTML = textarea.getAttribute('data-placeholder');
		}

		closeModal();
	}

	$modal.on("click", closeSelector, closeHandler);
	$modal.on("click", cancelSelector, function (e) {
		closeModal();
		$("body").unbind();
		return false;
	});
	if ($confirmButton.parents('ul.buttons-confirm').length) {
		$modal.on("click", confirmSelector, function () {
			closeModal();
			return false;
		});
	}

	//If this is the calendar,
	if ($modal.find(".full-date").length > 0) {


		//then force a refresh to bring in the peak days
		var dateToCheck = $modal.find(".full-date").val();
		if (dateToCheck == "") {
			$modal.find("td.low-range").click();
		} else {
			var splitDate = dateToCheck.split("/");
			var dateToClick = $modal.find("td.cd-" + splitDate[2] + splitDate[1] + splitDate[0])
			dateToClick.click();
		}
	}


	//If this is a calendar and there is an IsAM agrument then update the ampm field
	//alert(isAM);
	//Find what the currentl selected index of the ampm is
	/*var select = $modal.find("select.ampm");
	var currentSelection = select[0].selectedIndex;
	if (isAM == true) {

	select[0].selectedIndex = 0;

	}

	if (isAM == false) {

	select[0].selectedIndex = 1;

	}*/


};

FC.htmlDecode = function(str) {
	if (typeof str == "string") {
		return $('<div />').html(str).text();
	}
	return "";
};


// common logic to populate list items with results returned from a predictive search
FC.processPredictiveAirportResults = function processPredictiveSearchResults(data, list, predictiveInput) {
	if (!data || !list || !predictiveInput) { return; }

	function createAnchor(anchor, airportData) {
		anchor.setAttribute('data-airport', JSON.stringify(airportData));
		anchor.appendChild(document.createTextNode(FC.htmlDecode(data.Airports[i].SearchDescription)));
		anchor.href = "#";
		anchor.onclick = function (e) {
			predictiveInput.close();
			airportData = $.parseJSON(anchor.getAttribute('data-airport'));
			predictiveInput.input.attr('data-airport', anchor.getAttribute('data-airport'));
			predictiveInput.input.val(airportData.Code + ' ' + FC.htmlDecode(airportData.FullName));
			predictiveInput.input.trigger('update');
			return false;
		}
		return anchor;
	}

	for (var i = 0; i < data.Airports.length; i++) {
		var li = document.createElement('li');
		anchor = document.createElement('a');

		//if the airport doesn't have any restrictions, create an anchor
		//and append to <li>
		if (data.Airports[i].SelectedProgram.AircraftTypeRestrictions.length == 0) {
			li.appendChild(createAnchor(anchor, data.Airports[i]));
		} else {
			var thisAircraftRestricted = false;

			//loop through restrictions. if the selected aircraft type (val.aircraftType)
			//is found, break out of loop
			for (var j = 0; j < data.Airports[i].SelectedProgram.AircraftTypeRestrictions.length; j++) {
				if (predictiveInput.options && predictiveInput.options.aircraftType == data.Airports[i].SelectedProgram.AircraftTypeRestrictions[j].AircraftType) {
					thisAircraftRestricted = true;
					break;
				} else {
					thisAircraftRestricted = false;
				}
			}

			//if selected aircraft type (val.aircraftType) is on the restrictions list,
			//append it to <li>
			if (thisAircraftRestricted) {
				var restrictedSpan = document.createElement("span");
				restrictedSpan.className = "restricted";
				restrictedSpan.appendChild(document.createTextNode(data.Airports[i].SearchDescription + ' Not suitable for ' + data.Airports[i].SelectedProgram.AircraftTypeRestrictions[j].AircraftDescription));
				li.appendChild(restrictedSpan);

			}

			//the selected aircraft type (val.aircraftType) is not on the restricted list
			//so create anchor and append to <li>
			else {
				li.appendChild(createAnchor(anchor, data.Airports[i]));
			}
		}
		list.appendChild(li);
	}

};

FC.predictiveInput = function ($el, url, processResultsCallback) {
	var $input = $el,
		timeout = 500,
		charTrigger = $input.attr('data-predictive-char-trigger'),
		$resultsPanel = $input.next('div.predictive-results'),
		$persistList = $resultsPanel.find('ul.persist'),
		spinner = $resultsPanel.find('img'),
		resultList = $resultsPanel.find('ul:first')[0],
		type,
		elHeight = 0,
		elWidth,
		elOffset,
		lastSearchTerm,
		lastInputContent,
		lastSearchStart,
		loaderClass = 'predictive',
		self = this;

	self.options = {};
	self.close = closePredictiveText;
	self.searchParams = {};
	self.input = $input;

	function navigateResultList(keycode) {
		var resultList = $resultsPanel.find('a'),
			focusIndex = 0, //track which anchor has focus;
			numLinks = resultList.length - 1;

		if (keycode == 40) { //down key
			resultList.eq(focusIndex).focus();
		}

		resultList.bind('keydown', function (e) {
			e.preventDefault();
			var listKeyCode = e.keyCode;

			if (listKeyCode == 40) { //down key
				if (focusIndex < numLinks) {
					focusIndex++;
					resultList.eq(focusIndex).focus();
				} else if (focusIndex == numLinks) {
					focusIndex = 0;
					resultList.eq(focusIndex).focus();
				}
			} else if (listKeyCode == 38) { // up key
				if (focusIndex == 0) {
					//first link has focus so jump to the last link
					focusIndex = numLinks;
					resultList.eq(numLinks).focus();
				} else {
					focusIndex--;
					if (focusIndex >= 0) {
						resultList.eq(focusIndex).focus();
					}
				}
			} else if (listKeyCode == 13) {
				$(resultList.eq(focusIndex)).trigger('click');
			}
		});

	}

	function processSearchResults(data, searchTerm) {

		// check if this search result correspond to the last search
		if (searchTerm != lastSearchTerm) {
			return;
		}

		// indicate that the search is complete
		lastSearchStart = null;
		var currentSearch = $input.val();
		if (currentSearch != searchTerm) {

			// schedule a new async search, but continue with stale results
			setTimeout(function() { lookup($input.val()); }, 1);
		}

		resultList.innerHTML = "";
		if (data.Message != null) {
			var li = document.createElement('li');
			li.appendChild(document.createTextNode(data.Message));
			li.className = "message";
			resultList.appendChild(li);
		}else {
			processResultsCallback(data, resultList, self);
		}
		setPosition();
	}

	function startVisualFeedback() {
		var showDropDown = !resultList.firstChild;
		if (showDropDown) {
			resultList.innerHTML = "<li class='message'>Searching...</li>";
			setPosition();
		}else {
			resultList.firstChild.innerHTML = resultList.firstChild.innerHTML + '<div class="ajax-loader ' + loaderClass + ' blue"></div>';
			FC.loadingAnimation({
				frameWidth: 25,
				frames: 6,
				el: $(".ajax-loader." + loaderClass)
			});
		}
	}

	function endVisualFeedback() {
		FC.removeLoadingAnimation($('.ajax-loader.' + loaderClass));
	}

	function getSearchOptions(searchTerm) {
		var searchOptions = { "query": searchTerm };
		for (var option in self.options) {
			searchOptions[option] = self.options[option];
		}
		return searchOptions;
	}

	function lookup(searchTerm) {
		var currentTime = new Date();
		if ((lastSearchTerm == searchTerm) || (lastSearchStart && (currentTime.getTime() - lastSearchStart.getTime() < timeout))) {
			return;
		}
		lastSearchStart = currentTime;
		lastSearchTerm = searchTerm;
		self.searchParams = getSearchOptions(searchTerm);
		$.ajax({
			url: '' + url + '',
			data: self.searchParams,
			beforeSend: startVisualFeedback,
			dataType: 'json',
			success: function (data) {
				if (data.SessionExpired == false) {
					processSearchResults(data, searchTerm);
				}else {
					document.location.href = data.RedirectUrl;
				}
			},
			error: function (jqXHR, textStatus, errorThrown) {
				alert('An error occurred: ', textStatus);
			},
			complete: endVisualFeedback
		});
	}

	function inputFocusHandler(e) {
		lastInputContent = $input.val();
	}

	function keyUpHandler(e) {
		e.preventDefault();
		var keyCode = e.keyCode;
		if (keyCode == 40) { // down key
			navigateResultList(e.keyCode);
		} else if (keyCode == 38) { //up key
			navigateResultList(e.keyCode);
		} else {
			var currentSearchTerm = $input.val();
			if (!currentSearchTerm || currentSearchTerm.length < charTrigger) {
				closePredictiveText();
				return;
			}
			if (lastInputContent == currentSearchTerm || lastSearchTerm && lastSearchTerm == currentSearchTerm) {
				return;
			}
			lookup(currentSearchTerm);
		}
	}

	function setPosition() {

		//get the position of the input and use that to position the predictive text results
		if (elHeight == 0) {
			elHeight = $el.height(true),
			elWidth = $el.width(),
			elOffset = $el.offset();
		}
		if($el.is(":focus")){
			$resultsPanel.removeClass('off-screen');
		} else {
			$resultsPanel.addClass('off-screen');
		}
	}

	function persistFocusHandler(e) {
		e.preventDefault();
		e.stopPropagation();
		setPosition();
	}

	function closePredictiveText(e) {

	   //a click event is bound to the <html> element so you can click anywhere to close the
		//pred text overlays.
		//however, we need to prevent that from firing when the user clicks on the textfield!
		var regexp = new RegExp(/text/),
			wasTextField;
		if (!e || !e.target) {
			wasTextField = false;
		}else {
			wasTextField = regexp.test(e.target.className);
		}
		if (!wasTextField) {
			$(".predictive-results ul").empty();
			$(".predictive-results").addClass('off-screen');
		}
		lastInputContent = $input.val();
		lastSearchTerm = null;
		lastSearchStart = null;
	}

	//bind events
	$input.unbind('keyup').bind('keyup', keyUpHandler);
	$input.unbind('focus').bind('focus', inputFocusHandler);

	if ($persistList.length) {
		$input.unbind('focus').bind('focus', persistFocusHandler);
	}

	$input.off('focus.selectInput').on('focus.selectInput', function () {
		if ($(this).val() != "") {
			$(this).select();
		}
	});

	$('html').unbind('click').bind('click', closePredictiveText);

	$input.off('focusout').on('focusout', function () {
		var predictRes = $(this).parent().find(".predictive-results li");
		var predictLength = predictRes.length;

		if (predictLength == 1) {
			$(predictRes[0]).find("a").trigger("click");
		} else if ($(this).val() == '') {
			$(this).attr('data-airport', '{}')
			$(this).attr('data-person', '{}')
		}

	});
};

FC.revealPanel = function ($el) {
	var numReveals = $el.length,
		$revealPar,
		$trigger,
		$panel;

	$trigger = $el.find('.reveal-trigger');

	function toggleReveal($trigger) {
		if ($revealPar.hasClass('reveal-hide')) {
			$revealPar.removeClass('reveal-hide');
		} else {
			$revealPar.addClass('reveal-hide');
		}
	}

	for (var i = 0; i < $trigger.length; i++) {
		$currentTrigger = $trigger.eq(i);

		if ($currentTrigger[0].tagName == 'SELECT') {
			$currentTrigger.bind('change', function () {
				$revealPar = $(this).closest('div.reveal');
				selectedOption = this.options[this.selectedIndex];

				if (selectedOption.className == 'reveal-option') {
					toggleReveal();
				} else {
					$revealPar.addClass('reveal-hide');
				}
			});
		} else {
			$currentTrigger.bind('click', function () {
				$revealPar = $(this).closest('div.reveal');
				toggleReveal();
			});
		}
	}
};



FC.tooltip = function ($el) {
	var tooltipContent = $el.find('.tooltip-content'),
		tooltipAnchor = $el.find('a');

	tooltipAnchor.bind('mouseenter', function () {
		tooltipContent.css({
			left: 'auto',
			right: -180 + 'px',
			top: 0
		});
	});

	tooltipAnchor.bind('mouseleave', function () {
		tooltipContent.css({
			left: -999 + 'em',
			top: -999 + 'em'
		});
	});
};

FC.flightDetails = function ($el, isPastFlight, startDate, endDate) {

	var detailsL = $($el);

	var detailsP = detailsL.parent().find(".flight");

	detailsP.bind("click", function () {
	    var link = $(this).parent().find("a.details-link"),
            url = link.attr("href");

	    if (isPastFlight) {
	        url += "&pastFlight=true";
	        if (startDate && endDate) {
	            url += "&startDate=" + startDate + "&endDate=" + endDate;
	        }
	        encodeURI(url);
	    }
	    document.location.href = url;

	});
};

FC.fancySelect = function ($el) {

	$el.each(function () {
		$(this).wrap('<div class="fancy-select-wrapper clear"></div>');

		$(this).addClass("hidden").after('<input type="text" maxlength="2"/><a href="#" class="increase"><span class="icon">Increase value</span></a><a href="#" class="decrease"><span class="icon">Decrease value</span></a>');

		innerWrapper = $(this).parent('div.fancy-select-wrapper');
		fancyNumberInput = new FC.FancySelectInput(innerWrapper);

	});
};

FC.FancySelectInput = function (fancyInputWrapper) {

	var minVals = [0, 15, 30, 45];
	var incCount = 0;

	var increaseButton = fancyInputWrapper.find('a.increase'),
		decreaseButton = fancyInputWrapper.find('a.decrease'),
		valueField = fancyInputWrapper.find('input[type="text"]'),
		originalSelect = fancyInputWrapper.find('select'),
		maxValue = originalSelect[0].options.length,
		minute = $(originalSelect[0]).hasClass("minute"),
		firstRun = 0,
		noInc = 0,
		showMins = fancyInputWrapper.parents(".time").find("#showMins0"),
		showMinsOff = true,
		errorMessage = fancyInputWrapper.closest("li.section").find(".error-message"),
		hasAmPm = originalSelect.parent().parent().find("#depart-time-ampm-").length > 0;


	if (minute && showMinsOff) {
		//NJUU-1349
		originalSelect.trigger('change');
		valueField[0].value = originalSelect[0].options[originalSelect[0].selectedIndex].value;
	}


	function decreaseValue() {

		if (showMins.length > 0) {
		    if (showMins.prop("checked")) {
				showMinsOff = false;
			} else {
				showMinsOff = true;
			}
		}

		function hourDec() {
			//Decrement hour
			var decHour = $(originalSelect[0]).parents(".field").find("select.hour").parent().find("a.decrease");
			decHour.click();

		}


		//If this is a minute stepper
		if (minute) {

			if (showMinsOff) {

				//NJUU-1349
				var currentVal = originalSelect[0].selectedIndex;
				incCount = Math.ceil(currentVal / 15) - 1;

				//console.log("DECREMENT: " + incCount);

				if (incCount < 0) {
					incCount = 3;
				}

				if (incCount == 3) {
					hourDec();
				}

				originalSelect[0].selectedIndex = minVals[incCount];

			} else {

				if (originalSelect[0].selectedIndex != 0) {
					originalSelect[0].selectedIndex = originalSelect[0].selectedIndex - 1;

				} else {
					originalSelect[0].selectedIndex = maxValue - 1;
					hourDec();
				}


				var currentVal = originalSelect[0].selectedIndex;
				var nearest = Math.ceil(currentVal / 15);
				incCount = nearest;
				noInc = 1;

			}

		}
		//If this isn't a minute stepper
		else {

			if (originalSelect[0].selectedIndex > 0) {
				originalSelect[0].selectedIndex = originalSelect[0].selectedIndex - 1;

				var amPM = $(originalSelect[0]).parent().parent().find("#depart-time-ampm-");

				//if the hour is 12, then click the "am/pm" box
				if (amPM.length > 0 && originalSelect[0].selectedIndex == 10) {
					amPM.parent().find("a.increase").click();
				}

			} else {
				originalSelect[0].selectedIndex = maxValue - 1;

			}

		}

		originalSelect.trigger('change');
		return originalSelect[0].options[originalSelect[0].selectedIndex].value;

	}

	function increaseValue() {

		if (showMins.length > 0) {
		    if (showMins.prop("checked")) {
				showMinsOff = false;
			} else {
				showMinsOff = true;
			}
		}

		function hourInc() {
			//Increment hour
			var incHour = $(originalSelect[0]).parents(".field").find("select.hour").parent().find("a.increase");
			incHour.click();

		}


		//If this is a minute stepper
		if (minute) {

			if (showMinsOff) {

				//If a user has typed a number, we don't always need to increment
				//NJUU-1349
				var currentVal = originalSelect[0].selectedIndex;
				incCount = Math.floor(currentVal / 15) + 1;

				if (incCount == 4) {
					incCount = 0;

					hourInc();

				}

				if (incCount > 4) {
					incCount = 1;

				}

				originalSelect[0].selectedIndex = minVals[incCount];

				// console.log("minute stepper");

			} else {


				if (originalSelect[0].selectedIndex != maxValue - 1) {
					originalSelect[0].selectedIndex = originalSelect[0].selectedIndex + 1;

				} else {
					originalSelect[0].selectedIndex = 0;

					hourInc();


				}


				var currentVal = originalSelect[0].selectedIndex;
				var nearest = Math.ceil(currentVal / 15);
				incCount = nearest;
				noInc = 1;

			}

		}
		//If this isn't a minute stepper
		else {

			if (originalSelect[0].selectedIndex < 0) {
				originalSelect[0].selectedIndex = 0;
			}
			if (originalSelect[0].selectedIndex != maxValue - 1) {
				originalSelect[0].selectedIndex = originalSelect[0].selectedIndex + 1;

				var amPM = $(originalSelect[0]).parent().parent().find("#depart-time-ampm-");

				//if the hour is 12, then click the "am/pm" box
				if (amPM.length > 0 && originalSelect[0].selectedIndex == 11) {
					amPM.parent().find("a.increase").click();
				}

			} else {
				originalSelect[0].selectedIndex = 0;
			}

		}

		originalSelect.trigger('change');
		return originalSelect[0].options[originalSelect[0].selectedIndex].value;

	}


	function typedValue( $input ) {

		//NJUU-1316 - Work in progress

		var currentValue = $input.val();

		function is( string ){

			return $input.siblings().hasClass(string);

		}

		function isANumber( value ){

			var reg = new RegExp('^[0-9]+$');

			return reg.test( value );

		}

		function setNewValue( newValue ){

			$input.val( newValue );

		}

		if( is("minute") ){

			if( currentValue > 59 || !isANumber( currentValue ) ) {
				setNewValue( 0 );
			}

		} else if( is("hour") ){

			if ( hasAmPm && ( currentValue > 12 && currentValue < 25 ) ) {
				setNewValue( currentValue - 12 );
			} else if ( currentValue >= 24 || !isANumber( currentValue ) || currentValue == 0 ) {
				setNewValue( hasAmPm ? 12 : "00" );
			}

		}


		if (minute) {

			var currentVal = valueField[0].value;
			/*var nearest = Math.ceil(currentVal / 15);
			incCount = nearest;
			console.log("NEAREST: " + nearest);
			noInc = 1;*/

			if (currentVal > 59) {
				currentVal = 0;
			}
			originalSelect[0].selectedIndex = parseInt(currentVal, 10);

		} else {
			var currentVal = valueField[0].value;
			if (hasAmPm) {
				currentVal = currentVal - 1;
			}
			if (hasAmPm && currentVal > 11) {
				currentVal = currentVal - 12;
			}
			originalSelect[0].selectedIndex = parseInt(currentVal, 10);
		}

	}

	increaseButton.bind('click', function (e) {

		e.preventDefault();

		valueField[0].value = increaseValue();

	});

	decreaseButton.bind('click', function (e) {

		e.preventDefault();

		valueField[0].value = decreaseValue();

	});

	valueField.bind('keyup', function (e) {

		var reg = new RegExp('^[0-9]+$');

		if (e.keyCode == 38) {
			//up arrow
			valueField[0].value = increaseValue();
			e.preventDefault();
		} else if (e.keyCode == 40) {
			//down arrow
			valueField[0].value = decreaseValue();
			e.preventDefault();
		} else if (valueField.siblings("select").hasClass("dropoff-ampm") || valueField.siblings("select").hasClass("ampm")) {

			//NJUU-1298 - Date Picker - Meridian edit with typing always returns AM
			if (!valueField[0].value) {
				valueField[0].value = "am";
			}
			var value = valueField[0].value.toLowerCase();
			if (value == "am" || value == "a") {
				originalSelect[0].selectedIndex = 0;
			} else if (value == "pm" || value == "p") {
				originalSelect[0].selectedIndex = 1;
			} else {
				valueField[0].value = "am";
				originalSelect[0].selectedIndex = 0;
			}
		} else {
			setTimeout( function(){
				typedValue( $(e.target) );
			} , 700 );
		}

	});

	function initialise() {
		valueField[0].value = originalSelect[0].options[originalSelect[0].selectedIndex].value;
	}

	initialise();
};

//Sets wrapper height, prevents floating footer
FC.setWrapperHeight = function (_$els) {
	var viewportHeight = $(window).height();
	var docHeight = $('body').height();
	var footerHeight = $('.footer--main').outerHeight();
	var headerHeight = $('.header--main').outerHeight();
	var userbarHeight = $('#userbar').outerHeight();

	var heightToDeduct = (footerHeight + headerHeight) + userbarHeight;

	$('div.wrapper').css('min-height', viewportHeight - heightToDeduct + 'px');
};

//Calls FC.setWrapperHeight upon window resize timer
FC.wrapperHeightResizer = function (_$els) {
	var rtoResize = false;
	$(window).resize(function(){
		if ( rtoResize !== false )
		clearTimeout(rtoResize);
		rtoResize = setTimeout(FC.setWrapperHeight, 200); //200 is time in miliseconds
	});
}

// Function to replace <select> element with CSS-styled equivalent
FC.fancySelectGeneral = function (_$els) {
	var _$body = $('body'),
		_i = _$els.length,
		_a = document.createElement('A'),
		_spanOut = document.createElement('SPAN'),
		_spanIn = document.createElement('SPAN'),
		_availableHeight = $("div.bg") ? $("div.bg").outerHeight() : $(document).height(); /* document's height can't be used as .nj-page has overflow:hidden*/

	// If this is a subsequent init
	// then remove the previously generated fancy markup
	$('.fancy-select-general-inner, .fancy-select-general-ul', _$els).remove();

	_onClickHandler = function (e) {

		var _$sels = $('.fancy-select-general'),
			_$values = $('.fancy-select-general-value'),
			_$uls = $('.fancy-select-general-ul'),
			_ulsLength = _$uls.length,
			_target = $(e.target),
			_par = $(e.target).parents('.fancy-select-general'),
			_$ul = $('.fancy-select-general-ul', _par),
			_$select = $('select', _par),
			_$value = $('.fancy-select-general-value', _par),
			rOpen = /\bopen\b/;

		while (_ulsLength--) {
			_$uls[_ulsLength].className = _$uls[_ulsLength].className.replace(rOpen, "");
		}

		_$values.css('visibility', 'visible');
		_$sels.css('z-index', '10');


		switch (e.target.className) {
			case 'fancy-select-option-redirect':
				return true;
				break;
			case 'fancy-select-general-value':
				if (!rOpen.test(_$ul[0].className)) {
					_$ul[0].className += " open";
					_par.css('z-index', '100');
				} else {
					_$ul[0].className = _$ul[0].className.replace(rOpen, "");
				}
				//_$value.css('visibility', 'hidden');
				break;
			case 'fancy-select-general-option':
				// Copy class name from OPTION to SELECT
				var $span = _target.closest('.fancy-select-general').find('.fancy-select-general-inner');
				if ($span.attr('data-currentclass')) {
					$span.removeClass($span.attr('data-currentclass'))
				}
				$span.addClass(_target.parent()[0].className).attr('data-currentclass', _target.parent()[0].className)


				_$select[0].selectedIndex = $('li', _$ul).index(_target.parent()[0]);
				$(_$select[0]).change();
				//_$select.find("option:eq("+($("a", _par).index(e.target) - 1)+")").attr("selected", "selected");
				_$value[0].innerHTML = e.target.firstChild.nodeValue;
				_$value.css('visibility', 'visible');
				_$value.attr("data-val", $(e.target).attr('data-val'));
				_$ul[0].className = _$ul[0].className.replace(rOpen, "")
				break;
			default:
		}

		return false;
	},
	_bodyClickHandler = function (e) {
		var _$ul = $('.fancy-select-general-ul'),
			_ulLength = _$ul.length,
			_$value = $('.fancy-select-general-value'),
			rOpen = /\bopen\b/;

		switch (e.target.className) {
			case 'fancy-select-value':
				break;
			case 'fancy-select-general-option':
			case 'fancy-select-general-option-redirect':
				break;
			default:
				while (_ulLength--) {
					_$ul[_ulLength].className = _$ul[_ulLength].className.replace(rOpen, "");
				}
				_$value.css('visibility', 'visible');
		}
	};

	_spanOut.className = 'fancy-select-general-inner grad-white-grey';

	_a.href = '#';
	_spanIn.className = 'fancy-select-general-value';

	_a.appendChild(_spanIn);
	_spanOut.appendChild(_a);

	while (_i--) {
		if (_$els.eq(_i).find('span.fancy-select-general-inner').length) {
			continue;
		}

		var _docFrag = document.createDocumentFragment(),
			_$select = $(_$els[_i]).find('select'),
			_$options = $(_$els[_i]).find('option'),
			_length,
			_ul;

		if (_$options.length) {
			_length = _$options.length,
			_ul = document.createElement('UL');
		} else {
			continue;
		}

		_ul.className = 'fancy-select-general-ul';

		for (_j = 0; _j < _length; _j++) {
			var _a = document.createElement('A'),
				_li = document.createElement('LI');


			if (_$select.hasClass("redirect")) {
				_a.href = _$options[_j].value;
				_a.className = 'fancy-select-general-option-redirect';
			} else {
				_a.className = 'fancy-select-general-option';
			}

			if (_$options[_j].className != '') {
				_li.className += _$options[_j].className;
			}

			_a.appendChild(document.createTextNode(_$options[_j].firstChild.nodeValue));

			// set option value in data-val attribute
			$(_a).attr("data-val", $(_$options[_j]).attr("value"));

			_li.appendChild(_a);
			_ul.appendChild(_li);
		}

		//passengers somehow creating selects with no selected index, even though 2 options in it
		//occurs when no lead passenger selected, click 'add catering' and error panel shows
		//then select a lead passenger using lead drop down
		//work around is to set the first option as the selectedindex
		if (_$select[0].selectedIndex < 0) {
			_$select[0].selectedIndex = 0;
		}

		_spanOut.firstChild.firstChild.innerHTML = _$options[_$select[0].selectedIndex].firstChild.nodeValue;

		_docFrag.appendChild(_spanOut.cloneNode(true));
		_docFrag.appendChild(_ul);
		_$els[_i].appendChild(_docFrag);

		// Copy selected OPTION's classname to SELECT
		if (_$options[_$select[0].selectedIndex].className != '') {
			$(_$els[_i]).find(".fancy-select-general-inner")
				.addClass(_$options[_$select[0].selectedIndex].className)
				.attr('data-currentclass', _$options[_$select[0].selectedIndex].className)
		}

		/*
		_select_top = $(_$els[_i]).find(".fancy-select-general-inner").offset().top;
		_select_height = $(_$els[_i]).find(".fancy-select-general-inner").height();
		_options_height = $(_$els[_i]).find(".fancy-select-general-ul").height();

		if ((_select_top + _select_height + _options_height) > _availableHeight) {
		_options_height > 200 ? $(_$els[_i]).find(".fancy-select-general-ul").css("top", _options_height) : $(_$els[_i]).find(".fancy-select-general-ul").css("top", -_options_height);
		}
		*/
	}

	_$els.unbind('click').bind('click', _onClickHandler);
	_$body.bind('click', _bodyClickHandler);


	//handle up and down keys
	_keyPressHandler = function (e) {
		var _$sels = $('.fancy-select-general'),
			_$values = $('.fancy-select-general-value'),
			_$uls = $('.fancy-select-general-ul'),
			_ulsLength = _$uls.length,
			_par = $(e.target).parents('.fancy-general-select'),
			_$ul = $('.fancy-select-general-ul', _par),
			_$select = $('select', _par),
			_$value = $('.fancy-select-general-value', _par);

		//when keys are pressed
		var keycode = e.keyCode;
		_$selected = _$select.find("option:selected");
		_selectedIndex = (_$selected[0] == undefined) ? 0 : _$selected[0].index;
		_max = _$select.find("option").length;
		switch (keycode) {
			case 40:
				//down
			case 39:
				//right
				current = _selectedIndex;
				current = current + 1;
				if (current >= _max) return false;
				_$select.find("option:eq(" + current + ")").attr("selected", "selected");
				//console.log(current);
				_$value[0].innerHTML = _$select.find("option:eq(" + current + ")").get(0).firstChild.nodeValue;
				_$value.css('visibility', 'visible');
				return false;
				break;
			case 38:
				//up
			case 37:
				//left
				current = _selectedIndex;
				current = current - 1;
				if (current < 0) return false;
				_$select.find("option:eq(" + current + ")").attr("selected", "selected");
				_$value[0].innerHTML = _$select.find("option:eq(" + current + ")").get(0).firstChild.nodeValue;
				_$value.css('visibility', 'visible');
				return false;
				break;
			case 33:
				//page up
			case 36:
				//home
				_$select.find("option:eq(0)").attr("selected", "selected");
				_$value[0].innerHTML = _$select.find("option:eq(0)").get(0).firstChild.nodeValue;
				return false;
				break;
			case 34:
				//page down
			case 35:
				//end
				_$select.find("option:eq(" + (_max - 1) + ")").attr("selected", "selected");
				_$value[0].innerHTML = _$select.find("option:eq(" + (_max - 1) + ")").get(0).firstChild.nodeValue;
				return false;
				break;
			case 13:
				//enter
				if (_$select.hasClass('redirect')) {
					location.href = _$selected.val();
					return true;
				}
				return false;
				break;
			case 27:
				//escape
				return false;
				break;
		}
	}
	_$els.unbind('keydown').bind('keydown', _keyPressHandler);
};

// Validates date inputs
FC.isDate = function (dateStr, testYear) {
	var dateObj;
	var dateStamp;
	var day;
	var month;
	var year;
	var dateRegex;

	// Set regex pattern based to test for year or not.
	if (testYear === undefined || testYear == true) {
		testYear = true;
		dateRegex = /^([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{4})$/.exec(dateStr);
	} else {
		testYear = false;
		dateRegex = /^([0-9]{1,2})\/([0-9]{1,2})$/.exec(dateStr);
	}

	// Validate string.
	if (dateRegex == null) {
		return false;
	}

	// Get day, month, and year if testYear selected (or by default).
	month = parseInt(dateRegex[1], 10) - 1; // Subtract 1 because JS dates are 0-11.
	day = parseInt(dateRegex[2], 10);
	if (testYear) {
		year = parseInt(dateRegex[3], 10);
	} else {
		year = 1999; // This is arbitrary so long as it isn't a leap year.
	}

	if (year < 1920) {
		return false;
	}
	// Create dateObj.
	dateStamp = (new Date(year, month, day)).getTime();
	dateObj = new Date();
	dateObj.setTime(dateStamp);

	// Validate date.
	if (dateObj.getMonth() !== month || dateObj.getDate() !== day || dateObj.getFullYear() !== year) {
		return false;
	}

	return true;
};

/* this one used for constructing the aircraft edit accordion */
FC.testAcc = function ($el) {


	/*var items = [],
	activeItem,
	openFirst = false,
	self = this;


	self.addItem = function (item) {
	self.initialiseItem(item);
	// if the item has the class active on load, then open it up and set it as the active item
	if ($(item).hasClass('active') || $(item).hasClass('newly-added')) {
	self.setActiveItem(item);
	self.openItem(item);
	}
	//else {
	//self.closeItem(item); // otherwise close it
	//}

	//self.setActiveItem(item);
	};

	self.removeItem = function (elem) {
	items = $.map(items, function (item) {
	return item === elem ? false : item;
	});
	};

	self.openItem = function (item) {
	item.contentWrapper.slideDown('fast', function () {
	item.contentInner.animate({
	'opacity': 1
	});
	item.addClass('open active');
	self.setActiveItem(item);
	});
	};

	self.closeItem = function (item, callback) {
	$(item).find('.flight-acc-content-inner').animate({
	'opacity': 0
	}, 200, function () {
	$(item).find('.flight-acc-content-inner').slideUp(200);
	item.removeClass('open active');
	if (callback) {
	callback();
	}
	});
	};

	self.setActiveItem = function (item) {
	activeItem = item;
	};

	self.initialiseItem = function (item, i) {

	item.header = item.find('div.flight-acc-head');
	item.contentWrapper = item.find('div.flight-acc-content-wrapper');
	item.contentInner = item.contentWrapper.find('div.flight-acc-content-inner');

	item.header.bind('click', function () {
	if (item.hasClass('open')) {
	self.closeItem(item);
	} else {
	self.closeItem(activeItem, function () {
	self.openItem(item);
	});
	}
	});

	items.push(item);
	};
	self.openFirstItem = function () {
	console.info('need to open first item');
	}*/

	/* $el.find('li').each(function (i) {

	self.addItem($(this), i);

	if (i == $el.find('>li').length - 1) {
	//if this instance of the accordion is to start with the first item
	//and we have added some items already (by checking length of items)
	//then open the first one
	self.openItem(items[0]);
	self.setActiveItem(items[0]);

	} else {
	if (!activeItem) {
	console.info(items);
	self.openItem(items[0]);
	self.setActiveItem(items[0]);
	}

	}
	});*/

};

/* being called from catering.js */
FC.flightAccordion = function ($el, aF) {

	var flightList = $el,
		flightListItems = $el.find('li'),
		flightHeader = $(FC.vars.selectors.FLIGHT_ACC_HEADER),
		flightContentOuter = $(FC.vars.selectors.FLIGHT_ACC_CONTENT_WRAPPER),
		flightContentInner = $(FC.vars.selectors.FLIGHT_ACC_CONTENT_INNER),
		activeFlight = aF,
		thisFlight;

	//flightContentOuter.slideUp(1);
	//flightContentInner.css('opacity', 0);

	//activeFlight = flightListItems.filter('[class="open"]') || flightHeader.filter(':first');
	//activeFlight = flightHeader.filter(':first');

	//flightList.find(">li.panel .flight-acc-head").trigger("click");

	/*.each(function(index, el){
	$(this).find(".flight-acc-head").trigger("click");
	});*/

	/*setTimeout(function(){
	flightList.find(">li.panel .flight").eq(0).trigger("click");
	setTimeout(function(){
	flightList.find(">li.panel .flight").eq(1).trigger("click");
	},5000);
	},5000);*/


	this.closeActive = function () {
		flightContentOuter = activeFlight.next($(FC.vars.selectors.FLIGHT_ACC_CONTENT_WRAPPER));
		flightContentInner = flightContentOuter.find($(FC.vars.selectors.FLIGHT_ACC_CONTENT_INNER));

		/*flightContentInner.animate({
		opacity: 0
		}, 200, function () {
		flightContentOuter.slideUp('fast', function () {
		activeFlight.removeClass('open');
		});
		});*/
	};

	var openFlight = function (clickedFlight) {
		flightContentOuter = clickedFlight.children($(FC.vars.selectors.FLIGHT_ACC_CONTENT_WRAPPER));
		flightContentInner = flightContentOuter.children($(FC.vars.selectors.FLIGHT_ACC_CONTENT_INNER));
		flightContentOuter.slideDown('fast', function () {
			flightContentInner.animate({
				'opacity': 1
			});
		});
		clickedFlight.addClass('open active');
		activeFlight = clickedFlight;
	};

	var flightHeaderClickHandler = function (activeFlight, clickedFlight) {
		flightContentOuter = activeFlight.next($(FC.vars.selectors.FLIGHT_ACC_CONTENT_WRAPPER));
		flightContentInner = flightContentOuer.find($(FC.vars.selectors.FLIGHT_ACC_CONTENT_INNER));

		flightContentInner.animate({
			opacity: 0
		}, 200, function () {
			flightContentOuter.slideUp('fast', function () {
				openFlight(clickedFlight);
				activeFlight.removeClass('open').removeClass('active');
			});
		});
	};

	/*flightHeader.each(function () {
	$(this).bind('click', function () {
	thisFlight = $(this);
	flightHeaderClickHandler(activeFlight, thisFlight);
	//return false;
	});
	});*/

	openFlight(activeFlight);
};

//Temporary accordian for confirmation page
FC.requestFlightHeader = function ($el) {
	var flightHead = $el;
	var flightHeadL = flightHead.length;

	function setHeaderTitle(header, isCollapsed) {
		header.attr("title", isCollapsed ? "Click to expand flight request" : "Click to collapse flight request");
	}

	function collapseFlight(flightHeader, duration) {
		if (!flightHeader || !flightHeader.length) { return; }
		var par = flightHeader.parent(),
			details = par.find(".flight-details");
		if (details.length == 0) { return; }
		if (!duration) {
			duration = 600;
		}
		par.removeClass("open");
		par.addClass("closed");
		details.slideUp(duration, function() { setHeaderTitle(flightHeader, false); });
	}

	function expandFlight(flightHeader, duration) {
		if (!flightHeader || !flightHeader.length) { return; }
		var par = flightHeader.parent(),
			details = par.find(".flight-details");
		if (details.length == 0) { return; }
		if (!duration) {
			duration = 600;
		}
		par.removeClass("closed");
		par.addClass("open");
		details.slideDown(duration, function() {setHeaderTitle(flightHeader, true); });
	}

	for (i = 0; i < flightHeadL; i++) {
		var flightHeader = $(flightHead[i]),
			par = flightHeader.parent(),
			detailsHeight = par.find(".flight-details").height();
		par.find(".flight-details").attr("data-height", detailsHeight);
		if (par.hasClass("closed")) {
			collapseFlight(flightHeader);
		}else {
			setHeaderTitle(flightHeader, false);
		}
	}


	flightHead.bind("mouseover", function () {
		$(this).addClass("flight-head-over");
	});


	flightHead.bind("mouseout", function () {
		$(this).removeClass("flight-head-over");
	});


	flightHead.bind("click", function (e) {
		var flightHeader = $(e.target).parents(".flight-head"),
			par = flightHeader.parent();
		if (par.length == 0 || $(e.target).hasClass('cancel')) {
			return true;
		}
		if (par.hasClass("closed")) {
			expandFlight(flightHeader, 600);
		} else {
			collapseFlight(flightHeader, 600);
		}
	});

};


FC.checkboxes = function ($el) {

	/*var inputs = $el.parent().find("input[type='checkbox']");
	inputs.attr("checked", false);

	$el.bind("click", function () {

	var inp = $(this).find("input[type='checkbox']");

	alert(inp.attr("checked"));

	if (inp.attr("selected")) {

	$(this).removeClass("on");

	}
	else {

	$(this).addClass("on");

	}

	});*/

};


FC.externalLink = function (els) {
	els.each(function () {
		$(this).attr('target', '_blank');
	});

	$(els).unbind("click").bind("click", function(e) {
		window.open($(this)[0].href);
		e.preventDefault();
	});
};


//** Animating background (clouds)
FC.cloudBG = function ($elem) {

	var clouds = $elem.find("img");

	var ltIE8 = $("html.lt-ie9").length;


	function animate() {

		clouds.animate({ "margin-left": "-500px" }, 0);

		//If this isn't IE8 or below
		if (ltIE8 == 0) {

			clouds.animate({ opacity: 0 }, 0);

			clouds.animate({ opacity: 1, "margin-left": "-300px" }, 8000, 'linear', function () {
				clouds.animate({ "margin-left": "1000px" }, 40000, 'linear', function () {

					clouds.animate({ opacity: 0, "margin-left": "1300px" }, 8000, 'linear', function () { animate(); });

				});
			});

		} else {

			clouds.animate({ "margin-left": "1300px" }, 52000, 'linear', function () {

				animate();

			});
		}


	}

	animate();
};

FC.fancyCheckboxes = function ($els) {

	function fancyCheckboxClickHandler(checkbox) {

		var label = checkbox.next('label');

		if (checkbox.attr('disabled') != undefined) {
			return false;
		}
		if (checkbox.prop('checked')) {
			label.addClass('fancy-checked');
		} else {
			label.removeClass('fancy-checked');
		}
	}


	$els.each(function () {
		var currentCheckbox = $(this);

		if (currentCheckbox.attr('disabled') != undefined) {
			currentCheckbox.addClass('fancy-disabled');
			currentCheckbox.next('label').addClass('fancy-disabled');
		}

		currentCheckbox.bind('click', function () {
			fancyCheckboxClickHandler(currentCheckbox);
			return true;
		});
	});
};


FC.furtherInstructions = function ($el) {
	var originalOverlay = $('div.further-instructions-modal'),
		overlay,
		select,
		overlaySaveButton,
		overlayCancelButton;

	if (!$('body > div.further-instructions-modal').length) {
		overlay = originalOverlay.clone();
		originalOverlay.remove();
		$('body').append(overlay);
	}

	overlay = $('body').find('div.further-instructions-modal');

	function saveOverlayHandler() {
		FC.closeModal(overlay);
		return false;
	}

	function closeOverlayHandler() {
		overlay.find('input').val($(this).attr('placeholder'));
		FC.hideModal(overlay);
		return false;
	}

	function showOverlay() {
		FC.showModal(overlay, overlay.width(), overlay.height(), true);
		return false;
	}

	function selectChangeHandler() {
		if (select.val() == 'another-number') {
			showOverlay();
		}
	}

	function init() {
		overlaySaveButton = overlay.find('li.confirm a');
		overlayCancelButton = overlay.find('li.cancel a');
		select = $el.find('select');

		select.bind('change', selectChangeHandler);
		overlaySaveButton.bind('click', saveOverlayHandler);
		overlayCancelButton.bind('click', closeOverlayHandler);
	}


	init();
};

FC.expander = function ($el, options) {
	var self = this,
		itemArr = [],
		rootElement = $el,
		activeItem,
		openFirst = true;
	if (options) {
		openFirst = options.openFirst;
	}

	self.closeItem = function (item, callback) {
		item.content.slideUp(200, function () {
			if (callback) {
				callback();
				item.removeClass('open');
			} else {
				item.removeClass('open');
			}
		});

	};

	self.openItem = function (item) {
		item.content.slideDown(200);
		item.addClass('open');
	};

	self.addItem = function (item, open) {
		self.initialiseItem(item);

		if (open) {
			self.openItem(item);
		}
		self.setActiveItem(item);
	}

	self.setActiveItem = function (item) {
		activeItem = item;
	};

	self.initialiseItem = function (item) {
		item.header = item.find('.expander-trigger');
		item.trigger = item.header.find('a.trigger');
		item.content = item.find('div.expander-content');

		item.trigger.unbind('click').bind('click', function () {
			if (item.hasClass('open')) {
				self.closeItem(item);
			} else {
				self.openItem(item);
			}
			return false;
		});

		if (openFirst) {
			//if this instance of the expander is to start with the first item
			//open, we need to close all items when they are initialised
			item.content.slideUp(1);
		}

		itemArr.push(item);
	};

	this.initiate = function () {
		items = rootElement.find('.expander-item');

		items.each(function (i) {
			self.addItem($(this));

			if (openFirst && items.length >= 1) {
				self.openItem(itemArr[0]);
				self.setActiveItem(itemArr[0]);
			}
		});
	};

	this.initiate();
};

//Function to make the footer anchor to the window on short pages
FC.footer = function ($el) {

	//Find the window size
	var winH = $(window).height();

	//Find the content size
	var bodyH = $("body").height();

	//If the content is less than the window size, then add a class to anchor the footer to the window
	if (bodyH < winH) {
		$el.addClass("alt");
	}


};


//Function for login panels to auto focus onto fields when returning an error
FC.loginPanel = function ($el) {

};




//Function for checking session expiration
FC.sessionExpired = function (func) {

	var sessionCheck;

	$.ajax({
		url: "/Authenticate/SessionTimedOut",
		type: 'get',
		contentType: "application/json; charset=utf-8",
		success: function (data) {

			FC.vars.sessionExpired = data;

			if (FC.vars.sessionExpired == true) {

				document.location.href = "/Account/Authenticate/LogOn?expired=true";

			} else {

				func();

			}

		},
		error: function () {

			document.location.href = "/Account/Authenticate/LogOn?expired=true";

		}
	});

};


FC.simulatePlaceholderText = function($fields) {

	var form = $('form'),
		nativeSupport = "placeholder" in document.createElement("input"),
		addMultilineSupport = true;

	$fields.filter(':input[placeholder]').not(':password').each(function() {
		if(!nativeSupport) {
			setupPlaceholder($(this));
		} else {
			$(this).val("");
		}
		// Native placeholders doesn't support multiline
		if(nativeSupport & this.tagName == 'TEXTAREA' && addMultilineSupport) {
			setupPlaceholder($(this));
			$(this).removeAttr('placeholder');
		}
	});

	$fields.filter(':password[placeholder]', $fields).each(function () {
		setupPasswords($(this));
	});

	form.on('submit', function(e) {
		clearPlaceholdersBeforeSubmit($(this));
	});

	function setupPlaceholder($field) {
		var placeholderText = $field.attr('placeholder');

		// Reset field after page refresh
		if($field.val() === placeholderText) {
			$field.val('');
		}

		($field.val() === '') ? $field.val(placeholderText).addClass('placeholder-style') : $field.data('changed', true)

		$field.off('*')
			.off('focus').on('focus', function(e) {
				$field.removeClass('placeholder-style');
				if ($field.data('changed') === true && $field.val() != placeholderText) {
					$field.select();
					return;
				}
				if ($field.val() === placeholderText) {
					$field.val('').select();
				}
			})
			.off('blur').on('blur', function(e) {
				if ($field.val() === '') {
					$field.val(placeholderText);
				}
				 refreshStyle($field);
			})
			.off('change.placeholder').on('change.placeholder', function(e) {
				$field.data('changed', $field.val() !== '');
				refreshStyle($field);
			});
	}

	function refreshStyle($field) {
		if($field.val() === '' || $field.val() === $field.attr('placeholder')) {
			$field.addClass('placeholder-style');
		}
		else {
			$field.removeClass('placeholder-style');
		}
	}

	function setupPasswords($field) {
		var passwordPlaceholder = createPasswordPlaceholder($field);
		$field.after(passwordPlaceholder);

		($field.val() === '') ? $field.hide() : passwordPlaceholder.hide();

		$($field).blur(function(e) {
			if ($field.val() !== '') return;
			$field.hide();
			passwordPlaceholder.show();
		});

		$(passwordPlaceholder).focus(function(e) {
			$field.show().focus();
			passwordPlaceholder.hide();
		});
	}

	function createPasswordPlaceholder($field) {
		return $('<input>').attr({
			placeholder: $field.attr('placeholder'),
			value: $field.attr('placeholder'),
			id: $field.attr('id'),
			readonly: true
		}).addClass($field.attr('class'));
	}

	function clearPlaceholdersBeforeSubmit($form) {
		$form.find(':input[placeholder]').each(function() {
			if ($(this).data('changed') === true) return;
			if ($(this).val() === $(this).attr('placeholder')) $(this).val('');
		});
	}

};

//Generic function for clearing the default value of a field
FC.emptyFields = function ($el) {

	var element = $el;

	for (i = 0; i < element.length; i++) {
		$(element[i]).attr("data-default", element[i].defaultValue);
	}

	element.bind("focus", function () {

		$(this).select();

		var val = $(this).attr("value") || $(this).val();
		if (val == $(this).attr("data-default")) {
			$(this).attr("value", "");
			$(this).removeClass("placeholder");
		}
	});


	element.bind("blur", function () {
		var val = $(this).attr("value") || $(this).val();
		if (val == "") {

			if ($(this).attr("data-default") == "") {

				if ($(this).hasClass("departure-airport")) {
					$(this).attr("value", "From (airport or city)");
					$(this).attr("data-default", "From (airport or city)");
				}
				if ($(this).hasClass("arrival-airport")) {
					$(this).attr("value", "To (airport or city)");
					$(this).attr("data-default", "To (airport or city)");
				}

			}
			else {
				$(this).attr("value", $(this).attr("data-default"));
			}

			$(this).addClass("placeholder");

		}
	});

};

FC.TrackOutBoundLinkAndPdf = function ($elem) {
	$elem.on('click.outbound', function (event) {
		var href = $(this).attr('href'),
			target = $(this).attr("target");

		if (href == null)
			return;
		if (href.indexOf('http://') != -1 && href.toLowerCase().indexOf('.pdf') < 0) {
			if (ga) {
				ga('send', 'event', 'Exit Links', 'Link Clicked', href);
				if (target != "_blank") {
					event.preventDefault();
					setTimeout('document.location = "' + href + '"', 100);
				}
			}
		}
		else if (href.toLowerCase().indexOf('.pdf') >= 0) {
			if (ga) {
				ga('send', 'event', 'Downloads', 'PDF', href);
				event.preventDefault();
				setTimeout('document.location = "' + href + '"', 100);
			}
		}
		else if (href.toLowerCase().indexOf('mailto:') >= 0) {
			if (ga) {
				ga('send', 'event', 'Emails', 'Email opened', href);
				event.preventDefault();
				setTimeout('document.location = "' + href + '"', 100);
			}
		}
	});
};
FC.flightTracking = function ($sel){
	var originalFlightTrackingOverlay = $('div.flight-tracking.modal-window'),
		flightTrackingOverlay,
		overlaySaveButton,
		overlayCancelButton,
		currentFlight,
		reservationNumber = $(".flight-numbers .reservation"),
		currentData,
		dataSend;

	if (!$('body > div.flight-tracking.modal-window').length) {
		flightTrackingOverlay = originalFlightTrackingOverlay.clone();
		originalFlightTrackingOverlay.remove();
		$('body').append(flightTrackingOverlay);
	}

	flightTrackingOverlay = $('body').find('div.flight-tracking.modal-window');

	$(".view-flight-progress").unbind("click").bind("click", function(e){
		e.preventDefault();
		e.stopPropagation();
		FC.showLoading();
		currentFlight = JSON.parse($(this).parents('li').attr("data-flight"));
		$(".flight-numbers .reservation").html(currentFlight.ReservationID);
		$(".flight-numbers .flightNo").html(currentFlight.FlightId);
		$(".flight-numbers .tailNo").html(currentFlight.TailNumber);

		dataSend = {
					"reservationId": currentFlight.ReservationID,
					"flightId": currentFlight.FlightId,
					"callSign": currentFlight.CallSign,
					"imageWidth": "940",
					"imageHeight": "410"
				}

		getFlightDetails($(e.target).closest("li[data-flight]"));
	});

	function getFlightDetails( $flight ){

		var $errors = $(".errors-list");

		$.ajax({
			url: "/Book/FlightTracking/GetDetails",
			data: dataSend,
			type: 'GET',
			dataType: 'json',
			contentType: "application/json; charset=utf-8",
			success: function (data) {
				if (data.SessionExpired == false) {
					if(data.HasError){
						$errors.show().empty().append("<p class='alert alert-danger'>" + data.ErrorDescription + "</p>");

						$flight.prepend($errors);

						FC.removeLoading($(".curtain"));
					} else {
						$errors.hide();
						currentData = data;
						setupFlightTrackingModal(data);
					}
				} else {
					document.location.href = data.RedirectUrl;
				}
			}
		});


	}

	$(flightTrackingOverlay).find(".close-modal").unbind("click").bind("click", function(e){
		e.preventDefault();
		FC.hideModal(flightTrackingOverlay);
	});

	$(flightTrackingOverlay).find(".refresh-flight-details").unbind("click").bind("click", function(e){
		e.preventDefault();
		getFlightDetails();
	})

	function initializeMap(aircraftLoc, departureAirport, arrivalAirport, bearing) {
		var mapOptions = {
			center: new google.maps.LatLng(departureAirport.Location.Latitude, departureAirport.Location.Longitude),
			mapTypeId: google.maps.MapTypeId.TERRAIN,
			mapTypeControl: false
		};
		trackingMap = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
		google.maps.event.trigger(trackingMap, 'resize');
		var bounds = new google.maps.LatLngBounds();


		var imageSize = new google.maps.Size(37, 56);
		var imageOrigin = new google.maps.Point(0, 0);

		var imageAnchor = new google.maps.Point(19, 47);

		// infobox overlay
		var xOffset = -210;
		var yOffset = -10;

		var deptState, arriveState, openInfoBox, currentMarker;

		if (departureAirport.State != null) {
			deptState = ", " + departureAirport.State;
		} else {
			deptState = "";
		}

		if (arrivalAirport.State != null) {
			arriveState = ", " + arrivalAirport.State;
		} else {
			arriveState = "";
		}


		var departLatLon = new google.maps.LatLng(departureAirport.Location.Latitude, departureAirport.Location.Longitude);
		var boxText = "<div class='box-title'>" + departureAirport.Code + " (" + departureAirport.City.toLowerCase() + deptState + ")</div><div class='small-text'><span>" + departureAirport.Name.toLowerCase() + "</span></div>";
		bounds.extend(departLatLon);
		var departImage = "/Resources/images/icons/airport-map-icon.png";
		var departIconImage = {
			url: departImage,
			size: imageSize,
			origin: imageOrigin,
			anchor: imageAnchor
		};
		var departMarker = new google.maps.Marker({
			position: departLatLon,
			map: trackingMap,
			icon: departIconImage
		});
		var departBoxOptions = {
					content: boxText
						, disableAutoPan: false
						, maxWidth: 0
						, pixelOffset: new google.maps.Size(xOffset, yOffset)
						, zIndex: null
						, alignBottom: true
						, closeBoxURL: "/resources/images/icons/info-box-close-white-cross.jpg"
						, infoBoxClearance: new google.maps.Size(1, 1)
						, isHidden: false
						, pane: "floatPane"
						, enableEventPropagation: false
						, boxClass: "infoBox flight-tracking-info-box"
				};
		var departIB = new InfoBox(departBoxOptions);

		google.maps.event.addListener(departMarker, 'click', (function (departMarker, departIB) {
					return function () {
						//If another InfoBox is open then close it.
						if (openInfoBox) {
							openInfoBox.close();
						}
						departIB.open(trackingMap, departMarker);
						openInfoBox = departIB;
						currentMarker = departMarker;
					};
				})(departMarker, departIB));

		var arriveLatLon = new google.maps.LatLng(arrivalAirport.Location.Latitude, arrivalAirport.Location.Longitude);
		var arriveboxText = "<div class='box-title'>" + arrivalAirport.Code + " (" + arrivalAirport.City.toLowerCase() + arriveState + ")</div><div class='small-text'><span>" + arrivalAirport.Name.toLowerCase() + "</span></div>";
		bounds.extend(arriveLatLon);
		var arriveImage = "/Resources/images/icons/airport-map-icon-arrival.png";
		var arriveIconImage = {
			url: arriveImage,
			size: imageSize,
			origin: imageOrigin,
			anchor: imageAnchor
		};
		var arriveMarker = new google.maps.Marker({
			position: arriveLatLon,
			map: trackingMap,
			icon: arriveIconImage
		});

		var arriveBoxOptions = {
					content: arriveboxText
						, disableAutoPan: false
						, maxWidth: 0
						, pixelOffset: new google.maps.Size(xOffset, yOffset)
						, zIndex: null
						, alignBottom: true
						, closeBoxURL: "/resources/images/icons/info-box-close-white-cross.jpg"
						, infoBoxClearance: new google.maps.Size(1, 1)
						, isHidden: false
						, pane: "floatPane"
						, enableEventPropagation: false
						, boxClass: "infoBox flight-tracking-info-box"
				};
		var arriveIB = new InfoBox(arriveBoxOptions);

		google.maps.event.addListener(arriveMarker, 'click', (function (arriveMarker, arriveIB) {
					return function () {
						//If another InfoBox is open then close it.
						if (openInfoBox) {
							openInfoBox.close();
						}
						arriveIB.open(trackingMap, arriveMarker);
						openInfoBox = arriveIB;
						currentMarker = arriveMarker;
					};
				})(arriveMarker, arriveIB));


		var planeLatLon = new google.maps.LatLng(aircraftLoc.Latitude, aircraftLoc.Longitude);
		bounds.extend(planeLatLon);
		var planeImage = "/Resources/images/icons/planeCompass/planemarker"+bearing+".png";
		var planeImageSize = new google.maps.Size(40, 40);
		var planeImageOrigin = new google.maps.Point(0, 0);
		var planeImageAnchor = new google.maps.Point(20, 20);
		var planeIconImage = {
			url: planeImage,
			size: planeImageSize,
			origin: planeImageOrigin,
			anchor: planeImageAnchor
		};
		var planeMarker = new google.maps.Marker({
			position: planeLatLon,
			map: trackingMap,
			icon: planeIconImage
		});

		trackingMap.fitBounds(bounds);


		var lineCoordinates = [
			new google.maps.LatLng(departureAirport.Location.Latitude, departureAirport.Location.Longitude),
			new google.maps.LatLng(aircraftLoc.Latitude, aircraftLoc.Longitude)
		  ];

		  var lineSymbol = {
			path: 'M 0,-1 0,1',
			strokeOpacity: 1,
			scale: 4
		  };

		  var line = new google.maps.Polyline({
			path: lineCoordinates,
			strokeOpacity:1,
			strokeWeight:4,
			strokeColor:"#002d5d",
			map: trackingMap
		  });


		  var togolineCoordinates = [
			new google.maps.LatLng(aircraftLoc.Latitude, aircraftLoc.Longitude),
			new google.maps.LatLng(arrivalAirport.Location.Latitude, arrivalAirport.Location.Longitude)
		  ];

		  var lineSymbol = {
			path: 'M 0,-1 0,1',
			strokeColor:"#002d5d",
			strokeOpacity: 1,
			scale: 4
		  };

		  var arriveline = new google.maps.Polyline({
			path: togolineCoordinates,
			strokeOpacity:0,
			icons: [{
			  icon: lineSymbol,
			  offset: '0',
			  repeat: '20px'
			}],
			map: trackingMap
		  });

	}

	function setupFlightTrackingModal(flight) {
		//Get elements to be populated.
		var flightTrackingModal = $("#flight-tracking"),
		journeydetails = flightTrackingModal.find("#journey-details"),
		distanceRemaining = journeydetails.find(".distance-remaining span"),
		timeRemainingModule = journeydetails.find(".time-remaining")
		timeRemaining = journeydetails.find(".time-remaining span"),
		currentSpeed = journeydetails.find(".current-speed span"),
		currentAltitude = journeydetails.find(".current-altitude span"),
		weatherDesc = flightTrackingModal.find(".weather-area .temparature span.weatherDesc"),
		weatherTemp = flightTrackingModal.find(".weather-area .temparature span.numbers"),
		weatherWind = flightTrackingModal.find(".weather-area .winds span.numbers"),
		weatherWindDirection = flightTrackingModal.find(".weather-area .winds span.wind-direction"),
		weatherIcon = flightTrackingModal.find(".weather-icon");

		var departureArea = flightTrackingModal.find(".departure"),
		departureCode = departureArea.find("span.code"),
		departureAirport = departureArea.find("span.airport"),
		departureTime = departureArea.find(".scheduledTime");
		departureActualTime = departureArea.find(".departure-status");

		var arrivalArea = flightTrackingModal.find(".arrival"),
		arrivalCode = arrivalArea.find("span.code"),
		arrivalAirport = arrivalArea.find("span.airport"),
		arrivalTime = arrivalArea.find(".scheduledTime"),
		arrivalEstTime = arrivalArea.find(".arrival-status");

		var mainImage = flightTrackingModal.find(".map-image");


		//populate elements with data from flight object

		var planeLoc = {"Longitude": parseFloat(flight.Longitude), "Latitude": parseFloat(flight.Latitude)}
		//var planeLoc = {"Longitude": -77.808609, "Latitude": 40.552238}

		var bearing = flight.Bearing;
		FC.removeLoading(false);
		FC.showModal(flightTrackingOverlay, flightTrackingOverlay.width(), flightTrackingOverlay.height(), false);
		initializeMap(planeLoc, flight.Flight.DepartureAirport, flight.Flight.ArrivalAirport, bearing);
		distanceRemaining.html(flight.Distance);
		// we need to hide this module from user if data is falsy
		if( flight.TimeRemainingMinutes >= 0 ){
			timeRemainingModule.show();
			timeRemaining.html(flight.TimeRemainingMinutes);
		} else {
			timeRemainingModule.hide();
		}
		currentSpeed.html(flight.Speed);
		currentAltitude.html(FC.numberWithCommas(flight.Altitude));
		weatherTemp.html(flight.DestinationTemperature + "&deg;");
		weatherDesc.html(flight.DestinationWeatherDesc);
		weatherWind.html(flight.DestinationWindSpeed);
		weatherWindDirection.html(flight.DestinationWindDirection)
		weatherIcon.removeClass().addClass("weather-icon").addClass(FC.getWeatherIconClass(flight.DestinationWeatherDesc));

		departureCode.html(flight.Flight.DepartureAirport.Code);
		departureAirport.html(flight.Flight.DepartureAirport.Name);
		departureTime.html(FC.formatDateForFlightTracking(flight.Flight.RequestedDepartureTime || flight.Flight.DepartureTime));
		departureActualTime.html("Departed "+flight.Flight.ActualDepartureString.substring(10).toLowerCase());


		arrivalCode.html(flight.Flight.ArrivalAirport.Code);
		arrivalAirport.html(flight.Flight.ArrivalAirport.Name);
		arrivalTime.html(FC.formatDateForFlightTracking(flight.Flight.RequestedArrivalTime || flight.Flight.ArrivalTime));
		arrivalEstTime.html("Expected "+flight.Flight.EstimatedArrivalString.substring(10).toLowerCase());


	}
}
FC.AddAntiForgeryToken = function (request) {
	request.setRequestHeader("__RequestVerificationToken", $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val());
};

FC.GenerateGATaggingForHome = function ($items) {
	$items.on('click.outbound',function () {
	    var id = $(this).attr('id');
		if (ga) {
		    switch (id) {
		    case "submitted":
		        ga('send', 'pageview', '/Home/SubmittedFlights');
		        break;
		    case "drafts":
		        ga('send', 'pageview', '/Home/DraftReservations');
		        break;
            case "past-flights":
                ga('send', 'pageview', '/Home/PastFlights');
                break;
            default:
                break;
            }
		}
	});

};
FC.hideSafariAddressBar = function () {
	window.scrollTo(0, 1);
	window.scrollTo(0, 0);
};


FC.displayFormattedDate = function( obj ){

	var dayName   = obj.dayName,
		dateNum   = obj.dateNum,
		monthName = obj.monthName,
		yearNum   = obj.yearNum;

	return dayName + " " + dateNum + " " + monthName + " " + yearNum;

};

FC.displayPPD = function(flight) {
	if (!flight || !flight.IsFlyingDuringPeakPeriod) {
		return "";
	}
	return "<br /><span class='peakday' title='Traveling on Peak Period Day'></span><span class='peakday-text'>Peak Period Day</span>";
};

FC.numberWithCommas = function(x) {
	if(!x){
		return 0;
	}
	return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

FC.formatDateForFlightTracking = function(timeObject){
	var amorpm;
	if(timeObject.IsAM){
		amorpm = "am";
	} else {
		amorpm = "pm";
	}

	var timeString = '<span class="day">'+timeObject.Hours+':'+timeObject.Minutes+'</span> <span class="suffix">'+amorpm+'</span><span>, '+timeObject.WeekDay + " " + timeObject.Day + " " + timeObject.Month + " " + timeObject.Year +' </span>';
	return timeString;
}

FC.getWeatherIconClass = function(weatherDescription){
	var weatherClass;
	switch(weatherDescription){
		case "Mostly Cloudy":
			weatherClass = "mostly-cloudy";
			break;
		case "Clear":
			weatherClass = "weather-clear";
			break;
		case "Partly Cloudy":
			weatherClass = "partly-cloudy";
			break;
		case "Overcast":
			weatherClass = "overcast";
			break;
		case "Rain":
			weatherClass = "rain";
			break;
		case "Thunderstorms":
			weatherClass = "thunderstorms";
			break;
		case "Snow":
			weatherClass = "snow";
			break;
		case "Ice":
			weatherClass = "ice";
			break;
		case "Hail":
			weatherClass = "hail";
			break;
		case "Fog":
			weatherClass = "fog";
			break;
		case "Dust/Sand":
			weatherClass = "dust-sand";
			break;
		case "Smoke":
			weatherClass = "smoke";
			break;
		case "Haze":
			weatherClass = "haze";
			break;
		default:
			weatherClass = "weather-clear";
			break;
	}
	return weatherClass;
},

FC.isEmptyObj = function(obj) {
	for(var prop in obj) {
		if(obj.hasOwnProperty(prop))
			return false;
	}

	return true;
}

FC.predictiveResultsTabbingHandler = function(){

	$("body").keyup(function(e){

		var $predictiveResults = $(".predictive-results"),
			$activeElement = FC.vars.variables.activeElement,
			$predictiveInputs = $(".choose-airport").find(".predictive"),
			predictiveInputsLength = $predictiveInputs.length;

		function ensurePredictiveResultsIsHidden() {

			$predictiveResults.addClass("off-screen");

		}

		function displayPlaceholderText() {

			var defaultValue = $predictiveInputs.attr("data-default"),
				airportData;

			function getSelectedAirport(el) {
				var serializedAirport = $predictiveInputs.eq(el).attr("data-airport");
				if (!serializedAirport || !serializedAirport.length) {
					return null;
				}
				return $.parseJSON(serializedAirport);
			}

			function setDefaultValue( el ){
				$predictiveInputs.eq(el).val( defaultValue );

			}

			function setSelectedValue( el, airportData ){
				$predictiveInputs.eq(el).val(airportData.Code + ' ' + FC.htmlDecode(airportData.FullName));

			}

			for( var i = 0; i < predictiveInputsLength; i++ ){

				// fix to deal with incomplete serialized airport data
				var airport = getSelectedAirport(i);
				if (!airport || !airport.Code || !airport.FullName) {
					setDefaultValue( i );
				}else {
					setSelectedValue( i, airport );
				}
			}
		}

		function isActiveElementChildOfPredictiveResults(){

			$activeElement = $( document.activeElement );

			if( !$activeElement.parents(".predictive-results").length ){
				return false;
			}

			return true;

		}

		function tabPressed(){

			if( e.which == 9 ) {

				return true;

			}

			return false;

		}

		if( tabPressed() ){

			setTimeout( function(){

				if( !isActiveElementChildOfPredictiveResults() ){

					ensurePredictiveResultsIsHidden();
					displayPlaceholderText();

				}

			}, 500);

		}

	});
}

FC.updateProgressChevron = function(enable, handler) {
	var chevron = $("#content ol.progress"),
		links = chevron.find("a");

	if (enable) {
		chevron.removeClass('chevron-disabled');
	}else {
		chevron.addClass('chevron-disabled');
	}
	if (!links.length) {
		return;
	}
	links.unbind("click");
	if (enable) {
		if (handler) {
			links.bind("click", function(e) { handler(this); return false; });
		}
	}else {
		links.bind("click", function(e) { return false; });
	}
};



// MAGAZINE OVERLAY
FC.magazineOverlay = function ($el) {

	var links = $el;
	links.unbind().bind("click", function () {

		var url = $(this).attr("href");

		//Build the iframe
		$("body").append('<div class="magazine-overlay modal"><a href="#" class="close">Close</a><iframe src="' + url + '" width="100%" height="100%" frameborder="0"></iframe></div>');

		var magazineOverlay = $(".magazine-overlay");

		//Work out the maximum size of the overlay based on the available screen size
		/*var screenWidth = $(window).width();
		var screenHeight = $(window).height();
		screenHeight = screenHeight - 80;
		screenWidth = screenWidth - 80;

		console.log(screenHeight);

		var overlayWidth = 940;
		var overlayHeight = 940;

		var cssWidth = 900;
		var cssHeight = 860;

		if (overlayHeight > screenHeight) {

		overlayHeight = screenHeight;
		cssHeight = overlayHeight - 80;

		}

		if (overlayWidth > screenWidth) {

		overlayWidth = screenWidth;
		cssWidth = overlayWidth - 40;

		}*/

		//magazineOverlay.css({ "height": cssHeight + "px", "width": cssWidth + "px" });

		//FC.showModal(magazineOverlay, overlayWidth, overlayHeight, true);



		var ua = navigator.userAgent;
		var checker = {
			iPad: ua.match(/(iPad)/)
		};


		if (checker.iPad) {

			//Set a fixed height
			var screenWidth = $(window).width();
			var screenHeight = $(window).height();

			screenWidth = screenWidth - 20;
			screenHeight = screenHeight - 20;

			magazineOverlay.css({ "display": "block", "width": screenWidth + "px", "height": screenHeight + "px" });

		}
		else {

			magazineOverlay.css({ "display": "block"});

		}


		FC.showCurtain();



		var close = magazineOverlay.find("a.close");

		close.unbind().bind("click", function () {

			FC.hideModal(magazineOverlay);
			//Remove the overlay from the DOM
			magazineOverlay.remove();
			return false;

		});

		return false;

	});

}

/* ALERT OVERLAY */
FC.openAlert = function ($elem) {

	var mobile = $("ul.mini").is(":visible");

	$($elem).on('click', function () {

		if (mobile == false) {
			$('div.alertOverlay').toggle();
		}
		$('div.alertMessage').toggle();
		return false;
	});

	$('div.alertOverlay').on('click', function () {
		$(this).hide();
		$('div.alertMessage').hide();
		return false;
	});

	$('a.closeBtn').on('click', function () {
		if (mobile == false) {
			$('div.alertOverlay').hide();
		}
		$('div.alertMessage').hide();
		return false;
	});
}

FC.windowPrint = function ($elem) {
	$elem.on('click', function(evt){
		evt.preventDefault();
		window.print();
	});
}

function PrintElement(header, elem) {
	Popup(header, $(elem).html());
}

function Popup(header, data) {
	var mywindow = window.open('', '', 'height=600,width=600,scrollbars=1');
	mywindow.document.write('<html><head>');
	mywindow.document.write('<link rel="stylesheet" href="/Resources/css/compiled/base.css" type="text/css" />');
	mywindow.document.write('<link rel="stylesheet" href="/Resources/css/compiled/payments-invoices.css" type="text/css" />');
	mywindow.document.write('</head><body style="background: #fff;">');
	mywindow.document.write('<div class="page container clear">');
	mywindow.document.write('<div class="pi-container clear autopay-content" style="box-shadow:none;border:none;">');
	mywindow.document.write('<div style="padding: 10px 0;"><img src="/Resources/images/NetJets-logo.png" alt="NetJets"></div>');
	mywindow.document.write('<h3>' + header + '</h3>');
	mywindow.document.write(data);
	mywindow.document.write('</div></div>');
	mywindow.document.write('</body></html>');

	mywindow.document.close(); // necessary for IE >= 10
	mywindow.focus(); // necessary for IE >= 10

	setTimeout(function () { mywindow.print() }, 100);
	return true;
}

$(function () {

	FC.setJS();

	var __SEL = FC.vars.selectors, __$tmp;

	(function (arg) {
		for (var __i = 0, __j = arg.length, __o; __i < __j; __i++) {
			__o = arg[__i];
			(function () {
				__$tmp = $(__o.test);
				if (__$tmp.length && arg[__i].func === undefined) {
					if (typeof (console.error) == 'function') {
						console.error('"' + __o.test + '" handler is missing.')
					}
				}
				return __$tmp.length && arg[__i].func !== undefined
			})() ? __o.func(__$tmp, __o.args || null) : null;
		}
	})([{ func: FC.tabs, test: __SEL.TABS_CONTAINER },

		{ func: FC.viewReservations, test: __SEL.HOMEPAGE_RESERVATIONS_TABS },

		{ func: FC.accountsDD, test: __SEL.ACCOUNTS },

        { func: FC.blueSkies, test: __SEL.BLUESKIES },

        { func: FC.helpDD, test: __SEL.HELP },

		{ func: FC.mobileNav, test: __SEL.PRIMARY_NAV },

		{ func: FC.setWrapperHeight, test: 'body' },

		{ func: FC.wrapperHeightResizer, test: 'body' },

		{ func: FC.passwordStrength, test: __SEL.PASSWORD_STRENGTH_INPUT },

		{ func: FC.confirmDelete, test: __SEL.CONFIRM_DELETE },

		{ func: FC.planBookLoad, test: __SEL.RESERVATION_STEP1 },

		{ func: FC.planBookStep2, test: __SEL.RESERVATION_STEP2 },

		{ func: FC.showMoreReservations, test: __SEL.SHOW_MORE_RESERVATIONS_BUTTON },

		{ func: FC.revealPanel, test: __SEL.REVEAL },

		{ func: FC.tooltip, test: __SEL.TOOLTIP },

		{ func: FC.expander, test: __SEL.EXPANDER },

		{ func: FC.cateringCategories, test: __SEL.CATERING_CATEGORIES },

		{ func: FC.flightDetails, test: __SEL.FLIGHT_DETAILS },

		{ func: FC.groundTransport, test: __SEL.GROUND_TRANSPORT },

		{ func: FC.planBookRequestedReservation, test: __SEL.REQUEST_RESERVATION }, //

		{ func: FC.fancySelect, test: __SEL.FANCY_SELECT },

		{ func: FC.fancySelectGeneral, test: __SEL.FANCY_SELECT_GENERAL },

		{ func: FC.trimUsername, test: __SEL.LOGIN_USER_NAME },

		{ func: FC.furtherInstructions, test: __SEL.FURTHER_INSTRUCTIONS },

	// { func: FC.flightAccordion, test: __SEL.FLIGHT_ACC },

		{ func: FC.requestFlightHeader, test: __SEL.REQUEST_FLIGHT_HEADER },

		{ func: FC.checkboxes, test: __SEL.FORM_CHKBOXES },

		{ func: FC.people, test: __SEL.PEOPLE },

		{ func: FC.profile, test: __SEL.PROFILE },

		{ func: FC.GenerateGATagging, test: __SEL.SIDE_NAVIGATION },

		{ func: FC.GenerateGATaggingForHome, test: __SEL.HOME_NAVIGATION },

		{ func: FC.TrackOutBoundLinkAndPdf, test: __SEL.EVERY_LINK },

		{ func: FC.externalLink, test: __SEL.EXTERNAL_LINK },

		{ func: FC.loginPanel, test: __SEL.LOGIN_PANEL },

		{ func: FC.footer, test: __SEL.FOOTER },

		{ func: FC.editing, test: __SEL.PROFILE },

		{ func: FC.invoices, test: __SEL.INVOICE },

		{ func: FC.fancyCheckboxes, test: __SEL.FANCY_CHECKBOXES },

		{ func: FC.simulatePlaceholderText, test: __SEL.SIMULATE_PLACEHOLDER_TEXT_INPUTS },

		{ func: FC.hideSafariAddressBar, test: 'body' },

		{ func: FC.flightTracking, test: __SEL.FLIGHT_TRACKING_MODAL },

		{ func: FC.predictiveResultsTabbingHandler, test: 'body' },

		{ func: FC.notes, test: __SEL.NOTES },

		{ func: FC.notePreview, test: __SEL.NOTES_PREVIEW },

		{ func: FC.calendar, test: __SEL.CALENDAR },

		{ func: FC.magazineOverlay, test: __SEL.MAGAZINE },

		{ func: FC.selfEnroll, test: __SEL.SELF_ENROLL },
		{ func: FC.enroll, test: __SEL.ENROLL },

		{ func: FC.openAlert, test: __SEL.ALERT_BTN },
		{ func: FC.menus, test: __SEL.MENUS },
		{ func: FC.invoiceDataTable, test: __SEL.INVOICES_TABLE },
		{ func: FC.invoiceSelectedTable, test: __SEL.INVOICES_SELECTED_TABLE },
		{ func: FC.invoiceDataTableFilters, test: __SEL.INVOICES_TABLE_FILTERS },
		{ func: FC.invoiceDataTableFilters, test: __SEL.PAYMENT_HISTORY_TABLE_FILTERS},
		{ func: FC.customSelectArrow, test: __SEL.CUSTOM_SELECT_ARROW },
		{ func: FC.checkboxInvoices, test: __SEL.SELECT_ALL_INVOICES },
		{ func: FC.deleteSelectedInvoices, test: __SEL.DELETE_SELECTED_INOVICES },
		{ func: FC.agreeTermsAndConditionsCheckbox, test: __SEL.AGREE_TERMS_AND_CONDITIONS_CHECKBOX },
		{ func: FC.contactUsBtn, test: __SEL.CONTACT_US_BTN },
		{ func: FC.autopay, test: __SEL.AUTOPAY_CONTENT },
		{ func: FC.paymentAccountSelection, test: __SEL.ACCOUNT_DROPDOWN },
		{ func: FC.updateOtherAmount, test: __SEL.OTHER_AMOUNT },
		{ func: FC.manageAccount, test: __SEL.MANAGE_ACCOUNT_LINKS },
		{ func: FC.windowPrint, test: __SEL.WINDOW_PRINT },
		{ func: FC.triggerReviewPopup, test: __SEL.REVIEW_MODAL }
	]);
});

FC.notes = function (noteLink) {
	var baseUrl = "/Book/Notes/",
		theNote = {},
		controller,
		maxLength = 4000,
		isMobileView = $("meta [name='viewport']").length > 0;

	var getReservationNotesDisplayName = function (hasNotes) {
		if (hasNotes) {
			return isMobileView ? "Update Notes" : "Update Res. Notes";
		}
		return isMobileView ? "Add notes" : "Add reservation notes";
	};

	var initializeNote = function () {
		if (!noteLink) { return; }

		function initButtons() {
			if (theNote.readonly) {
				theNote.overlay.find("#clear-note").hide();
				theNote.overlay.find("#notes").attr("readonly", "readonly");
			}
			var closeButton = theNote.overlay.find("#save-note");
			closeButton.text("Close");
		}

		function setNoteContent() {
			if (!theNote || !theNote.overlay) {
				return;
			}
			var textArea = theNote.overlay.children("textarea");
			if (theNote && theNote.content) {
				textArea.focus().val(theNote.content.replace(/\r?\n/g, "<br />"));
			}else {
				textArea.focus().val("");
			}
			theNote.isDirty = false;
		}

		function decodeWithLineBreaks(data) {
			return $("<div />").html(data.replace(/\r?\n/g, "_[br]_")).text().replace(/_\[br\]_/gi,"\r");
		}

		var initOverlay = function () {
			if (!theNote) { return; }

			if (!theNote.content) {
				theNote.content = "";
			}
			theNote.currentContent = theNote.content;
			var header = "<h2>Reservation notes</h2>",
				closeLink = "<a href='' class='close exit'><i class='icon icon-close'></i></a>",
				content = "<textarea id='notes' cols='50' rows='20' class='mvm form-control'>" + theNote.content + "</textarea>",
				buttons = "<div class='note-buttons clear text-right'><a href='#' class='clear-note-link' id='clear-note'>Clear</a><a href='#' class='btn btn-primary' id='save-note'>Close</a></div>",
				overlay = $("<div class='modal modal-window notes-overlay'>" + header + closeLink + content + buttons + "</div>");
			if ($("body div.notes-overlay").length == 0) {
				$("body").append(overlay);
			}
			theNote.overlay = $("body > div.notes-overlay");
			if (!theNote.content && theNote.reservationId) {
				var url = "GetReservationNotes",
					params = { "reservationId": theNote.reservationId }
					textArea = theNote.overlay.children("textarea"),
					onGetReservationNotes = function (data) {
						theNote.content = data == null ? "" : decodeWithLineBreaks(data);
						theNote.currentContent = theNote.content;
						textArea.removeAttr("readonly");
						setNoteContent();
						initButtons();
						theNote.isInitialized = true;
					};
				textArea.attr("readonly", "readonly");
				getData(url, params, onGetReservationNotes);
			}else {
				initButtons();
				theNote.isInitialized = true;
			}
		};

		var markNoteAsSaved = function() {
			$(noteLink).text(getReservationNotesDisplayName(!!theNote.content));
			if (theNote && theNote.overlay) {
				FC.hideModal(theNote.overlay, true);
			}
			theNote.currentContent = theNote.content;
			theNote.isDirty = false;
		};

		var saveContent = function () {
			var url = "UpdateReservationNotes";
			var params = { "reservationId": theNote.reservationId, "Notes": theNote.content };
			setData(url, params, markNoteAsSaved);
			return;
		};

		// detects changes in the note text area without updating its content or comparing it with the original content
		var checkContentChanged = function() {
			if (!theNote || !theNote.isInitialized || theNote.isDirty) {
				return;
			}
			var content = theNote.overlay.children("textarea").val();
			theNote.isDirty = content != theNote.currentContent;
			return;
		};

		// synchronizes note content with text area and detects changes in original note content, if any
		var updateContent = function() {
			var textArea = theNote.overlay.children("textarea"),
				content = textArea.val();
			if (content) {
				content = $.trim(content);
			}
			theNote.content = content;
			theNote.isDirty = theNote.content != theNote.currentContent;
			return;
		};

		//MOS-258 - Close overlays with ESC key
		$("html").bind("keyup", function (e) {
			if (!theNote.overlay) { return; }
			if (e.keyCode == 27)
				theNote.overlay.children("a.exit").trigger("click");
		});

		return {
			reservationId: (noteLink.attr("data-reservationId") || null),
			readonly: !!noteLink.attr("data-readonly"),
			content: null,
			isDirty: false,
			isInitialized: false,
			initOverlay: initOverlay,
			saveContent: saveContent,
			markNoteAsSaved: markNoteAsSaved,
			checkContentChanged: checkContentChanged,
			updateContent: updateContent,
			restoreContent: setNoteContent
		};
	};

	// obtains data using the specified end-point and calls the specified callback
	// upon successful completion.
	function getData(url, params, callback, callbackParams) {
		$.ajax({
			url: baseUrl + url,
			data: params,
			type: "GET",
			dataType: "json",
			contentType: "application/json; charset=utf-8",
			beforeSend: startVisualFeedback,
			success: function (data) { handleServerRespones(data, callback, callbackParams); },
			complete: endVisualFeedback,
			error: handleServerErrors
		});
	}

	// posts data to server using the specified end-point and calls the specified callback upon successful completion.
	function setData(url, params, callback, callbackParam, dataType) {
		$.ajax({
			url: baseUrl + url,
			data: JSON.stringify(params),
			dataType: dataType || "json",
			contentType: "application/json; charset=utf-8",
			type: "POST",
			beforeSend: function (request) {
				startVisualFeedback();
				FC.AddAntiForgeryToken(request);
			},
			success: function (data) { handleServerRespones(data, callback, callbackParam); },
			complete: endVisualFeedback,
			error: handleServerErrors
		});
	}

	function handleServerErrors(data) {
		if (data) {
			var message = (data.statusText ? data.statusText : data);
			if (message && message.length && message.charAt(message.length - 1) != '.') {
				message += ".";
			}
			alert("An error occurred: " + message);
		}else {
			alert("An error occurred.");
		}
		// revert note content
		theNote.content = theNote.currentContent;
	}

	function handleServerRespones(data, callback, callbackParams) {
		if (data != null && data.SessionExpired) {
			if (data.RedirectUrl) {
				document.location.href = data.RedirectUrl;
			}
			return;
		}
		if (data && data.HasError) {
			handleServerErrors(data == null ? null : data.ErrorDescription);
			return;
		}
		callback(data, callbackParams);
	}

	function startVisualFeedback() {
		if (!theNote.overlay) { return; }

		if (theNote.overlay.find(".ajax-loader.blue").length == 0) {
			theNote.overlay.append("<div class='ajax-loader blue'></div>");
			FC.loadingAnimation(
				{ frameWidth: 25, frames: 6, el: theNote.overlay.find(".ajax-loader.blue") }
			);
		}
	}

	function endVisualFeedback() {
		if (theNote.overlay) {
			FC.removeLoadingAnimation(theNote.overlay.find(".ajax-loader.blue"));
		}
	}

	var initializeController = function () {
		if (!noteLink) {
			return null;
		}

		function onContentChanged(force) {
			if (!theNote || !theNote.isInitialized || theNote.readonly) {
				return;
			}
			if (force) {
				theNote.isDirty = true;
			}else {
				theNote.checkContentChanged();
			}
			var closeButton = theNote.overlay.find("#save-note");
			if (theNote.isDirty) {
				closeButton.text("Save");
				theNote.overlay.find("#save-note").unbind("click").bind("click", onSaveNote);
			}else {
				closeButton.text("Close");
				theNote.overlay.find("#save-note").unbind("click").bind("click", onCloseNote);
			}
		}

		var onClearNote = function (e) {
			if (!theNote || !theNote.overlay) {
				return false;
			}
			var textArea = theNote.overlay.children("textarea");
			if (textArea.val()) {
				textArea.val("");
				onContentChanged(true);
			}
			return false;
		};

		var onSaveNote = function (e) {
			ga('send', 'event', 'Note', 'Save Note');
			if (!theNote || !theNote.overlay) {
				return false;
			}
			theNote.updateContent();
			if (theNote.reservationId && theNote.isDirty) {
				theNote.saveContent();
			}else {
				theNote.markNoteAsSaved();
			}
			return false;
		};

		var onCloseNote = function (e) {
			if (!theNote || !theNote.overlay) {
				return false;
			}
			FC.hideModal(theNote.overlay, true);
			theNote.overlay.find("#save-note").unbind("click").bind("click", onCloseNote);
			theNote.restoreContent();
			return false;
		};

		var onChange = function (e) {
			if (!e || !e.target) {
				return;
			}
			var value = $(this).val();
			if (value && value.length > maxLength) {
				$(this).val(value.substring(0, maxLength - 1));
			}
			onContentChanged(e.type == "paste");
		};

		var onEditNote = function (e) {
			ga('send', 'event', 'Note', 'Open Note');
			if (!theNote) {
				return false;
			}
			theNote.initOverlay();
			if (!theNote.overlay || !theNote.overlay.length) {
				return false;
			}
			FC.showModal(theNote.overlay, theNote.overlay.width(), theNote.overlay.height(), true);
			theNote.overlay.children("a.exit").unbind("click").bind("click", onCloseNote);
			theNote.overlay.find("#clear-note").unbind("click").bind("click", onClearNote);
			theNote.overlay.find("#save-note").unbind("click").bind("click", onCloseNote);
			theNote.overlay.find("textarea").unbind("keyup").bind("keyup", onChange);
			theNote.overlay.find("textarea").unbind("paste").bind("paste", onChange);
			theNote.overlay.find("textarea").unbind("input").bind("input", onChange);
			return false;
		}

		noteLink.unbind("click").bind("click", onEditNote);

		// TODO: review
		return {};
	};

	theNote = initializeNote();
	controller = initializeController();
	FC.notes.currentNote = theNote;
	FC.notes.getReservationNotesDisplayName = getReservationNotesDisplayName;
};

FC.notePreview = function(noteLink) {
	var onOpenReservationNote = function (e) {
		if (!e || !e.target) { return false; }
		var link = $(e.target).parent().find("a.details-link");
		if (link.length > 0) {
			document.location.href = link.attr("href");
		}
		return false;
	};

	$(noteLink).unbind("click").bind("click", onOpenReservationNote);
};

FC.calendar = function (link) {
	function dataAccess() {
		function startVisualFeedback() { ; }

		function endVisualFeedback() { ; }

		function handleServerErrors(data) {
			if (data) {
				var message = (data.statusText ? data.statusText : data);
				if (message && message.length && message.charAt(message.length != '.')) {
					message += ".";
				}
				alert("These issues need your attention: " + message);
			}else {
				alert("Failed to open calendar.");
			}
        }

		function handleServerRespones(data, callback, callbackParams) {
            if (data != null && data.SessionExpired) {
                document.location.href = data.RedirectUrl;
				return;
            }
			if (!data || data.HasError) {

				handleServerErrors(data == null ? null : data.ErrorDescription);
				return;
			}
			callback(data, callbackParams);
		}
		
		// obtains data using the specified end-point and calls the specified callback
		// upon successful completion.
		function getData(url, params, callback, callbackParams) {
            $.ajax({
                url: url,
                data: params,
                type: "GET",
                dataType: 'html',
                beforeSend: startVisualFeedback,
                success: function (data) { handleServerRespones(data, callback, callbackParams); },
                complete: endVisualFeedback,
                error: handleServerErrors
            });
		}

		return { getData: getData };
	}

    var selector = "div.calendar-overlay",
		url = "/Book/Calendar",
		popup = $(selector),
		targetUrl,
		dataAccess = dataAccess(),
		displayOverlay = function() {
			var newSelector = "body > " + selector;
			if ($(newSelector).length == 0) {
				if (popup.length == 0) {
					return;
				}
				popup.clone().appendTo("body");
			}
			popup = $(newSelector);
			popup.children("a.exit").unbind("click").bind("click", onCloseCalendar);
			$("html").bind("keyup", onEscapeCalendar);
			popup.find("a.download-calendar, a[href='#']").unbind("click").bind("click", onDownloadCalendar);
			FC.showModal(popup, popup.width(), popup.height(), true);
		},
		addOverlay = function(html) {
			if (!html) { return; }
			$("body").append(html);
			displayOverlay();
		},
		onDownloadCalendar = function(e) {
		    ga('send', 'event', 'Calendar', 'Download Calendar');
			window.location.href = targetUrl;
			return false;
		},
		onCloseCalendar = function(e) {
			if (!e || !e.target) { return false; }
			var overlay = $(e.target).parents(".calendar-overlay");
			if (overlay.length > 0) {
	           FC.hideModal(overlay, true);
			}
			return false;
		},
        onEscapeCalendar = function (e) {
            if (e.keyCode == 27) {
                popup.children("a.exit").trigger("click");
            }
            return false;
        },
		onExportCalendar = function(e) {
		    ga('send', 'event', 'Calendar', 'Add To Calendar');
			if (!e || !e.target) { return false; }
			targetUrl = $(e.target).parent().attr("href");
			if (popup.length == 0) {
				dataAccess.getData(url, null, addOverlay);
			}else {
				displayOverlay();
			}
			return false;
		};

    $(link).unbind("click").bind("click", onExportCalendar);
};

FC.vList = function(dataUrl, selector, totalCount, pageSize, updateCallback) {
	var $selector = $(selector),
		padding = 0,
		lastPage = 0,
		enabled = true,
		waiting = false,
		totalPages = (pageSize == 0) ? 0 : Math.ceil(totalCount / pageSize),
        isWindow = ($selector.css('overflow-y') === 'visible'),
        $window = $(window),
        $body = $('body'),
        $scroll = isWindow ? $window : $selector;

    function observe() {
		if (!enabled) { return; }
        wrapInnerContent();
        var $inner = $selector.find('div.vList-inner').first(),
            borderTopWidth = parseInt($selector.css('borderTopWidth')),
            borderTopWidthInt = isNaN(borderTopWidth) ? 0 : borderTopWidth,
            iContainerTop = parseInt($selector.css('paddingTop')) + borderTopWidthInt,
            iTopHeight = isWindow ? $scroll.scrollTop() : $selector.offset().top,
            innerTop = $inner.length ? $inner.offset().top : 0,
            iTotalHeight = Math.ceil(iTopHeight - innerTop + $scroll.height() + iContainerTop);

        if (!waiting && iTotalHeight + padding >= $inner.outerHeight()) {
            load();
        }
    }

    function wrapInnerContent() {
        if (!$selector.find('.vList-inner').length) {
            $selector.contents().wrapAll('<div class="vList-inner" />');
        }
    }

    function setBindings() {
        if ($body.height() <= $window.height()) {
            observe();
        }
        $scroll.unbind('scroll').bind('scroll', function() {
            return observe();
        });
    }

	function setupScroll() {
        wrapInnerContent();
        setBindings();
	}

    function startVisualFeedback() {
        if ($selector.parent().find(".loading").length == 0) {
            $selector.after("<div class='loading'>Loading more data...</div>");
        }
    }

    function endVisualFeedback() {
		$selector.parent().find(".loading").remove();
    }

	function handleServerErrors(error) {
		waiting = false;
	}

	function handleServerRespones(data) {
		try {
			updateCallback(data);
			++lastPage;
		}catch(e) { ; }
		waiting = false;
		return true;
	}

    function getData(params) {
        $.ajax({
            url: dataUrl,
            data: params,
            type: "GET",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            beforeSend: startVisualFeedback,
            success: function(data) { handleServerRespones(data); },
            complete: endVisualFeedback,
            error: function(error) { handleServerErrors(error); }
        });
    }

	function load() {
		waiting = true;
		if (!updateCallback || lastPage >= totalPages - 1) { 
			waiting = false;
			return; 
		}
		try {
			var params = { pageOffset: lastPage + 1, numberOfPages: 1 };
			getData(params);
		}catch(e) { 
			waiting = false;
		}
		return true;
	}

	function reset() {
		enable();
		try {
			var params = { pageOffset: 0, numberOfPages: 1 };

			// set last page taking into account that first page will be loaded asynchronously now
			lastPage = -1;
			getData(params);
		}catch(e) { ; }
	}

	function enable() {
		enabled = true;
	}

	function disable() {
		enabled = false;
	}

	function isEnabled() {
		return enabled;
	}

	enable();
	setupScroll();
	FC.vList.reset = reset;
	FC.vList.enable = enable;
	FC.vList.disable = disable;
	FC.vList.isEnabled = isEnabled;
	return;
};

FC.menus = function (link) {
    var baseUrl = "/Book/Menus/";
    function dataAccess() {
        function startVisualFeedback() { ; }

        function endVisualFeedback() { ; }

        function handleServerErrors(data) {
            if (data) {
                var message = (data.statusText ? data.statusText : data);
                if (message && message.length && message.charAt(message.length != '.')) {
                    message += ".";
                }
                alert("These issues need your attention: " + message);
            } else {
                alert("Failed to open regional Menus.");
            }
        }

        function handleServerRespones(data, callback, callbackParams) {
            if (data != null && data.SessionExpired) {
                document.location.href = data.RedirectUrl;
                return;
            }
            if (!data || data.HasError) {

                handleServerErrors(data == null ? null : data.ErrorDescription);
                return;
            }
            callback(data, callbackParams);
        }

        // obtains data using the specified end-point and calls the specified callback
        // upon successful completion.
        function getData(url, params, callback, datatype, callbackParams) {
            $.ajax({
                url: baseUrl + url,
                data: params,
                type: "GET",
                dataType: datatype,
                beforeSend: startVisualFeedback,
                success: function (data) { handleServerRespones(data, callback, callbackParams); },
                complete: endVisualFeedback,
                error: handleServerErrors
            });
        }

        return { getData: getData };
    }
    function GetRegionalMenus(program) {
        var url = "GetRegionalMenus",
		params = { "programFolder": (program == "US" ? "~/Global/Catering Menus/NJA" : "~/Global/Catering Menus/NJE") };
        onGetRegionalMenus = function (data) {
            SetRegionalMenus(data);
        };
        dataAccess.getData(url, params, onGetRegionalMenus, "json");
    }

    function SetRegionalMenus(data) {
        var fieldType = $("select#regionalMenu");
        var selectParent = fieldType.parent();
        var optionsString = "";
        $.each(data, function (index, value) {
            optionsString += "<option>" + value + "</option>";
        });
        fieldType.html(optionsString);
    }
    function SetMenuLink() {
        if ($("#program").val() == "Europe") {
            $("#downloadStandardMenu").attr("href", "/Global/Catering Menus/NJE/Standard Menu/Standard Menu, NJE.pdf");
            $("#downloadStockItemMenu").attr("href", "/Global/Catering Menus/NJE/Onboard Snacks and Beverages Menu/Onboard Snacks and Beverages Menu, NJE.pdf");
        }
        else {
            $("#downloadStandardMenu").attr("href", "/Global/Catering Menus/NJA/Standard Menu/Standard Menu, NJA.pdf");
            $("#downloadStockItemMenu").attr("href", "/Global/Catering Menus/NJA/Onboard Snacks and Beverages Menu/Onboard Snacks and Beverages Menu, NJA.pdf");
        }
    }
    function SetRegionalMenuLink() {
        var menuLink = "";
        if ($("#program").val() == "Europe") {
            menuLink = "/Global/Catering Menus/NJE/" + $("#regionalMenu").val() + ".pdf";
        }
        else {
            menuLink = "/Global/Catering Menus/NJA/" + $("#regionalMenu").val() + ".pdf";
        }
        $("#downloadRegionalMenu").attr("href", menuLink);
    }
    var selector = "div.menus-overlay",
		url = "",
		popup = $(selector),
		targetUrl,
		dataAccess = dataAccess(),
		displayOverlay = function () {
		    var newSelector = "body > " + selector;
		    if ($(newSelector).length == 0) {
		        if (popup.length == 0) {
		            return;
		        }
		        popup.clone().appendTo("body");
		    }
		    popup = $(newSelector);
		    popup.children("a.exit").unbind("click").bind("click", onCloseMenus);
		    popup.find("#close-menus").unbind("click").bind("click", onCloseMenus);
		    popup.find("#program").unbind("change").bind("change", onChangeProgram);
		    popup.find("#regionalMenu").unbind("change").bind("change", onChangeMenu);

		    onChangeProgram();
		    onChangeMenu();

		    $("html").bind("keyup", onEscapeMenus);
		    FC.showModal(popup, popup.width(), popup.height(), true);
		},
		addOverlay = function (html) {
		    if (!html) { return; }
		    $("body").append(html);
		    displayOverlay();
		},
		onCloseMenus = function (e) {
		    if (!e || !e.target) { return false; }
		    var overlay = $(e.target).parents(".menus-overlay");
		    if (overlay.length > 0) {
		        FC.hideModal(overlay, true);
		    }
		    return false;
		},
        onEscapeMenus = function (e) {
            if (e.keyCode == 27) {
                popup.children("a.exit").trigger("click");
            }
            return false;
        },

        onChangeProgram = function (e) {
            if ($("#program").val() == "Europe") {
                $("#marketText").text("The Signature Seletions menu is available at more than 20 airports across Europe.");
            }
            else {
                $("#marketText").text("The Signature Selections menu is available at over 200 airports in 40 markets across the United States.");
            }
            GetRegionalMenus($("#program").val());
            SetMenuLink();
            SetRegionalMenuLink();
            return false;
        },
        onChangeMenu = function (e) {
            SetRegionalMenuLink();
            return false;
        },

        onExportMenus = function (e) {
            ga('send', 'event', 'Menus', 'Regional Menus');
            if (popup.length == 0) {
                dataAccess.getData(url, null, addOverlay, "html");
            } else {
                displayOverlay();
            }
            SetMenuLink();
            SetRegionalMenuLink();
            return false;
        };

    $(link).unbind("click").bind("click", onExportMenus);

};
