// Enable background image caching for IE6
try {
	document.execCommand("BackgroundImageCache", false, true);
} catch(err) {}

// Prevent IE from breaking w/ console.logs
if(typeof console == 'undefined'){
	console = {
		log: function(){}
	};
}

// Register the namespaces
Type.registerNamespace('MSVideo');
Type.registerNamespace('Csp');
(function(){
	
	// Cache ASP.NET Ajax Methods
	var $dom = Sys.UI.DomElement; 
	var $event = Sys.UI.DomEvent;
	var $ajax = Sys.Net;	
	var $delegate = Function.createDelegate;
	
	// Shorthand for browser agents
	var browser = Sys.Browser;
	var agent = Sys.Browser.agent;
	
	/**
		Short hand for accessing all common utilities needed for the dom elements
		@static
		@param elements {String | HTMLElement | MSAjaxWrapper | HTMLElement[] | String[] | MsAjaxWrapper[]} An element id, element reference, or MSAjaxWrapper instance			
		@return Sys.$.MSAjaxWrapper        
		@type Sys.$.MSAjaxWrapper        
	*/
	Sys.$ = function(element)
	{
		// So you don't have to use the new keyword whenever you create a object
		var elem = (element instanceof Sys.$.MSAjaxWrapper) ? element : new Sys.$.MSAjaxWrapper(element);		
		
		// Make sure if the element can't be found (a bad id was passed in, we return null)
		return elem.length > 0 ? elem : null;
	};
	
	/**
		Shorthand for accessing common utilities needed for silverlight xaml elements
		@static
		@param elements { XamlElement | SilverlightWrapper | XamlElement[] | SilverlightWrapper[]} An element reference, or SilverlightWrapper instance
		@return Sys.$.SilverlightWrapper        
		@type Sys.$.SilverlightWrapper 
	*/
	Sys.xaml = function(element)
	{	
		// So you don't have to use the new keyword whenever you create a object
		var elem = (element instanceof Sys.$.SilverlightWrapper) ? element : new Sys.$.SilverlightWrapper(element);		
		
		// Make sure if the element can't be found (a bad id was passed in, we return null)
		return elem.length > 0 ? elem : null;
	};
	
	/**
		Copies the properties from one object to another
		@static
		@param obj1 {Object} The object to copy the properties to
		@param obj2 {Object} The object to copy the properties from
	*/
	Sys.$.mix = function()
	{
		var args = arguments;
		var len = args.length;
		var src;
		
		// If one parameter is passed in, extend Sys.$
		if(len == 1){
			args = [this, args[0]];			
			len++;
		}
		
		var obj = args[0];
		var propObj;
		// Merge properties from right to left
		for(var i=len-1; i > 0; i--)
		{
			src = args[i];
			for(var property in src)
			{
				propObj = src[property];
				// Don't copy undefined values (nulls are ok).  Prevent infinite recursion for circular references
				if(propObj != undefined && propObj != null && propObj != obj)
				{
					if(typeof(propObj) == 'object' && obj[property])
					{
						 Sys.$.mix(obj[property], propObj);
					}
					else
					{
						obj[property] = propObj;
					}
				}
			}
		}		
		
		return obj;
	};
	
	/**
		Wrapper object that contains all the common MicrosoftAjax utilities, e.g. Dom utilities, event utilities, ajax utilities, etc.
		@class
		@constructor
		@param elements {String | HTMLElement | MSAjaxWrapper | HTMLElement[] | String[] | MsAjaxWrapper[]} An element id, element reference, or MSAjaxWrapper instance			
	*/	
	Sys.$.MSAjaxWrapper = function(elements)	
	{
		elements = elements || [];			
		// An id was passed
		if(typeof elements == 'string')
		{
			elements = [$get(elements)];				
		}
		else if (elements.tagName == "FORM") {				
			elements = [$get(elements.name)];
		}
		else if(elements.length == undefined || elements == window || elements == document)
		{
			elements = [elements];
		}												
		
		// Add references to the appropriate instance
		for(var i=0, len= this.length =elements.length; i < len; i++)
		{
			this[i] = typeof(elements[i]) == 'string' ? $get(elements[i]) : elements[i];
		}
	};
		
	Sys.$.MSAjaxWrapper.prototype = {
		/*	=======================
			BEGIN DOM METHODS
			======================= */
		
		// Add elements
		add: function(element)
		{
			this[this.length] = Sys.$(element)[0];
			this.length++;
		},
		
		children: function(fn)
		{	
			// Create a dummy instance of a MSAjaxWrapper
			var children = new Sys.$.MSAjaxWrapper();
			var child;
			
			fn = fn || function(){return true};
			
			// Get the children of every element in the MsAjaxWrapper
			this.forEach(function(key, value){
				
				// Get the childNodes of each element
				var childNodes = value.childNodes;
				var child;
				for(var i=0, len=childNodes.length; i < len; i++)
				{
					child = childNodes[i];
					if(child.nodeType == 1 && fn(child))
					{
						children.add(child);
					}
				}
			});			
			
			return children;
		},
		
		forEach: function(fn)
		{
			return Sys.$.forEach(this, fn);
		},
		
		getAttribute: function(name)
		{			
			var attr = this[0][name] != undefined ? this[0][name] : this[0].getAttribute(name);
			return attr;
		},
		
		setAttribute: function(name, value)
		{
			return this.forEach(function(key, elem){
				elem[name] = value;		
			});
		},
		
		addClass: function(className)
		{
			return this.forEach(function(key, elem){					
				if(!$dom.containsCssClass(elem, className)){
					$dom.addCssClass(elem, className);
				}
			});
		},
		
		removeClass: function(className)
		{
			return this.forEach(function(key, elem){
				$dom.removeCssClass(elem, className);
			});			
		},
		
		hasClass: function(className)
		{
			var hasClass = false;
			this.forEach(function(key, elem){
				hasClass = $dom.containsCssClass(elem, className);
			});
			
			return hasClass;			
		},
		
		getBounds: function()
		{
			return $dom.getBounds(this[0]);
		},
		
		setLocation: function(x, y)
		{
			return this.forEach(function(key, elem){
				$dom.setLocation(elem, x, y);
			});
		},
		
		getAncestor: function(fn, total)
		{
			var anscestor = new Sys.$.MSAjaxWrapper();		
			var count = 1;
			total = total != undefined ? total : 20;
			this.forEach(function(key, elem){
				var parent = elem.parentNode;				
				while(parent != null && count < total)
				{
					if(fn(Sys.$(parent))){
						anscestor.add(parent);
						return true;
					}	
					count++;
					parent = parent.parentNode;
				}
			});
			
			return anscestor;
		},
		
		hide: function()
		{
			return this.style('display', 'none');
		},
		
		show: function()
		{			
			return this.style('display', 'block');
		},
		
		style: function(name, value)
		{
			if(value !== undefined)
			{
				return this.forEach(function(key, elem){
					elem.style[name] = value;
				});				
			}
			else
			{
				return this[0].style[name];
			}
		},
		
		setHtml: function(value)
		{	
			return this.forEach(function(key, elem){
				elem.innerHTML = value;
			});
		},
		getHtml: function()
		{
			return this[0].innerHTML;
		},
		/*	=======================
			END DOM METHODS
			======================= */		
		
		/*	=======================
			BEGIN EVENT HELPERS
			======================= */		
		on: function(name, callback)
		{
			return this.forEach(function(key, elem){
				$event.addHandler(elem, name, callback);
			});
		},
		
		removeHandler: function(name, fn)
		{
			return this.forEach(function(key, elem){
				$event.removeHandler(elem, name, fn);
			});
		},
		
		clearHandlers: function()
		{
			return this.forEach(function(key, elem){
				$event.clearHandlers(elem);
			});
		},
		/*	=======================
			END EVENT MANAGER
			======================= */	
			
		/*	=======================
			BEGIN ANIMATIONS (Expect the animation dependencies to be loaded)
			======================= */	
		fadeIn: function(oProps, fn)
		{	
			return this.fade(AjaxControlToolkit.Animation.FadeEffect.FadeIn, oProps, fn);
		},
		
		fadeOut: function(oProps, fn)
		{
			return this.fade(AjaxControlToolkit.Animation.FadeEffect.FadeOut, oProps, fn);
		},		
		
		/**
			Wrapper for fading 
			@param fadeType {AjaxControlToolkit.Animation.FadeEffect} The type of fade to do
			@param oProps {Object} Config object
				@prop minimumOpacity {Float} Value between 0 and 1
				@prop maximumOpacity {Float} Value between 0 and 1
				@prop duration {Float} Amount of time in seconds
				@prop forceLayoutInIE (optional) {Boolean} Whether to force IE to respect the has layout property
			@param fn {Function} Callback for when the animation is completed
			@return MSAjaxWrapper
		*/
		fade: function(fadeType, oProps, fn)
		{
			var relative = oProps.relative != undefined ? oProps.relative : true;			
			var fps = oProps.fps || 25;
			var forceLayoutInIE = oProps.forceLayoutInIE != undefined ? oProps.forceLayoutInIE : false;
			
			fn = fn || function(){};	
			
			switch(fadeType)
			{
				case AjaxControlToolkit.Animation.FadeEffect.FadeOut:
					fadeType = 'FadeOutAnimation';
					break;
				case AjaxControlToolkit.Animation.FadeEffect.FadeIn:
					fadeType = 'FadeInAnimation';				
			}
			
			return this.forEach(function(key, elem){				
				var anim = new AjaxControlToolkit.Animation[fadeType](
					elem, oProps.duration, 
					fps, oProps.effect, 
					oProps.minimumOpacity, oProps.maximumOpacity, forceLayoutInIE);
				anim.add_ended($delegate(elem, fn));
				anim.play();
			});
		},
		
		moveTo: function(oProps, fn)
		{
			var relative = oProps.relative != undefined ? oProps.relative : true;
			var units = oProps.units || 'px';
			var fps = oProps.fps || 25;
			
			fn = fn || function(){};	
			
			return this.forEach(function(key, elem){
				var anim = new AjaxControlToolkit.Animation.MoveAnimation(
					elem, oProps.duration, 
					fps, oProps.horizontal, 
					oProps.vertical, relative, 
					units);
				anim.add_ended($delegate(elem, fn));
				add.play();
			});
		}
		/**	=======================
			END ANIMATIONS
			======================= */		
	};
	
	/**
		Wrapper object that contains all the common MicrosoftAjax utilities, e.g. Dom utilities, event utilities, ajax utilities, etc.			
		@class
		@constructor
		@param elements { XamlElement | SilverlightWrapper | XamlElement[] | SilverlightWrapper[]} An element reference, or SilverlightWrapper instance
	*/
	Sys.$.SilverlightWrapper = function(elements)
	{
		elements = elements || [];
		// An id was passed			
		if(elements instanceof Array)
		{ 				
		}	
		else
		{
			elements = [elements];
		}			
		
		// Add references to the appropriate instance
		for(var i=0, len= this.length =elements.length; i < len; i++)
		{
			this[i] = elements[i];
		}
	};
	
	/** @scope Sys.$.SilverlightWrapper */
	Sys.$.SilverlightWrapper.prototype = {
		/**
			Show the xaml element
		*/
		show: function()
		{
			return this.set('Visibility', 'Visible');
		},
		
		/**
			Hide the xaml element
		*/	
		hide: function()
		{
			return this.set('Visibility', 'Collapsed');			
		},
		
		get: function(prop)
		{
			return this[0][prop];
		},
		
		set: function(prop, value)
		{
			return this.forEach(function(index, elem){				
				elem[prop] = value;
			});
		},
		
		forEach: function(fn)
		{
			return Sys.$.forEach(this, fn);
		}, 
		offset: function()
		{
			var elem = this[0];
			var x = elem['Canvas.Left'];
			var y = elem['Canvas.Top'];
			
			elem = elem.GetParent();
			while(elem != null)
			{
				x += elem['Canvas.Left'];
				y += elem['Canvas.Top'];
				elem = elem.GetParent();
			}
			return {x:x, y:y};
		}

	};
	
	// Add the core members
	Sys.$.mix(
	/** @scope Sys.$*/
	{
		/*	=======================
			BEGIN STATIC MEMBERS
			======================= */
		
		// Browser sniffing variables
		isIE: agent == browser.InternetExplorer,
		isFF: agent == browser.Firefox,
		isSafari: agent == browser.Safari,
		isOpera: agent == browser.Opera,
		
		head: document.getElementsByTagName('head')[0] || document.documentElement,	// The head should be avaliable if this script is loading		
		
		// Manage cookies
		cookies: {
			enabled:function(){return navigator.cookieEnabled;},
			getCookie:function(cookieName)
			{
				var cookies=document.cookie.split(';');
				var cookieNames=[];
				for(var i=0;i<cookies.length;i++)
				{
				var cookie=cookies[i].split('=');
				if(cookieName==cookie[0].trimStart())
				{return decodeURIComponent(cookie[1]);}
				}
				return null;
			},
			getCookies:function(){
				var cookies=document.cookie.split(';');
				var cookieJSON={};
				for(var i=0;i<cookies.length;i++)
				{
					var cookie=cookies[i].split('=');
					cookieJSON[cookie[0].trimStart()]=decodeURIComponent(cookie[1]);
				}
				return cookieJSON;
			},
			hasCookie:function(cookieName){
				var cookies=document.cookie.split(';');
				var cookieNames=[];
				for(var i=0;i<cookies.length;i++){
					var cookie=cookies[i].split('=');cookieNames.push(cookie[0].trimStart());
				}
				return Array.contains(cookieNames,cookieName);
			},
			removeCookie:function(cookieName){
				this.setCookie(cookieName,0,-1);
			},
			setCookie:function(cookieName,cookieValue,daysToLive){
				if(typeof(daysToLive) == 'undefined'){
					document.cookie=cookieName+"="+encodeURIComponent(cookieValue)+";";
				}
				else {
					var date=new Date();
					date.setTime(date.getTime()+daysToLive*24*60*60*1000);
					document.cookie=cookieName+"="+encodeURIComponent(cookieValue)+"; expires="+date.toGMTString();
				}					
			},
			setCookieForMSResearch:function(cookieValue,secToLive){
				var date=new Date();
				date.setTime(date.getTime() + (secToLive*1000));
				document.cookie="msresearch="+encodeURIComponent(cookieValue)+"; expires="+date.toGMTString()+"; path=/";
			}
		},
		/**
			Helper for iterating over a collection (in the spirit of jQuery's each)
			@static
			@param obj {Object | Array} The object to iterate over
			@param fn {Function} The callback function to call at every step			
		*/
		forEach: function(objs, fn)
		{
			var obj;
			if (objs.length == undefined)
			{
				for (var i in objs)
				{		
					obj = objs[i];
					fn.call(objs, i, obj);
				}
			}
			else
			{
				for (var i=0, len=objs.length; i < len; i++)
				{
					obj = objs[i];
					if (fn.call(objs, i, obj) === false) break;
				}
			}
			
			// For chainability
			return objs;
		},		
		
		/**
			Wrapper for making xhr requests 
			@static
			@param oProps {Object} Config object
				@prop method {String} GET or POST
				@prop url {String} Url of the service to call
				@prop callback {Object} Object that contains the success and failed callbacks
				@prop params {Object} Object to send as parameters					
			@return Sys.Net.WebRequest
		*/
		ajax: function(oProps)
		{
			var request = new Sys.Net.WebRequest();
			request.set_url(oProps.url);
			request.set_httpVerb(oProps.method);
			
			var bodyStr = [];
			var params = oProps.params || {};
			for(var name in params)
			{
				bodyStr.push(name + '=' + params[name]);
			}			
			request.set_body(bodyStr.join('&'));			
			oProps.callback.error = oProps.callback.error || function(){};
			
			request.add_completed(oProps.callback.success);
						
			request.invoke();			
			return request;
		},
		
		/**
			Wrapper for making xhr requests to return json
			@static
			@param oProps {Object} Config object
				@prop method {String} GET or POST
				@prop url {String} Url of the service to call
				@prop callback {Object} Object that contains the success and failed callbacks
				@prop params {Object} Object to send as parameters					
			@return Sys.Net.WebRequest
		*/
		getJson: function(oProps)
		{
			var obj = {
				method: oProps.method,
				url: oProps.url,
				callback: {
					success: function(req){
						var json;
						try {										
							eval('json=(' + req.get_responseData() + ')');
							oProps.callback.success(json, req);
						}catch(e){
							oProps.callback.error(e);
						}	
					},
					error: oProps.error
				},
				params: oProps.params
			};			
			
			try {
				return this.ajax(obj);
			}
			catch(e)
			{
				oProps.callback.error(e);
			}

			return null;
		},
		
		// Dyanmic Script loading components
		
		scripts: {},				// Hash of all the script urls either currently executing / executing
		scriptCallbackQueue: [],	// Queue of callbacks to load		
		
		/**
			Dynamically load scripts by appending script tags to a page.  All the callbacks are executed based on FIFO.  
			@static
			@param urls{String | Array}  The url (s)of the scripts to load
			@param fn (optional) {Function} The callback to execute when all the scripts have loaded			
		*/
		loadScript: function(urls, fn)
		{
			var script;
			var head = this.head;
			urls = typeof(urls) == 'string' ? [urls] : urls;			
			fn = fn || function(){};
			
			// Scripts are still loading.  Make sure we load everything in the queue based on method invokation order			
			if(this.scriptCallbackQueue.length > 0)
			{
				this.scriptCallbackQueue.push({
					fn: fn,
					urls: urls
				});
				return;
			}
			
			// Add all the scripts to the dom
			for(var i=0, len=urls.length; i < len; i++)
			{
				script = document.createElement('script');
				script.type = 'text/javascript';
				script.src = urls[i];				
				head.appendChild(script);
				
				this.scripts[urls[i]] = true;	// Cache all the urls so we have a record of loaded scripts
			}
			
			// Add the callback to the queue
			this.scriptCallbackQueue.push({
				fn: fn				
			});
			
			if(Sys.$.isIE)
			{
				script.onreadystatechange = function(){
					if(/loaded|complete/.test(this.readyState))
					{
						// yield control here just to be safe
						setTimeout(function(){
							Sys.$.scriptsLoaded();
						}, 0);
					}
				};
			}
			else
			{
				script = this.execScript('Sys.$.scriptsLoaded()');
			}
			
			head.appendChild(script);
		},
				
		/**
			@static
		*/
		scriptsLoaded: function()
		{
			if(this.scriptCallbackQueue.length == 0)
			{
				return;
			}
			
			var obj = this.scriptCallbackQueue.shift();
			
			// Execute the callback
			if(typeof(obj.urls) == 'undefined'){
				obj.fn();
			}
			else
			{
				this.loadScripts(obj.urls, obj.fn);
			}			
		},
		
		/**
			Executes javascript that needs to be added dynamically (e.g. script tags inside an innerHTML string)
			@static
			@param text {String} The text to load inside the script tag
			@param scriptAttr (optional) {Object} Contains all the attributes to set for the object
			@return {HtmlElement}
		*/
		execScript: function(text, scriptAttr)
		{
			// Inspired by jQuery 1.2.3 that was in turn "Inspired by code by Andrea Giammarchi
			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html"
			var script = document.createElement('script');
			scriptAttr = scriptAttr || {type: 'text/javascript'};		
			script.type = scriptAttr.type;
			if(typeof (scriptAttr.id) != 'undefined')
			{
				script.id = scriptAttr.id;
			}
			
			// IE won't let you add a text node to a script element
			if(Sys.$.isIE){
				script.text = text;
			}
			else{
				script.appendChild(document.createTextNode(text));
			}

			return script;
		},
		
		/**
			Animates a collection of storyboards
			@static
			@param {Object} [Object[]] Array of animation objects
				@param {Storyboard} storyboard The storyboard that should be animated
				@param {Function} [before] Executes before the animation begins
				@param {Function} [after] Executes after the animation finishes
			@param {Function} [complete] Executes after all the animations have completed
		*/
		animateXaml: function(anims, complete)
		{
			var sb;			
			
			// The object to return so that animations can be stopped and started at anypoint in the sequence
			var mgr = {
				current: null,				
				stop: function(){
					if(!this.current){
						return
					}
					this.current.storyboard.stop();
				},
				pause: function(){	
					this.current.storyboard.pause();
				},
				begin: function(){
					this.current.storyboard.begin();
				}
			};
			
			for(var i=0, len=anims.length; i < len; i++)
			{
				sb = anims[i];
				complete = complete || function(){};
				sb.next = anims.length < len + 1 ? anims[len+1] : false;				
				sb.token = sb.storyboard.AddEventListener('Completed', Function.createDelegate(sb, function(){
			
					// Remove the event listener
					this.storyboard.RemoveEventListener('Completed', this.token);
					
					if(this.after){
						this.after();
					}					
					
					// Finished with the last animation
					if(!this.next){
						complete.call(anims);
						return;
					}
					
					mgr.current = this.next;
					
					// Start the next animation
					this.next.before();
					this.next.storyboard.begin();
				}));
			}
			
			// Start the animations
			if(anims.length > 0)
			{
				mgr.current = anims[0];				
				if(mgr.current.before){
					mgr.current.before();
				}
				mgr.current.storyboard.begin();
			}
			
			return mgr;
		}
		/*	=======================
			END STATIC METHODS
			======================= */
	});
	
	// Set the cookies value for Csp for consistency
	Csp.Cookies = Sys.$.cookies;
	
	// Wrapper for finding out when the dom is ready
	(function(){
		var dEvent = [];		
		var isReady = false;
		var readyFn = function(){			
			if(isReady){return}	// Make sure only to fire once			
			isReady = true;
			Sys.$.forEach(dEvent, function(key, fn){
				fn();
			});			
		};
		
		/**
			Add callbacks that are executed when the DOM is ready
			@static
		*/
		Sys.$.onDomReady = function(fn)
		{	
			// The dom is already ready.  Just fire the function
			if(isReady){
				fn();
			}
			else{
				dEvent.push(fn);
			}
		};
		
		try
		{
			// Use the loaded event as a failsafe for all browsers			
			Sys.$(window).on('load', readyFn);
			
			// Browsers that support DOMContentLoaded			
			if (document.addEventListener){
				document.addEventListener('DOMContentLoaded', readyFn, false);				
			}			
			
			// Use the Diego Perini Solution for IE
			// http://javascript.nwbox.com/IEContentLoaded/
			if(Sys.$.isIE)
			{	
				(function(){
					if(isReady){return}
					try {
						// throws errors until after ondocumentready
						document.documentElement.doScroll('left');
						readyFn();
					} catch (e) {
						setTimeout(arguments.callee, 50);						
					}
				})();
			}			
		}catch(e){}
	})();
})();

(function(){
	
	/**
		Class for creating / managing custom events
		@class
		@constructor
		@param {Object} [scope] The scope to execute the callbacks
	*/
	MSVideo.CustomEvents = function(scope)
	{
		this.scope = scope || window;
		this._events = {};
	};
	
	/** @scope MSVideo.CustomEvents */
	MSVideo.CustomEvents.prototype = {
		add: function(name)
		{
			var e = this._events[name];
			if(!e){
				e = this._events[name] = [];
			}			
		},
		addHandler: function(name, fn)
		{
			this.add(name);			
			this._events[name].push(fn);			
			return this;
		},
		removeHandler: function(name, fn)
		{
			var callbacks = this._events[name] || [];
			for(var i=0,len=callbacks.length; i<len; i++)
			{
				if(callbacks[i] === fn)
				{
					callbacks.splice(i,1);
					break;
				}
			}
			return this;
		},
		clearHandlers: function()
		{
			this._events = {};
			return this;
		},
		fire: function(name, args)
		{
			var scope = this.scope;
			var callbacks = this._events[name] || [];
			args = args || [];
			for(var i=0,len=callbacks.length; i<len; i++)
			{
				callbacks[i].apply(scope, args);
			}
		},
		hasEvent: function(name)
		{
			return this._events[name] != undefined;
		}
	};
})();

(function(){
	var imgCache = [];
	// Global Initialization Functions	
	MSVideo.renewSession = function()
	{	
		/*
		if(MSVideo.isEmbed != undefined && MSVideo.isEmbed == true){return}
		if(!MSVideo.renewTimeout){return}
		
		// Add the session iframe to the page	
		var img = new Image(0,0);
		img.src = '/video/renewsession';
		
		imgCache.push(img.src);		
		*/
	};
})();

/**
	Initializes the video guide component
*/
MSVideo.initMenuGuide = function(elem)
{	
	// Clear the current onmouseover event handler so this function is only called once
	elem.onmouseover = null;
	
	var $menu = Sys.$(elem);	
	var showTimer;
	var hideTimer;		
	
	// Attach the event handlers now
	$menu.on('mouseover', function(){		
		if(hideTimer != undefined){
			clearTimeout(hideTimer);
			hideTimer = undefined;
		}
		var $me = Sys.$(this);
		if(!$me.hasClass('on'))
		{
			showTimer = setTimeout(function(){
				$me.addClass('on');
			}, 250);		
		}
	});
	
	$menu.on('mouseout', function(){
		if(showTimer != undefined){
			clearTimeout(showTimer);
			showTimer = undefined;
		}
		var $me = Sys.$(this);
		hideTimer = setTimeout(function(){
			$me.removeClass('on');
		}, 250);				
	});
	
	// Show the mouse over on the first attempt
	showTimer = setTimeout(function(){
		$menu.addClass('on');
	}, 250);
};

MSVideo.initSearchDefault = function(){
    var $searchInput = Sys.$('videoSearchField');

    $searchInput.on('focus', function(){
        $searchInput.removeClass("default");
        if ($searchInput[0].value == $searchInput[0].defaultValue) {
		    $searchInput[0].value = "";
		}
    });
    $searchInput.on('blur', function(){
        if ($searchInput[0].value == "") {
		    $searchInput.addClass("default");
            $searchInput[0].value = $searchInput[0].defaultValue;
        }
    });
}
/**
	Initializes the search scopes
*/
MSVideo.initSearchScope = function(searchArrow)
{	
	// Get rid of the search scope mouseover handler
	searchArrow.onmouseover = null;
    var inMouseOver  = false;
	Sys.$(searchArrow).addClass('searchHover');
	var searchScopeDropDown = {
	
		searchSelect: Sys.$('search_scope'),
		searchArrow: Sys.$(searchArrow),
		_selectedIndex: 0,
		get_selectedIndex: function(){return this._selectedIndex;},
		set_selectedIndex: function(value){this._selectedIndex = value; this.indexChanged(value);},
		indexChanged: function(value)
		{
			// Set the select selectedindex
			this.searchSelect[0].selectedIndex = value;
			this.selectedElem = this.searchSelect[0].options[value];
			
			// Hide the overlay
			$searchList.hide();			
		},
        get_selectedText: function(){return this.searchSelect[0].options[this._selectedIndex].text;}
	};
	
	var hideTimer;
	var showTimer;
	
	// The search Arrow
	var $searchArrow = searchScopeDropDown.searchArrow;
	
	// The list of search scopes
	var $searchList = Sys.$('search_scope_list');
	
	// Attach the event handlers to the search arrow
	$searchArrow.on('click', function(){
		if(hideTimer != undefined){
			clearTimeout(hideTimer);
			hideTimer = undefined;
		}
        inMouseOver = true;
        var $me = Sys.$(this);
		if(!$me.hasClass('on'))
		{
			showTimer = setTimeout(function(){
				$searchList.show();
			}, 250);
        }
    });

	$searchArrow.on('mouseover', function(){		
		var $me = Sys.$(this);
		$me.addClass('searchHover');		
	});
	
	$searchArrow.on('mouseout', function(){
        if(inMouseOver) return;
        if(showTimer != undefined){
			clearTimeout(showTimer);
			showTimer = undefined;
		}
		var $me = Sys.$(this);		
		hideTimer = setTimeout(function(){
			$searchList.hide();
			$me.removeClass('searchHover');
		}, 250);
    });

    $searchList.on('mouseover', function(){
        inMouseOver = true;
        if(hideTimer != undefined){
			clearTimeout(hideTimer);
			hideTimer = undefined;
		}
    });
    $searchList.on('mouseout', function(){
        inMouseOver = false;
    })
	
	// Set mouseover event handlers on all the li's in the list
	var scopes = $searchList.children();
	//initialize selected Index for the default value
	if (scopes.length == 4) { //if we are on "This Category" or "This Channel" page
		searchScopeDropDown.set_selectedIndex(3);
	}
	scopes.forEach(function(index, elem){
		(function(el, ind){
		Sys.$(el)
			.on('click', function(){
				// Remove the selected state from the last selected item
				var select = searchScopeDropDown.searchSelect[0];
				var oldInd = searchScopeDropDown.get_selectedIndex();
				Sys.$(scopes[oldInd])
				.removeClass('selected');
				inMouseOver = false;
				searchScopeDropDown.set_selectedIndex(ind);
                // reset the default value for the search
                if(Sys.$('videoSearchField')[0].value == "" || Sys.$('videoSearchField')[0].value == Sys.$('videoSearchField')[0].defaultValue){
                    Sys.$('videoSearchField')[0].value = searchScopeDropDown.get_selectedText();
                }
                Sys.$('videoSearchField')[0].defaultValue = searchScopeDropDown.get_selectedText();
                Sys.$(this).addClass('selected');
            })
			.on('mouseover', function(){
				Sys.$(this).addClass('on');
            })
			.on('mouseout', function(){
				Sys.$(this).removeClass('on');
            });
		})(elem, index);
	});
	
	// Finally, show the search list on the first mouseover
	showTimer = setTimeout(function(){
		$searchList.show();
	}, 250);	
};

MSVideo.initWebSearch = function(btn){
	// Set the search scope for the web button
	Sys.$(btn).on('click', function(){
		Sys.$('search_scope')[0].selectedIndex = 2;
	});
};

	
MSVideo.utils = {	
	// Used to clean any user generated content
	cleanStr: function(str)
	{
		return str.replace(/<(.|\n)*?>/g,'').replace(/<\/(.|\n)*?>/g,'');
	}
};