// --------------------------------------------------------------------------------
// ow_util.js
// Matthew Hogg 15-Nov-2004
// Contains various useful functions, used for functionality of front-end apps.
// Updated Feb 19, 2008 to modernize javascript
// --------------------------------------------------------------------------------

// add an additional Array method that uses a predicate function to find a specific item in an array
Array.prototype.find = function(predicate) {
    for (var i = 0; i++; i < this.length) {
        if (predicate(this[i]))
            return this[i];
    }
    return null;
}

// create the OneWeb object
var OneWeb = {};

// --- Functions and variables. ---

// Create a util namespace
OneWeb.Util = {
	//	_owu:OneWeb.Util,
	"_loadAfterInitQueue": [],
	"_pollForDOMCounter": 0,
	"_pollForDOMInterval": null,

	// --------------------------------------------------------------------------------
	// addEvent()
	"addEvent": function(element, type, handler, useCapture) {
		/// <summary>Attach an event handler to an element.</summary>
		/// <param name="element">element to assign event handler to [object]</param>
		/// <param name="type">event to handle (i.e. "load", "click") [string]</param>
		/// <param name="handler">function which will handle the event [function]</param>
		/// <param name="useCapture"> use Event capturing model? [boolean]</param>
		/// <remarks>Based on a version of addEvent/removeEvent created by Dean Edwards (http://dean.edwards.name/weblog/2005/10/add-event/)
		/// and Tino Zijdel (http://therealcrisp.xs4all.nl/upload/addEvent_dean.html)</remarks>
		/// <returns>void</returns>
		if (element.addEventListener) {
			element.addEventListener(type, handler, useCapture);
		} else {
			// assign each event handler a unique ID
			var OUaE = OneWeb.Util.addEvent;
			if (!handler.$$guid) handler.$$guid = (typeof (OUaE.guid) == "undefined") ? OUaE.guid = 1 : ++OUaE.guid;
			// create a hash table of event types for the element
			if (!element.events) element.events = {};
			// create a hash table of event handlers for each element/event pair
			var handlers = element.events[type];
			if (!handlers) {
				handlers = element.events[type] = {};
				// store the existing event handler (if there is one)
				if (element["on" + type]) {
					handlers[0] = element["on" + type];
				}
			}
			// store the event handler in the hash table
			handlers[handler.$$guid] = handler;
			// assign a global event handler to do all the work
			element["on" + type] = OneWeb.Util._handleEvent;
		}
	},

	// --------------------------------------------------------------------------------
	// removeEvent()
	"removeEvent": function(element, type, handler, useCapture) {
		/// <summary>Attach an event handler to an element.</summary>
		/// <param name="element">element to remove event handler from [object]</param>
		/// <param name="type">event to handle (i.e. "load", "click") [string]</param>
		/// <param name="handler">function which handled the event [function]</param>
		/// <param name="useCapture"> use Event capturing model? [boolean]</param>
		/// <remarks>Based on a version of addEvent/removeEvent created by Dean Edwards (http://dean.edwards.name/weblog/2005/10/add-event/)
		/// and Tino Zijdel (http://therealcrisp.xs4all.nl/upload/addEvent_dean.html)</remarks>
		/// <returns>void</returns>
		if (element.removeEventListener) {
			element.removeEventListener(type, handler, useCapture);
		} else {
			// delete the event handler from the hash table
			if (element.events && element.events[type] && handler.$$guid) {
				delete element.events[type][handler.$$guid];
			}
		}
	},

	"getEvent": function(event) {
		///<summary>Used to retrieve the event object from IE</summary>
		return event || OneWeb.Util._fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
	},

	// --------------------------------------------------------------------------------
	// _handleEvent()
	"_handleEvent": function(event) {
		/// <summary>Used internally to handle events in a standard fasion in non-standard browsers (IE).</summary>
		var returnValue = true;
		// grab the event object (IE uses a global event object)
		event = OneWeb.Util.getEvent(event);
		// get a reference to the hash table of event handlers
		var handlers = this.events[event.type];
		// execute each event handler
		for (var i in handlers) {
			if (!Object.prototype[i]) {
				this.$$handleEvent = handlers[i];
				if (this.$$handleEvent(event) === false) {
					returnValue = false;
					break;
				}
			}
		}
		// detach last event handler from the element
		if (this.$$handleEvent)
			this.$$handleEvent = null;
		return returnValue;
	},

	"_fixEvent": function(event) {
		/// <summary>Used internally to add W3C standard event methods to IE event objectss.</summary>
		event.preventDefault = function() { this.returnValue = false; };
		event.stopPropagation = function() { this.cancelBubble = true; };
		event.target = event.srcElement;
		if (event.target !== null && event.target.nodeType == 3)
			event.target = event.target.parentNode;  // defeat Safari bug with text nodes incorrectly receiving target status
		return event;
	},

	"failEvent": function(e, test) {
		///<summary>Causes an event to be cancelled and returns the false value too.</summary>
		///<param name="e" type="Sys.EventArgs">Event object to be cancelled</param>
		///<param name="e" type="boolean">Optional test result to determine if the event should be cancelled.  If provided and true, the event will not be cancelled.</param>
		if (typeof (test) === "boolean" && test)
			return;
		else if (typeof (test) === "function" && test())
			return;

		if (e)
			OneWeb.Util.preventDefault(e);
		return false;
	},

	// --------------------------------------------------------------------------------
	// appendLoadEvent()
	"appendLoadEvent": function(f) {
		/// <summary>Append a function to be executed when the onload event fires.</summary>
		/// <param name="f">function to be appended [function]</param>
		/// <returns>void</returns>
		OneWeb.Util.addEvent(window, "load", f);
	},

	// --------------------------------------------------------------------------------
	// appendUnloadEvent()
	"appendUnloadEvent": function(f) {
		/// <summary>Append a function to be executed when the onunload event fires.</summary>
		/// <param name="f">function to be appended [function]</param>
		/// <returns>void</returns>
		OneWeb.Util.addEvent(window, "unload", f);
	},

	// --------------------------------------------------------------------------------
	// appendInitEvent()
	"appendInitEvent": function(f) {
		/// <summary>Appends a function to be executed when the DOM if fully initialised.  This method
		///	simply adds the function pointer to the queue of other initializers.</summary>
		/// <param name="f">function to be appended [function]</param>
		/// <returns>void</returns>
		OneWeb.Util.addEvent(window, "load", f);
		/*	IE is having a hard time with hard-refreshes not running these scripts
		OneWeb.Util._loadAfterInitQueue.push(f);
		if (!OneWeb.Util._pollForDOMInterval)
		OneWeb.Util._runInitMethods();
		*/
	},

	// --------------------------------------------------------------------------------
	// _isDOMInitialized()
	"_isDOMInitialized": function() {
		/// <summary>Checks to see if the DOM is initialized (full DOM hierarchy created).</summary>
		/// <returns>boolean</returns>
		return (typeof document.getElementsByTagName != "undefined"
				&& (document.getElementsByTagName("body")[0] != null || document.body != null));
	},

	// --------------------------------------------------------------------------------
	// _pollForDOM()
	"_pollForDOM": function() {
		/// <summary>Polls the DOM for full initialization (full DOM hierarchy created).</summary>
		/// <returns>void</returns>
		OneWeb.Util._pollForDOMCounter++;
		if (OneWeb.Util._isDOMInitialized()) {
			OneWeb.Util._runInitMethods();
			window.clearInterval(OneWeb.Util._pollForDOMInterval);
			OneWeb.Util._pollForDOMInterval = null;
		} else if (OneWeb.Util._pollForDOMCounter == 10) {
			// reset the interval to 250ms from 50 ms
			window.clearInterval(OneWeb.Util._pollForDOMInterval);
			OneWeb.Util._pollForDOMInterval = window.setInterval(OneWeb.Util._isDOMInitialized, 250);
		} else if (OneWeb.Util._pollForDOMCounter >= 60) {
			// reset the interval to 1 sec
			window.clearInterval(OneWeb.Util._pollForDOMInterval);
			OneWeb.Util._pollForDOMInterval = window.setInterval(OneWeb.Util._isDOMInitialized, 1000);
		}
	},

	// --------------------------------------------------------------------------------
	// _runInitMethods()
	"_runInitMethods": function() {
		/// <summary>Runs the initialization methods.</summary>
		/// <returns>void</returns>
		for (var i = 0; i < OneWeb.Util._loadAfterInitQueue.length; i++) {
			try {
				OneWeb.Util._loadAfterInitQueue[i]();
			} catch (ex) {
				var fn = OneWeb.Util._loadAfterInitQueue[i] + "";
				fn = fn.substring(fn.indexOf(" ") + 1, fn.indexOf("("));
				alert("ERROR!\nThe function " + fn + "() was found in the DOM queue but could not be executed.\n" + ex.description);
			}
		}
		OneWeb.Util._loadAfterInitQueue.length = 0;
	},

	// --------------------------------------------------------------------------------
	// stopEventProp()
	"stopEventProp": function(e) {
		/// <summary>Prevent triggered events from propogating to parent elements.
		///	<param name="e">triggered event [object]</param>
		/// <returns>void</returns>
		if (!e) e = window.event;
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
		return true;
	},

	// --------------------------------------------------------------------------------
	// preventDefault()
	"preventDefault": function(e) {
		/// <summary>Prevent triggered events from executing their default action.</summary>
		///	<param name="e">triggered event [object]</param>
		/// <returns>void</returns>
		if (!e) e = window.event;
		if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; }
	},

	// --------------------------------------------------------------------------------
	// addSubmitEvent()
	"addSubmitEvent": function(elm, fn) {
		/// <summary>Attach an osubmit event handler.</summary>
		/// <param name="elm">form element to assign event handler to [object]</param>
		/// <param name="fn">function which will handle the event [function]</param>
		/// <returns>void</returns>
		var _fn = function(e) { var r = fn(e); if (r === false) e.preventDefault(); return r; }
		OneWeb.Util.addEvent(elm, "submit", _fn);
	},

	// --------------------------------------------------------------------------------
	// trapEnterKey()
	"addEnterKeyEvent": function(elm, fn) {
		/// <summary>Attach an event handler to a field specifically for the enter key.</summary>
		/// <param name="elm">form element to assign event handler to [object]</param>
		/// <param name="fn">function which will handle the event [function]</param>
		/// <returns>void</returns>

		var _fn = function(e) {
			var code;
			if (!e) e = window.event;
			if (e.keyCode) code = e.keyCode;
			else if (e.which) code = e.which;

			if (code == 13) {
				return fn.apply(this, arguments);
			}
		}
		OneWeb.Util.addEvent(elm, "keypress", _fn, false);
	},

	// --------------------------------------------------------------------------------
	// detachEvents()
	"detachEvents": function(elm) {
		/// <summary>Detaches all event handlers from an element and its children.</summary>
		/// <param name="elm">element to detach event handlers from [object]</param>
		/// <returns>void</returns>
		if (!elm)
			return;

		var a = elm.attributes, i, l, n;
		if (a) {
			l = a.length;
			// changed to reverse order of attribute selection in case attributes renumber when setting value to null
			for (i = l - 1; i >= 0; i--) {
				n = a[i].name;
				if (typeof elm[n] === "function") {
					elm[n] = null;
				}
			}
		}
		a = elm.childNodes;
		if (a) {
			l = a.length;
			for (i = 0; i < l; i++) {
				OneWeb.Util.detachEvents(elm.childNodes[i]);
			}
		}
	},

	"removeElement": function(elm) {
		/// <summary>Detaches all event handlers from an element and its children, and then removes the element from its parent if attached.</summary>
		/// <param name="elm">element to remove.</param>
		/// <returns>element removed</returns>
		if (!elm)
			return;
		OneWeb.Util.detachEvents(elm);
		return (elm.parentNode ? elm.parentNode.removeChild(elm) : elm);
	},

	// --------------------------------------------------------------------------------
	// getElementsByClassName()
	"getElementsByClassName": function(cls, tag, elm) {
		/// <summary>Find all elements in the document with the specified CSS class attribute.</summary>
		///	<param name="cls">class name to be searched for [string]</param>
		///	<param name="tag">search for specific tags with given class, or "*" for all [string]</param>
		///	<param name="elm">element to search within, or empty for document [element]</param>
		/// <returns>all elements with the specified class [array]</returns>
		/// --------------------------------------------------------------------------------
		var arr = [], j = 0, i;
		if (!elm) elm = document;
		var elms = elm.getElementsByTagName(tag);

		var re = new RegExp("(^|\\s)" + cls + "(\\s|$)", "i");
		for (i = 0; i < elms.length; i++) {
			if (re.test(elms[i].className))
				arr[arr.length] = elms[i];
		}
		return arr;

	},

	"hasClass": function(elm, cls) {
		/// <summary>Checks an element to see if it has a css class.</summary>
		/// <param name="elm">element to check.</param>
		///	<param name="cls">class name to be checked for [string]</param>
		/// <returns>boolean</returns>
		/// --------------------------------------------------------------------------------
		return elm !== null ? (elm.className.search("(^|\\s)" + cls + "(\\s|$)") > -1) : false;
	},

	"addClass": function(elm, cls) {
		/// <summary>Adds a css class to an element.</summary>
		/// <param name="elm">element to update.</param>
		///	<param name="cls">class name to be added [string]</param>
		/// <returns>void</returns>
		/// --------------------------------------------------------------------------------
		if (elm === null)
			return;
		if (elm.className.search("(^|\\s)" + cls + "(\\s|$)") === -1)
			elm.className = (elm.className + " " + cls).replace(/(^\s+)|(\s+(?=\s\b))|(\s+$)/, "");
	},

	"removeClass": function(elm, cls) {
		/// <summary>Removes a css class from an element.</summary>
		/// <param name="elm">element to update.</param>
		///	<param name="cls">class name to be removed [string]</param>
		/// <returns>void</returns>
		/// --------------------------------------------------------------------------------
		if (elm === null)
			return;
		elm.className = elm.className.replace(new RegExp("(^|\\s)" + cls + "(?:\\s|$)"), "$1");
	},

	"toggleClass": function(elm, cls) {
		/// <summary>Adds or Removes a css class from an element.</summary>
		/// <param name="elm">element to check.</param>
		///	<param name="cls">class name to be checked for [string]</param>
		/// <returns>boolean</returns>
		/// --------------------------------------------------------------------------------
		if (elm === null)
			return;
		(elm.className.search("(^|\\s)" + cls + "(\\s|$)") > -1) ? OneWeb.Util.removeClass(elm, cls) : OneWeb.Util.addClass(elm, cls);
	},

	// --------------------------------------------------------------------------------
	// getTotalOffset()
	"getTotalOffset": function(elm, off) {
		/// <summary>Compute the total offset of an element from the top-left corner of the screen.</summary>
		/// <param name="elm">element to calculate the offset for [object]</param>
		/// <param name="off">type of offset to calculate (i.e. "offsetLeft", "offsetTop") [string]</param>
		/// <returns>total calculated offset for specified element [integer]</returns>
		var totalOffset = 0;
		var item = eval("elm");

		do {
			totalOffset += eval("item." + off);
			item = eval("item.offsetParent");
		} while (item != null);
		return totalOffset;
	},

	// getElementStyle()
	"getElementStyle": function(elm, prop) {
		/// <summary>Get current value of a CSS style property for a specified element.</summary>
		///	<param name="elm">element to find a style for [object]</param>
		///	<param name="prop">name of property to find value for (i.e. "margin-top") [string]</param>
		/// <returns>current value of specified property [string]</returns>
		if (window.getComputedStyle) {
			return window.getComputedStyle(elm, null).getPropertyValue(prop);
		} else if (elm.currentStyle) {
			var ieProp = "";
			for (var i = 0; i < prop.length; i++) {
				if (prop.charAt(i) == "-") {
					i++;
					ieProp += prop.charAt(i).toUpperCase();
				} else {
					ieProp += prop.charAt(i);
				}
			}
			return elm.currentStyle[ieProp];
		}
	},

	// autoFocus()
	"autoFocus": function(input) {
		///<summary>Checks for the HTML5 autofocus input element property, and if not available or not set, then focusses to the element.</summary>
		if (!input) return;	// return if input not set
		if ("autofocus" in document.createElement("input") && input.autofocus) return;	// return if HTML5 support included and set on field already
		if ("focus" in input) input.focus();
	},

	// compareRanges - compares two text range boundaries in browser-compliant fashion
	"compareRanges": function(range1, range2, comparison) {
		///<summary>Compares to Text ranges to each other.</summary>
		///<param name="range1">The range to compare against</param>
		///<param name="range2">The range to compare with</param>
		///<param name="comparison">The boundaries of the range to compare:  StartToStart (0), StartToEnd (1), EndToEnd (2), EndToStart (3), or Both (undefined)</param>
		///<returns>Returns -1 if the range1 boundary is to the left of range2, 0 if the boundaries coincide, 
		/// and 1 if the range1 boundary is to the right of the range2 boundary</returns>
		if (!range1 || !range2)
			throw "Ranges not specified.";
		if (!comparison || comparison == "Both") {
			// compare ranges for equality
			comparison = "StartToStart";
			var result = OneWeb.Util.compareRanges(range1, range2, comparison);
			if (result == 0) {
				comparison = "EndToEnd";
				result = OneWeb.Util.compareRanges(range1, range2, comparison);
			}
			return result;

		} else {
			if (range1.compareBoundaryPoints) {
				// W3 standard method
				switch (comparison) {
					case "StartToStart": comparison = Range.START_TO_START; break;
					case "StartToEnd": comparison = Range.START_TO_END; break;
					case "EndToEnd": comparison = Range.END_TO_END; break;
					case "EndToStart": comparison = Range.END_TO_START; break;
					default: comparison = Range.START_TO_START;
				}
				// perform the comparison
				return range1.compareBoundaryPoints(comparison, range2);
			} else if (range1.compareEndPoints) {
				// IE method
				switch (comparison) {
					case 0: comparison = "StartToStart"; break;
					case 1: comparison = "StartToEnd"; break;
					case 2: comparison = "EndToEnd"; break;
					case 3: comparison = "EndToStart"; break;
					default: comparison = "StartToStart";
				}
				// perform the comparison
				range1.compareEndPoints(comparison, range2);
			} else
				throw "Range1 is invalid.";
		}
		return;
	},

	//parseTemplate
	"parseTemplate": function(elm, data) {
		/// <summary>Parse a client-side template contained within the a specified element, and optionally binding a JSON data object to it.</summary>
		///	<param name="elm">element or id containing the template string to parse[object]</param>
		///	<param name="data">JSON-formatted data object to bind to the template[object]</param>
		/// <returns>If no data is submitted, then the template is parsed and returned as a function.  If
		/// a data object is provided the templated is bound to the data and returned as a string [function/string]</returns>
		/// <remarks>Based on the micro-template script developed by John Resig (http://ejohn.org/blog/javascript-micro-templating/)
		/// and tweaked by Rick Strahl (http://www.west-wind.com/Weblog/posts/509108.aspx)

		var OU = OneWeb.Util;

		// create the function cache for the template
		if (!OU._templateCache) OU._templateCache = {};

		var err = "";
		try {
			// checks if we've got an id, a string value, or an element
			var fn = (typeof elm == "string") ?
                (!/^[A-Za-z][A-Za-z0-9:_.-]*$/.test(elm)) ?
                new Function("obj",
                "var p=[];" + // debugging code "var p=[],print=function(){p.push.apply(p,arguments);};" +
                            "with(obj){p.push('" +
                elm.replace(/[\r\t\n]/g, " ")
                   .replace(/'(?=[^#]*#>)/g, "\t")
                   .split("'").join("\\'")
                   .split("\t").join("'")
                   .replace(/<#=(.+?)#>/g, "',$1,'")
                   .split("<#").join("');")
                   .split("#>").join("p.push('")
                   + "');}return p.join('');") :
			// if we have an id, recall the function and cache the result
            (OU._templateCache[elm] || OU.parseTemplate(document.getElementById(elm))) :

			// generate the reusable function and cache it (we only cache when an element is submitted)
            (OU._templateCache[elm.id] =
                OU._templateCache[elm.id] || OU.parseTemplate(elm.innerHTML));

			//alert(fn.toString());

			// curry the return value
			return data ? fn(data) : fn;
		} catch (e) { err = e.message; }
		if (typeof (Sys) !== "undefined" && typeof (fn) !== "undefined") Sys.Debug.traceDump(fn.toString());
		return "< # ERROR: " + err.toString() + " # >";

	},

	// gets the local time zone in a javascript object similar to the server-side TimeZoneInfo object
	"getLocalTimeZoneInfo": function() {
		///<summary>Determines information about the user's timezone using the browser's Date object</summary>
		///<returns>An object that contains timezone information for the user's local computer.</returns>

		// get the time zone offsets for the user
		var year = new Date().getFullYear();
		var jan1 = new Date(year, 0, 1);
		var jun1 = new Date(year, 6, 1);
		var jan1Offset = jan1.getTimezoneOffset();
		var jun1Offset = jun1.getTimezoneOffset();
		var nameRegex = /(?:(\S*)|(?:(?:\()([^)]*)(?:\))))$/;

		// standard time is the time whose offset is lower than daylight savings time (DST by definition adds time to the offset; js offset is negative of what it should be)
		var std = (jan1Offset >= jun1Offset) ? jan1 : jun1;

		var name = std.toTimeString().match(nameRegex);
		var timeZone = {
			standardName: name[1] + name[2],
			daylightName: "",
			baseOffset: -std.getTimezoneOffset(),
			adjustment: null
		};
		if (jan1Offset !== jun1Offset) {
			// DST in effect
			var daylight = ((std === jan1) ? jun1 : jan1);
			name = daylight.toTimeString().match(nameRegex);
			timeZone.daylightName = name[1] + name[2];
			timeZone.adjustment = {
				delta: -(daylight.getTimezoneOffset() - std.getTimezoneOffset()),
				transitionStart: null,
				transitionEnd: null
			};

			// calculate the transition dates
			var date = new Date(jan1.valueOf());
			var offset = jan1Offset;
			var incr = initIncr = 64; // set an initial and current day increment in which we'll look for the time zone offset change

			while (date.getFullYear() === year) {
				if (date.getTimezoneOffset() !== offset) {
					if (incr > 1) {
						// a transition has occurred, but we're still incrementing over a day - > reverse and decrease the increment
						// essentially this performs a binary search for the transition date until the increment is only a day
						date.setDate(date.getDate() - incr);
						incr = (incr > 2) ? Math.abs(incr / 2) : 1;
					} else {
						// a transition has occurred over a day - store the offset change and reset back a day 
						var delta = Math.abs((date.getTimezoneOffset() - offset) / 60);
						date.setDate(date.getDate() - 1);

						// determine if this is a fixed or floating transition by checking the date in 2 years to see if it occurs on the same date
						var isFixedDate = (new Date(year + 2, date.getMonth(), date.getDate()).getTimezoneOffset() !== new Date(year + 2, date.getMonth(), date.getDate() + 1).getTimezoneOffset());

						// store the transition date as the Month, Week, and Day of Week
						var transition = {
							month: date.getMonth() + 1,
							week: Math.floor(date.getDate() / 7) + 1,
							day: date.getDate(),
							dayOfWeek: date.getDay(),
							hour: 0,
							isFixedDate: isFixedDate
						};

						// enumerate the hours until we cross the transition again
						date.setHours(0);
						while (date.getHours() + delta < 24) {
							var hour = date.getHours();
							date.setHours(hour + delta);
							if (date.getHours() != hour + delta || date.getTimezoneOffset() !== offset) {
								// hour addition didn't occur properly or the offset changed - marks the transition hour; increment the date to the next day and check the offset time
								date.setDate(date.getDate() + 1);

								// set the hour of the transition, and determine if this is the start or the end transition
								transition.hour = hour + delta;
								if (date.getTimezoneOffset() === daylight.getTimezoneOffset())
									timeZone.adjustment.transitionStart = transition;
								else
									timeZone.adjustment.transitionEnd = transition;

								// break out of the hour loop back to the day loop
								if (date < jun1) {
									// we've only found the first transition - set the date to the second half of the year and reset the increment
									date = new Date(jun1.valueOf());
									offset = date.getTimezoneOffset();
									incr = initIncr;
								} else {
									// we've found both transitions
									return timeZone;
								}
								break;
							}
						}
					}
				}
				// increment the day
				date.setDate(date.getDate() + incr);
			}
		}
		return timeZone;
	},

	// --------------------------------------------------------------------------------
	// runInitializers()
	"runInitializers": function() {
		/// <summary>Run the initialization functions, or schedule them for running.</summary>
		/// <returns>void</returns>
		if (OneWeb.Util._isDOMInitialized())
			OneWeb.Util._runInitMethods()
		else
			OneWeb.Util._pollForDOMInterval = window.setInterval(OneWeb.Util._pollForDOM, 50);
	},

	"_getEngineVersion": function() {
		var engine = { name: null, version: null, major: 0, minor: 0, revision: 0, build: 0, prerelease: "", flash: null };
		var ua = navigator.userAgent.toLowerCase();
		var engRegex = null;
		var flashDescrip = "0 r0";
		if (ua.match(/rv\:[^)]+\).*gecko\/\d{8}/) != null) {
			// Mozilla-based browsers
			engine.name = "Gecko"
			engRegex = /rv\:([^)]+)\)/;
			try { flashDescrip = navigator.plugins["Shockwave Flash"].description; } catch (e) { };
		} else if (ua.match(/msie [\d\.\w]+;.*windows/) != null) {
			// IE
			engine.name = "Trident";
			engRegex = /msie\s+([\d\.\w]+);/;
			try { flashDescrip = new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version"); } catch (e) { };
		} else if (ua.match(/applewebkit\/[\d\.\w]+ /) != null) {
			// Safari, Chrome, Konqueror
			engine.name = "WebKit";
			engRegex = /applewebkit\/([\d\.\w]+)\s/;
			try { flashDescrip = navigator.plugins["Shockwave Flash"].description; } catch (e) { };
		} else if (ua.match(/opera[\/ ][\d\.\w]+/) != null) {
			// Opera
			engine.name = "Presto";
			engRegex = /opera[\/ ]([\d\.\w]+)/;
			try { flashDescrip = navigator.plugins["Shockwave Flash"].description; } catch (e) { };
		}
		if (engRegex != null) {
			var version = engRegex.exec(ua);
			if (version != null) {
				engine.version = version[1];
				engine.versionParts = engine.version.split(".");
				for (var i = 0; i < engine.versionParts.length; i++) {
					if (engine.versionParts[i] == null)
						engine.versionParts[i] = "";
					var part = parseInt(engine.versionParts[i]);
					if (isNaN(part))
						part = 0;
					switch (i) {
						case 0: engine.major = part; break;
						case 1: engine.minor = part; break;
						case 2: engine.revision = part; break;
						case 3: engine.build = part; break;
					}
					// check for pre-release signature
					if (i == engine.versionParts.length - 1 && engine.versionParts[i].length > 0 && (engine.versionParts[i] != part.toString() || part == 0))
						engine.prerelease = engine.versionParts[i].substr(part.toString().length);
				}
				engine.toString = function() { return this.name + ":" + this.version; }
			}
		}
		var flashVer = flashDescrip.match(/\d+/g);
		engine.flash = { version: parseInt(flashVer[0] || 0 + "." + flashVer[1] || 0), build: parseInt(flashVer[2] || 0) };
		OneWeb.Util.appendInitEvent(function() {
			// determine if the W3C CSS box model is supported
			var div = document.createElement("div");
			div.style.width = div.style.paddingLeft = "1px";
			document.body.appendChild(div);
			engine.boxModel = (div.offsetWidth === 2);
			document.body.removeChild(div).style.display = 'none';
		});

		return engine;
	}
};

//shims
var ow_f_AppendInitEvent = OneWeb.Util.appendInitEvent;
var ow_f_AppendLoadEvent = OneWeb.Util.appendLoadEvent;
var ow_f_AppendUnloadEvent = OneWeb.Util.appendUnloadEvent;
var ow_f_AddEvent = OneWeb.Util.addEvent;
var ow_f_RemoveEvent = OneWeb.Util.removeEvent;
var ow_f_GetElementsByClassName = OneWeb.Util.getElementsByClassName;
var ow_f_GetTotalOffset = OneWeb.Util.getTotalOffset;
var ow_f_GetElementStyle = OneWeb.Util.getElementStyle;
var ow_f_StopEventProp = OneWeb.Util.stopEventProp;
var ow_f_PreventDefault = OneWeb.Util.preventDefault;


// default initialization functions

// --------------------------------------------------------------------------------
// searchOnEnter()
OneWeb._searchOnEnter = function(e) {
    /// <summary>Click the corresponding search button when [ENTER] is pressed.</summary>
    /// <param name="e">event object</param>
    /// <returns>void</returns>
    var code;
    if (!e) e = window.event;
    if (e.keyCode) code = e.keyCode;
    else if (e.which) code = e.which;

    if (code == 13) {
        var elm = null;
        if (e.target) elm = e.target;
        else elm = e.srcElement;
        var btn = document.getElementById((elm.id).replace("ow_txt", "ow_btn"));
        if (btn) {
            btn.click();
            if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
        } else {
            var img = document.getElementById((elm.id).replace("ow_txt", "ow_img"));
            if (img) {
                img.click();
                if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
            }
        }
    }
}

// --------------------------------------------------------------------------------
// initSearchBox()
OneWeb._initSearchBox = function() {
    /// <summary>Find all search textfields and wire up the [ENTER] key to submit the form properly.</summary>
    /// <returns>void</returns>
    var txt;
    var inp = OneWeb.Util.getElementsByClassName("ow_sbox", "input");
    for (var i = 0; i < inp.length; i++) {
        if (inp[i].id.indexOf("ow_txtSearch") != -1) {
            OneWeb.Util.addEvent(inp[i], "keypress", OneWeb._searchOnEnter, false);
        }
    }
}

// --------------------------------------------------------------------------------
// _initAutoComplete()
OneWeb._initAutoComplete = function() {
    /// <summary>Find all hidden input fields and disable the autocomplete, which tends to 
    /// screw up event validation by maintaining stale values in ajax scenarios.</summary>
    /// <returns>void</returns>
    var inputs = document.getElementsByTagName("INPUT");
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].getAttribute("type") == "HIDDEN")
            inputs[i].setAttribute("autocomplete", "off");
    }
}

OneWeb._initFlashObjects = function() {
	///<summary>Find all flash object tags and initialize them using SWFObject</summary>
	if (typeof (swfobject) !== "undefined") {
		var OU = OneWeb.Util;
		var objects = document.getElementsByTagName("object");
		for (var i = 0, l = objects.length; i < l; i++) {
			var obj = objects[i];
			if (obj.id.length > 0 && OU.hasClass(obj, "ow_swf")) {
				swfobject.registerObject(obj.id, "6");
			}
		}
	}
}
// --------------------------------------------------------------------------------
// Initialize()
/// <summary>Initializes the OneWeb javascript</summary>
/// <returns>void</returns>
OneWeb.initialize = function() {
    OneWeb.Util.engine = OneWeb.Util._getEngineVersion();
    OneWeb.Util.appendInitEvent(OneWeb._initSearchBox);
	//OneWeb.Util.appendInitEvent(OneWeb._initFlashObjects);	// TM - swfobject calls must be made before the object tags are loaded
    OneWeb.Util.runInitializers();

    // This little snippet fixes the problem that the onload attribute on the body-element will overwrite
    // previous attached events on the window object for the onload event
    if (!window.addEventListener) {
        document.onreadystatechange = function() {
            if (window.onload && window.onload != OneWeb.Util._handleEvent) {
                OneWeb.Util.addEvent(window, 'load', window.onload);
                window.onload = OneWeb.Util._handleEvent;
            }
        }
    }
}

// --------------------------------------------------------------------------------
// immediate calls

OneWeb.initialize();
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();/* 6.0.3887 */ 

