﻿/*global document, $, Dom, Event, Image, Lang, YAHOO */
/*members CloseChild, ContentClass, FontResizer, FormFill, JumpSelect, 
    Load, MouseOvers, add, addClass, addListener, alt, applied, apply, call, 
    ceil, checked, childNodes, close, content, cookie, cssSizes, 
    currentState, data, doClick, doHover, dropMenus, el, elements, env, 
    every, filter, findActiveState, floor, forEach, getElementsByTagName, 
    getTarget, hasOwnProperty, height, hoverEl, hoverSrc, href, ie, indexOf, 
    init, lastIndexOf, length, location, map, nodeName, onDOMReady, 
    onMouseOut, onMouseOver, options, prototype, push, reduce, reduceRight, 
    removeClass, selected, selectedIndex, selects, setState, setStyle, 
    size1, size2, size3, size4, sizes, some, split, src, substr, substring, 
    text, toLowerCase, toString, type, ua, value, waiting, width
*/

"use strict";

if (!Array.prototype.indexOf) {
	/** Returns the first index at which a given element can be found in the
	  * array, or -1 if it is not present.
	  * This algorithm is exactly the one used in Firefox and SpiderMonkey.
	  * @param  {Object}    elt    Element to locate in the array.
	  * @param  {Integer}  [from]  The index at which to begin the search.
	  *                            Defaults to 0, i.e. the whole array will be
	  *                            searched. If the index is greater than or
	  *                            equal to the length of the array, -1 is
	  *                            returned, i.e. the array will not be
	  *                            searched. If negative, it is taken as the
	  *                            offset from the end of the array. Note that
	  *                            even when the index is negative, the array
	  *                            is still searched from front to back. If
	  *                            the calculated index is less than 0, the
	  *                            whole array will be searched.
	  * @return {Number} */
	Array.prototype.indexOf = function (elt /*, from*/) {
		var len = this.length,
		from = Number(arguments[1]) || 0;

		from = (from < 0) ? Math.ceil(from) : Math.floor(from);

		if (from < 0) {
			from += len;
		}

		for (; from < len; from++) {
			if (from in this && this[from] === elt) {
				return from;
			}
		}
		return -1;
	};
}


if (!Array.prototype.lastIndexOf) {
	/** Returns the last index at which a given element can be found in the array, or -1 if it is not present.
	  * The array is searched backwards, starting at fromIndex.
	  * This algorithm is exactly the one used in Firefox and SpiderMonkey.
	  * @param  {Object}    elt    Element to locate in the array.
	  * @param  {Integer}  [from]  The index at which to start searching backwards.
	  *                            Defaults to the array's length, i.e. the whole array will be searched.
	  *                            If the index is greater than or equal to the length of the array, the
	  *                            whole array will be searched. If negative, it is taken as the offset from
	  *                            the end of the array. Note that even when the index is negative, the array
	  *                            is still searched from back to front. If the calculated index is less
	  *                            than 0, -1 is returned, i.e. the array will not be searched.
	  * @return {Number} */
	Array.prototype.lastIndexOf = function (elt /*, from*/) {
		var len = this.length,
		from = Number(arguments[1]);

		if (isNaN(from)) {
			from = len - 1;
		} else {
			from = (from < 0) ? Math.ceil(from) : Math.floor(from);

			if (from < 0) {
				from += len;
			} else if (from >= len) {
				from = len - 1;
			}
		}

		for (; from > -1; from--) {
			if (from in this && this[from] === elt) {
				return from;
			}
		}
		return -1;
	};
}


if (!Array.prototype.some) {
	/** Tests whether some element in the array passes the test implemented by the provided function.
	  * This algorithm is exactly the one used in Firefox and SpiderMonkey.
	  * @param  {Function}  fun     Function to test for each element.
	  * @param  {Object}   [thisp]  Object to use as this when executing fun.
	  * @return {Boolean} */
	Array.prototype.some = function (fun /*, thisp*/) {
		var len = this.length,
		thisp   = arguments[1],
		i;

		if (typeof fun !== "function") {
			throw new TypeError();
		}

		for (i = 0; i < len; i++) {
			if (i in this && fun.call(thisp, this[i], i, this)) {
				return true;
			}
		}

		return false;
	};
}



if (!Array.prototype.every) {
	/** Tests whether all elements in the array pass the test implemented by the provided function.
	  * This algorithm is exactly the one used in Firefox and SpiderMonkey.
	  * @param  {Function}  fun     Function to test for each element.
	  * @param  {Object}   [thisp]  Object to use as this when executing fun.
	  * @return {Boolean} */
	Array.prototype.every = function (fun /*, thisp*/) {
		var len = this.length,
		thisp   = arguments[1],
		i;

		if (typeof fun !== "function") {
			throw new TypeError();
		}

		for (i = 0; i < len; i++) {
			if (i in this && !fun.call(thisp, this[i], i, this)) {
				return false;
			}
		}

		return true;
	};
}



if (!Array.prototype.forEach) {
	/** Executes a provided function once per array element.
	  * This algorithm is exactly the one used in Firefox and SpiderMonkey.
	  * @param  {Function}  fun     Function to test for each element.
	  * @param  {Object}   [thisp]  Object to use as this when executing fun. */
	Array.prototype.forEach = function (fun /*, thisp*/) {
		var len = this.length,
		thisp = arguments[1],
		i;

		if (typeof fun !== "function") {
			throw new TypeError();
		}

		for (i = 0; i < len; i++) {
			if (i in this) {
				fun.call(thisp, this[i], i, this);
			}
		}
	};
}



if (!Array.prototype.filter) {
	/** Creates a new array with all elements that pass the test implemented by the provided function.
	  * This algorithm is exactly the one used in Firefox and SpiderMonkey.
	  * @param  {Function}  fun     Function to test for each element.
	  * @param  {Object}   [thisp]  Object to use as this when executing fun.
	  * @return {Array} */
	Array.prototype.filter = function (fun /*, thisp*/) {
		var len = this.length,
		res     = [],
		thisp   = arguments[1],
		i, val;

		if (typeof fun !== "function") {
			throw new TypeError();
		}

		for (i = 0; i < len; i++) {
			if (i in this) {
				val = this[i]; // in case fun mutates this
				if (fun.call(thisp, val, i, this)) {
					res.push(val);
				}
			}
		}

		return res;
	};
}



if (!Array.prototype.map) {
	/** Creates a new array with the results of calling a provided function on every element in this array.
	  * This algorithm is exactly the one used in Firefox and SpiderMonkey.
	  * @param  {Function} fun
	  * @param  {Object}   [thisp]
	  * @return {Array} */
	Array.prototype.map = function (fun /*, thisp*/) {
		var len = this.length,
		res     = [],
		thisp   = arguments[1],
		i;

		if (typeof fun !== "function") {
			throw new TypeError();
		}

		for (i = 0; i < len; i++) {
			if (i in this) {
				res[i] = fun.call(thisp, this[i], i, this);
			}
		}

		return res;
	};
}



if (!Array.prototype.reduce) {
	/** Apply a function simultaneously against two values of the array
	  * (from left-to-right) as to reduce it to a single value.
	  * This algorithm is exactly the one used in Firefox and SpiderMonkey.
	  * @param  {Function}  callback         Function to execute on each value in the array.
	  * @param  {Object}   [initialValue]    Object to use as the first argument to the first call of the callback.
	  * @return {Object} */
	Array.prototype.reduce = function (fun /*, initial*/) {
		var len = this.length,
		rv, i   = 0;
		if (typeof fun !== "function") {
			throw new TypeError();
		}

		// no value to return if no initial value and an empty array
		if (len === 0 && arguments.length === 1) {
			throw new TypeError();
		}

		if (arguments.length >= 2) {
			rv = arguments[1];
		} else {
			do {
				if (i in this) {
					rv = this[i++];
					break;
				}

				// if array contains no values, no initial value to return
				if (++i >= len) {
					throw new TypeError();
				}
			} while (true);
		}

		for (; i < len; i++) {
			if (i in this) {
				rv = fun.call(null, rv, this[i], i, this);
			}
		}

		return rv;
	};
}


if (!Array.prototype.reduceRight) {
	/** Apply a function simultaneously against two values of the array
	  * (from right-to-left) as to reduce it to a single value.
	  * This algorithm is exactly the one used in Firefox and SpiderMonkey.
	  * @param  {Function}  callback         Function to execute on each value in the array.
	  * @param  {Object}   [initialValue]    Object to use as the first argument to the first call of the callback.
	  * @return {Object} */
	Array.prototype.reduceRight = function (fun /*, initial*/) {
		var len = this.length,
		rv, i   = len - 1;
		if (typeof fun !== "function") {
			throw new TypeError();
		}

		// no value to return if no initial value, empty array
		if (len === 0 && arguments.length === 1) {
			throw new TypeError();
		}

		if (arguments.length >= 2) {
			rv = arguments[1];
		} else {
			do {
				if (i in this) {
					rv = this[i--];
					break;
				}

				// if array contains no values, no initial value to return
				if (--i < 0) {
					throw new TypeError();
				}
			} while (true);
		}

		for (; i >= 0; i--) {
			if (i in this) {
				rv = fun.call(null, rv, this[i], i, this);
			}
		}

		return rv;
	};
}


var PB = {
	JumpSelect: function (o) {
		if (o.value && o.value !== '') {
			document.location.href = o.value;
		}
	},

	CloseChild: function (o) {
		o.close();
	},

	ContentClass: 'layout_eWEP',
	FormFill: {
		Load: function (formID, fieldName, value) {
			var i, x, field, form;
			if (value === null) {
				return;
			}
			form = $(formID);
			if (form) {
				field = form[fieldName];
			}

			if (field) {
				switch (field.type) {
				case 'select-one':
					i = field.options.length;
					while (i--) {
						if (field[i].value === value || field[i].text === value) {
							field.selectedIndex = i;
						}
					}
					break;

				case 'select-multiple':
					i = field.options.length;
					while (i--) {
						for (x = 0; x < value.split(', ').length; x++) {
							if (field[i].value === value.split(', ')[x] || field[i].text === value.split(', ')[x]) {
								field.options[i].selected = true;
							}
						}
					}
					break;

				case 'radio':
				case 'checkbox':
					if (field.value === value) {
						field.checked = true;
					}
					break;

				case 'file':
					break;

				case undefined:
					// The form element is likely a nodelist.
					if (field.length && field.length > 0) {
						switch (field[0].type) {
						case 'radio':
							i = field.length;
							while (i--) {
								if (field[i].value === value) {
									field[i].checked = true;
								}
							}
							break;

						case 'checkbox':
							i = field.length;
							value = value.split(', ');
							while (i--) {
								x = value.length;
								while (x--) {
									if (field[i].value === value[x]) {
										field[i].checked = true;
									}
								}
							}
							break;
						}
					}
					break;

				default:
					field.value = value;
					break;
				}
			}
		}
	},
	MouseOvers: {
		elements:    [ ],
		waiting:     false,

		/** Add a mouseover effect
		  * @param  {string | img}  el
		  * @param  {string}        hoverURL
		  */
		add: function (el, hoverURL) {
			this.elements.push({
				el      : el,
				src     : null,
				hoverEl : null,
				hoverSrc: hoverURL,
				applied : false
			});
		},

		/** Applies all loaded mouse over effects that have not already been applied.
		  * Performs pre-loading of hover URLs that match elements that are found in
		  * the document.
		  * It is safe to call this whenever--any real work will be defered until the
		  * DOM is available.
		  */
		apply: function () {
			if (this.waiting === true) {
				return;
			}

			this.waiting = true;
			Event.onDOMReady(function () {
				var els = this.elements,
				x, z, el;
				this.waiting = false;
				for (x = 0; x < els.length; x++) {

					if (els[x].applied === true) {
						continue;
					}

					el = $(els[x].el);
					if (el === null || el.nodeName.toLowerCase() !== 'img') {
						continue;
					}

					z = els.length;
					while (z--) {
						if (els[z].el === el && els[z].applied === true) {
							els[x].applied = true;
							continue;
						}
					}

					els[x].el  = el;
					els[x].src = el.src;
					els[x].hoverEl = new Image(el.width, el.height);
					els[x].hoverEl.alt = el.alt;
					els[x].hoverEl.src = els[x].hoverSrc;
					els[x].hoverSrc    = els[x].hoverEl.src;
					Event.addListener(el, 'mouseover', this.doHover, els[x]);
					Event.addListener(el, 'mouseout',  this.doHover, els[x]);

					els[x].applied = true;
				}

			}, this, true);
		},
		doHover: function (e, o) {
			var target = Event.getTarget(e);
			target.src = (e.type === 'mouseover') ? o.hoverSrc : o.src;
		}
	},

	FontResizer: {

		data: {
			content: 'layout_Content',
			sizes: {
				size1: 'text_size_1',
				size2: 'text_size_2',
				size3: 'text_size_3',
				size4: 'text_size_4'
			},
			cssSizes: {
				size1: '10px',
				size2: '13px',
				size3: '16px',
				size4: '19px'
			}
		},

		init: function () {
			var k;

			function resolve(o) {
				for (var x in o) {
					if (Lang.hasOwnProperty(o, x)) {
						o[x] = $(o[x]);
					}
				}
			}

			resolve(this.data);
			resolve(this.data.sizes);

			// Abort if we don't have controls
			if (!this.data.sizes.size1) {
				return;
			}

			for (k in this.data.sizes) {
				if (Lang.hasOwnProperty(this.data.sizes, k)) {
					Event.addListener(this.data.sizes[k], 'click', this.doClick, this, true);
				}
			}

			this.findActiveState();
			if (this.currentState !== 'size2') {
				this.setState(this.currentState);
			}
		},

		findActiveState: function () {
			var idx, name, x,
			cookies  = document.cookie.split('; '),
			value    = null;

			// Read cookie
			for (x = 0; x < cookies.length; x++) {
				idx = cookies[x].indexOf('=');
				name = cookies[x].substr(0, idx);
				if (name !== 'FontSize') {
					continue;
				}
				value = cookies[x].substring(idx + 1);
				break;
			}

			if (value === null) {
				value = 'size2';
			}

			if (Lang.hasOwnProperty(this.data.sizes, value) === false) {
				value = 'size2';
			}

			this.currentState = value;
			document.cookie = 'FontSize=' + value;
		},

		doClick: function (e) {
			var target = Event.getTarget(e),
			x, value   = null;

			for (x in this.data.sizes) {
				if (Lang.hasOwnProperty(this.data.sizes, x) &&
					this.data.sizes[x] === target) {
					value = x;
				}
			}

			if (value === this.currentState || value === null) {
				return;
			}

			this.setState(value);

		},
		setState: function (value) {

			var size = this.data.cssSizes[value];
			if (!size) {
				return;
			}

			Dom.setStyle(this.data.content, 'fontSize', size);
			this.currentState = value;
			document.cookie = 'FontSize=' + value;
		}
	},
	dropMenus: {
		selects: null,
		init: function () {
			var el = $('layout_TopMenu'),
			x, li, selects, ie = YAHOO.env.ua.ie;

			if (ie > 6 || ie === 0 || !el) {
				return;
			}

			el = Dom.getElementsByClassName('Root', 'ul', el)[0];
			if (!el) {
				return;
			}

			li = [];
			x = el.childNodes.length;
			while (x--) {
				if (el.childNodes[x].nodeName === 'LI') {
					li.push(el.childNodes[x]);
				}
			}

			Event.addListener(li, 'mouseover', this.onMouseOver);
			Event.addListener(li, 'mouseout',  this.onMouseOut);

			selects = $('bd');
			if (!selects) {
				return;
			}
			selects = selects.getElementsByTagName('SELECT');
			if (selects.length) {
				this.selects = selects;
			}
		},
		onMouseOver: function () {
			Dom.addClass(this, 'hover');
			if (PB.dropMenus.selects) {
				Dom.addClass(PB.dropMenus.selects, 'hover');
			}
		},
		onMouseOut: function () {
			Dom.removeClass(this, 'hover');
			if (PB.dropMenus.selects) {
				Dom.removeClass(PB.dropMenus.selects, 'hover');
			}
		}
	}
};

Event.onDOMReady(PB.FontResizer.init, PB.FontResizer, true);
Event.onDOMReady(PB.dropMenus.init, PB.dropMenus, true);
