/**
 * CliUIFunctions.js
 * 
 * contains the functions used to facilitate User Interface design and dynamic interactivity
 * NOTE: these functions make substantial use of the jQuery framework.
 * 
 * TOC
 * 
 * 1  -  CliChannelsRowManager			supports the channel row
 * 2  -  CliHeroRowManager				supports the hero row
 * 3  -  CliInputBoxesManager			supports the changing backgrounds of input boxes
 * 4  -  initFooterMoreSkySitesLink		supports the More Sky Sites link in the footer
 * 5  -  CliTweenedObject				supports tweening elements on the page
 * 6  -  fieldsetInfo					jQuery plugin - shows or hides a block of info for a fieldset when the focus moves
 * 7  -  sifr3 							jQuery plugin - uses sifr3 to display text in any font
 * 8  -  CliCenterSIFRContentVertically	centers sIFR replaced text inside its parent
 * 9  -  CliIsSilverlightInstalled		checks if an appropriate Silverlight version is currently installed.
 * 10 -  CliFixInlineLinks				jQuery plugin - used to fix inline backgrounds in ie6 (for arrows after links)
 * 11 -  CliInitTopNavChannelsSelect	loads the page selected from the channels select menu in top nav bar
 */


/**
 * 1 - CliChannelsRowManager - functions to support the channel row - requires jQuery framework
 */

var CliChannelsRowManager = function() {
	this.init();
};

CliChannelsRowManager.prototype = {
	
	logo_interspace: 20,
	default_delta_x: 1,
	max_deltax_delta: 10,
	inertia: 6,
	slider_timer_interval: 75,
	logo_widths: [],
	logo_heights: [],
	logo_default_X: [],
	logo_default_Y: [],
	curr_offset: null,
	curr_deltax: null,
	target_deltax: null,
	slider_max_width: null,
	channel_strip_height: null,
	channel_strip_width: null,
	stop_movement: null,
	fade_in_buffer: 100,
	slider_timer: null,
	channel_strip_items: [],
	num_channel_strip_items: null,
	memory: [],
	
	init: function() {
		var CS = this;
		window.CliChannelStripObj = this;
		// and initialise values
		CS.slider_max_width = 0;
		CS.channel_strip_height = $("#channelSelector .channelStrip").height();
		CS.channel_strip_width = parseInt($("#channelSelector .channelStrip").css('width'),10);
		CS.channel_strip_items = $("#channelSelector h2 a").get();
		CS.num_channel_strip_items = CS.channel_strip_items.length;
		$("#channelSelector h2 a img").each(function(i){
			var logoObj = $(this);
			CS.logo_widths[i] = logoObj.width();
			CS.logo_heights[i] = logoObj.height();
			CS.logo_default_X[i] = CS.slider_max_width;
			CS.slider_max_width += logoObj.width() + CS.logo_interspace;
			CS.logo_default_Y[i] = parseInt((CS.channel_strip_height - logoObj.height())/2,10);
			logoObj.parent().css('top',CS.logo_default_Y[i]+'px');
			CS.fade_in_buffer = Math.max(CS.fade_in_buffer,CS.logo_widths[i]);
		});
		CS.fade_in_buffer += CS.logo_interspace;
		CS.slider_max_width = Math.max(CS.slider_max_width, CS.channel_strip_width + CS.logo_widths[0] + CS.logo_interspace);
		CS.target_deltax = CS.default_delta_x;
		CS.curr_offset = CS.fade_in_buffer;
		CS.curr_deltax = 0;
		CS.stop_movement = false;
		
		// cache some values for use in positioning calculations
		CS.fade_constraint_right = this.channel_strip_width - this.fade_in_buffer;
		CS.opacity_falloff_modifier =  Math.PI / 2;
		
		// create necessary HTML structure
		$("#channelSelector").addClass('ready'); // set it component to ready (to allow rendering)		
		$("#channelSelector").append('<div id="CSprevChannel" class="prevChannel">Previous</div><div id="CSnextChannel" class="nextChannel">Next</div>');
		$("#CSprevChannel").hover(function(event){
			CS.speedUp(event, '#CSprevChannel');
		}, function(event){
			CS.defaultSpeed(event, '#CSprevChannel');
		});
		$("#CSnextChannel").hover(function(event){
			CS.speedUp(event, '#CSnextChannel');
		}, function(event){
			CS.defaultSpeed(event, '#CSnextChannel');
		});

		$("#channelSelector h2 a").hover(function(){CS.stop_movement = true;},function(){CS.stop_movement = false;});
		CS.positionItems();
		CS.slider_timer = window.setInterval(function() {
			if (((CS.target_deltax !== 0) || (CS.curr_deltax !== 0)) && (!CS.stop_movement)) {
				var slider_max_width = CS.slider_max_width;
				var curr_deltax = CS.curr_deltax;
				
				CS.curr_deltax += (CS.target_deltax - curr_deltax) / CS.inertia;
				CS.curr_offset += Math.round(curr_deltax);
				if (CS.curr_offset > slider_max_width) {
					CS.curr_offset = 0;
				} else if (CS.curr_offset < 0) {
					CS.curr_offset = slider_max_width;
				}
				CS.positionItems();
			}
		}, CS.slider_timer_interval);
		$(window).unload(CS.deallocate);
	},

	speedUp: function(event, buttonID) {
		var slide_direction = (buttonID == '#CSprevChannel') ? (-1) : 1;
		this.target_deltax = slide_direction * this.max_deltax_delta;
		this.default_delta_x = slide_direction * Math.abs(this.default_delta_x);
		$(buttonID).addClass('buttonActive');
	},
	
	defaultSpeed: function(event, buttonID) {
		this.target_deltax = this.default_delta_x;
		$(buttonID).removeClass('buttonActive');
	},
	
	positionItems: function() {
		var slider_max_width = this.slider_max_width;
		var channel_strip_width = this.channel_strip_width;
		var curr_offset = this.curr_offset;
		var slider_max_width = this.slider_max_width;
		var opacity_falloff_modifier = this.opacity_falloff_modifier;
		var fade_in_buffer = this.fade_in_buffer;
		var fade_constraint_right = this.fade_constraint_right;
		var logo_interspace = this.logo_interspace;
		
		for (var i = 0, len = this.num_channel_strip_items; i < len; i++) {
			var logo_width = this.logo_widths[i];
			var new_left_pos = this.logo_default_X[i] + curr_offset;
			if (new_left_pos >= slider_max_width) {
				new_left_pos -= slider_max_width;
			} else if (new_left_pos < 0) {
				new_left_pos += slider_max_width;
			}
			new_left_pos -= ( !this.memory[i] ) ? fade_in_buffer : (fade_in_buffer - logo_interspace);
			if (new_left_pos < channel_strip_width  ) {
				var item = this.channel_strip_items[i];
				var logo_opacity = 1.0;
				if (new_left_pos < fade_in_buffer - logo_width) {
					logo_opacity = Math.max(Math.sin((new_left_pos + logo_width) / fade_in_buffer * opacity_falloff_modifier), 0);
				} else if (new_left_pos > fade_constraint_right) {
					logo_opacity = Math.max(Math.sin((channel_strip_width - new_left_pos) / fade_in_buffer * opacity_falloff_modifier), 0);
				}
		
				var s = item.style;
				s.display = 'block';
				s.left = new_left_pos + 'px';
				// only change opacity if it is different from previous one
				if ( !this.memory[i] || ( this.memory[i] && this.memory[i].opacity != logo_opacity )  ) $(item).css('opacity', logo_opacity );
				this.memory[i] = { opacity: logo_opacity };
				
				
			} else {
				this.channel_strip_items[i].style.display = 'none';
			}
		}		
	},
	
	deallocate: function() {
		/* free the memory used by this object by avoiding circular references DOM-Javascript */
		window.clearInterval(window.CliChannelStripObj.slider_timer);
		$("#CSprevChannel, #CSnextChannel").unbind();
		$("#channelSelector h2 a").unbind();
		window.CliChannelStripObj = null;
	}
};


/**
 * 2 - CliHeroRowManager - functions to support the hero row - requires jQuery framework.
 * 						   The row cycles through the tabs at a set interval.
 */

var CliHeroRowManager = function() {
	this.init();
};

CliHeroRowManager.prototype = {
	
	CYCLE_INTERVAL: 5000,	// interval for tab cycling, in milliseconds
	cycleTimerObj: null,
	curr_tab: 0,
	last_tab_ndx: -1,
	positionTrackingObj: null,
	
	init: function() {
		var HR = this;
		window.HeroRowManagerObj = this;
		$(".hero-row .rowMenu .activeItem").parent().next().addClass('hideBorder');

		// initialise menu
		$(".hero-row .rowMenu a").map(function(index){
			$(this).click(function(event){
				event.preventDefault();
				$(this).addClass('activeItem').parent().siblings().find('a').removeClass('activeItem');
				$(".hero-row .rowMenu li").removeClass('hideBorder');
				$(this).parent().next().addClass('hideBorder');
				HR.showTab(index);
			});
			HR.last_tab_ndx++;
		});
		
		// and start position tracking
		window.CliCurrentMousePos = {X: 0, Y: 0};
		$('body').mousemove(function(e){
			window.CliCurrentMousePos = {X: e.pageX, Y: e.pageY};
		});
			
		HR.cycleTimerObj = window.setInterval(HR.cycleTab,this.CYCLE_INTERVAL);
		$(window).unload(HR.deallocate);
		
	},
	
	showTab: function(tab_ndx) {
		this.curr_tab = tab_ndx;
		$(".hero-row .rowBackground .heroRowTab").eq(tab_ndx).fadeIn('slow').siblings('.heroRowTab').fadeOut('slow');
	},
	
	cycleTab: function () {
		var HR = window.HeroRowManagerObj;
		// check if mouse is over tabs
		var HRDynamicAreaObj = $(".hero-row .rowBackground");
		var HRDynamicAreaOffset = HRDynamicAreaObj.offset();
		var mouseX = window.CliCurrentMousePos.X;
		var mouseY = window.CliCurrentMousePos.Y;
		// if the mouse is over the tabs, return and do nothing
		if ((mouseX > HRDynamicAreaOffset.left) && (mouseY > HRDynamicAreaOffset.top) && (mouseX < HRDynamicAreaOffset.left + HRDynamicAreaObj.width()) && (mouseY < HRDynamicAreaOffset.top + HRDynamicAreaObj.height())) {
			return;
		}
		
		// if not then select next tab
		if (++HR.curr_tab > HR.last_tab_ndx) {
			HR.curr_tab = 0;
		}
		// make sure to also change the tab menu to reflect the current tab
		var tabMenuLnkObj = $(".hero-row .rowMenu li a").eq(HR.curr_tab);
		tabMenuLnkObj.addClass('activeItem').parent().siblings().find('a').removeClass('activeItem');
		$(".hero-row .rowMenu li").removeClass('hideBorder');
		tabMenuLnkObj.parent().next().addClass('hideBorder');
		
		
		HR.showTab(HR.curr_tab);
	},
	
	deallocate: function() {
		window.clearInterval(window.HeroRowManagerObj.cycleTimerObj);
		window.HeroRowManagerObj = null
		$(".hero-row .rowMenu a").unbind('click');
		$("body").unbind('mousemove');
	}
};




/**
 * 3 - CliInputBoxesManager - functions to support the changing backgrounds of input boxes - requires jQuery framework
 */

var CliInputBoxesManager = function() {
	this.init();
};

CliInputBoxesManager.prototype = {
	
	init: function(){
		var CIBM = this;
		$("input.withBackground").focus(function(){
			$(this).parent().removeClass('empty').addClass('focused');
		}).blur(CIBM.setBackground);
		$("input.withBackground").blur();
		$(window).unload(this.deallocate);
	},
	
	setBackground: function() {
		try {
			var currInputObj = $(this);
			currInputObj.parent().removeClass('focused');
			if (!currInputObj.attr('value') ||(currInputObj.attr('value').trim() === '')) {
				currInputObj.parent().addClass('empty');
			}
		} catch(e) {}
	},
	
	deallocate: function(){
		$("input.withBackground").unbind('focus').unbind('blur');
	}

};




/**
 * 4 - initFooterMoreSkySitesLink - function to support the More Sky Sites link in the footer - requires jQuery framework
 */
function initFooterMoreSkySitesLink(alternativeURL) {
	
	var moreSkySitesLinkID = '#moreSkySitesLink';
	var moreSkySitesLinksArea = '#moreSkySitesLinkArea';
	var targetAreaToRetrieve = '#FOOTER_MORE';
	var linkObj = $(moreSkySitesLinkID + " a");
	
	try {
		if ($(moreSkySitesLinkID).length == 1) {
			$(moreSkySitesLinksArea).fadeTo(0,0);
			
			// check if cross domain (to prevent ie messages)
			if (!isCrossDomain(linkObj)) {
				
				$.ajax({
					url: linkObj.attr('href'),
					error: function() {
						throw "try alternate url"
					},
					success: function(htmlReturned){
						$(moreSkySitesLinksArea).html(jQuery("<div/>").append(htmlReturned.replace(/<script(.|\s)*?\/script>/g, "")).find(targetAreaToRetrieve));
						addMoreSkySitesMenu();
					}
				});
			} else {
				throw "cross domain"
			}
		}
	} catch(e) {
		// try alternativeURL (possibly again), for the case of cross domain errors in FFox 3
		try {
			if (typeof(alternativeURL) != 'undefined') {
				$(moreSkySitesLinksArea).load(alternativeURL + ' ' + targetAreaToRetrieve,null,addMoreSkySitesMenu);
			}
		} catch(e) {}
	};
	
	function addMoreSkySitesMenu(){
		$(moreSkySitesLinkID + " > a").click(function(e){
			e.preventDefault();
			$(moreSkySitesLinksArea).css('display', 'block').fadeTo('slow', 0.95);
		});
		$(moreSkySitesLinksArea).hover(function(){
		}, function(){
			$('#moreSkySitesLinkArea').fadeTo('slow', 0, function(){
				$('#moreSkySitesLinkArea').css('display', 'none')
			});
		});
		$(moreSkySitesLinksArea + ' a').attr('target','_blank');
	}
	
	function isCrossDomain(linkObj) {
		try {
			var linkHostname = linkObj[0].hostname;
			var linkDomain = linkHostname.match(/\w+\.\w+/);
			var currDomain = document.domain.match(/\w+\.\w+/);
			return (linkDomain.toString() != document.domain.toString());
		} catch(e) {
			return true;
		}
	}
}



/**
 * 5 - CliTweenedObject - function to support tweening elements on the page - requires jQuery framework
 */

var CliTweenedObject = function(obj_id,tweenProperties) {
	this.init(obj_id,tweenProperties);
};

CliTweenedObject.prototype = {
	
	obj_id: null,
	tweenOptions: null,
	state1: null,
	state2: null,
	num_steps: 5,
	interval: 30,
	step: null,
	direction: null,
	timerHandle: null,
	
	init: function(obj_id,tweenProps) {
		this.tweenOptions = {left: false, top: false, height: false, width: false};
		this.state1 = {left: 0, top: 0, height: 10, width: 10};
		this.state2 = {left: 0, top: 0, height: 20, width: 20};
		
		if (obj_id && (document.getElementById) && (document.getElementById(obj_id))) {
			this.obj_id = '#' + obj_id;
			if (tweenProps) {
				this.parseTweenProps(tweenProps);
			}
		}
	},
	
	parseTweenProps: function(tweenProps) {
		if (typeof(tweenProps.state1) != 'undefined') {
			if (typeof(tweenProps.state1.left) != 'undefined') {
				this.state1.left = tweenProps.state1.left;
				this.tweenOptions.left = true;
			};
			if (typeof(tweenProps.state1.top) != 'undefined') {
				this.state1.top = tweenProps.state1.top;
				this.tweenOptions.top = true;
			};
			if (typeof(tweenProps.state1.height) != 'undefined') {
				this.state1.height = tweenProps.state1.height;
				this.tweenOptions.height = true;
			};
			if (typeof(tweenProps.state1.width) != 'undefined') {
				this.state1.width = tweenProps.state1.width;
				this.tweenOptions.width = true;
			};
		}
		if (typeof(tweenProps.state2) != 'undefined') {
			if (typeof(tweenProps.state2.left) != 'undefined') {
				this.state2.left = tweenProps.state2.left;
			};
			if (typeof(tweenProps.state2.top) != 'undefined') {
				this.state2.top = tweenProps.state2.top;
			};
			if (typeof(tweenProps.state2.height) != 'undefined') {
				this.state2.height = tweenProps.state2.height;
			};
			if (typeof(tweenProps.state2.width) != 'undefined') {
				this.state2.width = tweenProps.state2.width;
			};
		}
		if (typeof(tweenProps.num_steps) != 'undefined') {
			this.num_steps = tweenProps.num_steps;
		}
		if (typeof(tweenProps.anim_interval) != 'undefined') {
			this.interval = tweenProps.anim_interval;
		}
	},

	forwardTween: function(execParams){
		if (typeof(execParams) != 'undefined') {
			this.parseTweenProps(execParams);
		}
		this.step = 0;
		this.direction = 1;
		this.startTween();
	},
	
	reverseTween: function(execParams){
		if (typeof(execParams) != 'undefined') {
			this.parseTweenProps(execParams);
		}
		this.step = this.num_steps;
		this.direction = -1;
		this.startTween();
	},
	
	startTween: function() {
		var thisObj = this;
		if (thisObj.timerHandle) {
			window.clearInterval(thisObj.timerHandle);
		}
		thisObj.timerHandle = window.setInterval(function(){
			thisObj.renderTweenStep();
		},thisObj.interval);
	},

	renderTweenStep: function(){
		this.step = this.step + this.direction;
		var percent_progress = this.step / this.num_steps;
		var tweenStepCSS = {};
		if (this.tweenOptions.left) {
			tweenStepCSS.left = parseInt(this.state1.left + (this.state2.left - this.state1.left) * percent_progress) + 'px';
		}
		if (this.tweenOptions.top) {
			tweenStepCSS.top = parseInt(this.state1.top + (this.state2.top - this.state1.top) * percent_progress) + 'px';
		}
		if (this.tweenOptions.height) {
			tweenStepCSS.height = parseInt(this.state1.height + (this.state2.height - this.state1.height) * percent_progress) + 'px';
		}
		if (this.tweenOptions.width) {
			tweenStepCSS.width = parseInt(this.state1.width + (this.state2.width - this.state1.width) * percent_progress) + 'px';
		}
		$(this.obj_id).css(tweenStepCSS);
		if ((this.step <= 0) || (this.step >= this.num_steps)) {
			this.step = null;
			this.direction = null;
			window.clearInterval(this.timerHandle);
		}
	},
	
	destroy: function() {
		if (this.timerHandle) {
			window.clearInterval(this.timerHandle);
		}
	}
};

/**
 * 6 - fieldsetInfo jQuery plugin
 * 
 * shows or hides a block of info for a fieldset when the focus moves
 */
(function(jQuery) {
	
	jQuery.fn.fieldsetInfo = function() {
	
		var _current = null;
		var _timeout = null;
	
		return this.each(function(){
			var fieldset = $(this);
			var wrapper = fieldset.find('.infoText').wrap('<div class="infoWrapper"></div>');
			var info = fieldset.find('.infoWrapper').fadeTo(0,0);
			if (fieldset.is('fieldset')) {
				fieldset.find('input,select,textarea,button,a').focus(function(){
					if (_current != info) {
						if (_current) _current.fadeTo('slow',0);
						info.fadeTo('slow',1.0);
						_current = info;
					}
					if (_timeout) window.clearTimeout(_timeout);
				}).blur(function() {
					if (_timeout) window.clearTimeout(_timeout);
					_timeout = window.setTimeout(function () { info.fadeTo('slow',0); _current = null; }, 100);
				});
			}
		});
	}
	
})(jQuery);

/**
 * 7 - sifr3 jQuery plugin
 * 
 * jQuery wrapper for sIFR3 so we can get the properties from the regular CSS and
 * tweak if required
 * 
 * usage: $('.replace').sifr3({font: 'skyInfoText.swf'});
 */
(function(jQuery) {

	var activated = false;
	var hexDigits = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
	var nativeSupportAvailable = isNativeSupportAvailable();
	
	function rgbToHex(color) {
		if (color.substring(0,1) == '#') return color;
		var parts = color.match(/rgb\(([0-9]+),\s([0-9]+),\s([0-9]+)\)/);
		var r = parts[1], g = parts[2], b = parts[3];
		return '#' + hexDigits[(r - r % 16) / 16] + hexDigits[r % 16] + hexDigits[(g - g % 16) / 16] + hexDigits[g % 16] + hexDigits[(b - b % 16) / 16] + hexDigits[b % 16];
	}
	
	function isNativeSupportAvailable() {
		
		var supported_versions = {
				'safari': '525.13.1', // 3.1 - supports TrueType fonts (.ttf) as well as OpenType fonts with TrueType (.ttf) or PostScript (.otf) outlines 
				'mozilla': '1.9.1', // firefox 3.1 - supports TrueType fonts (.ttf) as well as OpenType fonts with TrueType (.ttf) or PostScript (.otf) outlines
				'msie': '',
				'opera': '10.00'
		}
		
		function isMac(){
			return /Mac/.test(navigator.platform);
		}
		
		function normaliseVersion(version_string){
			var parts = 5;
			var browserVersionArr = version_string.split('.');
			while (browserVersionArr.length < parts) {
				browserVersionArr.push(0);
			}
			for (var i=0; i < parts; i++) {
				browserVersionArr[i] = parseInt(browserVersionArr[i]);
			}
			return browserVersionArr;
		}
		
		function isRequiredVersion(current, min_required, max_required){
			var current = normaliseVersion(current);
			var required = normaliseVersion(min_required);
			var max_required = (max_required || false) ? normaliseVersion(max_required) : false;
			var equal_min = true;
			var equal_max = false;
			var gt_max = false;
			var gt_min = false;
			// work out if greater than or equal to the minimum supplied version
			for(var i = 0, len = current.length ; i < len; i++){
				if(current[i] != required[i]) equal_min = false;
				if(current[i] > required[i]){ 
					gt_min = true;
					break;
				}
				if(current[i] < required[i]) break;
			}
			// work out if less than but not equal to the max version if supplied
			if(max_required){
				equal_max = true;
				for(var i = 0, len = current.length ; i < len; i++){
					if(current[i] != max_required[i]) equal_max = false;
					if(current[i] > max_required[i]){ 
						gt_max = true;
						break;
					}
					if(current[i] < max_required[i]) break;
				}
			}
			return (gt_min || equal_min) && (!gt_max && !equal_max);
		}
		
		var supported = false;
		var currBrowser = jQuery.browser;
		if (currBrowser.msie) {
			//supported = false;	// this is only half true... it does not look properly antialiased, could use sIFR to better it
		} else {
			// actual functionality support detection is not easy, for now best rely on version numbers...
			if (currBrowser.safari) {
				supported = isRequiredVersion(currBrowser.version, supported_versions.safari);
			} else if (currBrowser.mozilla) {
				supported = isRequiredVersion(currBrowser.version, supported_versions.mozilla) ;
				// only for this implimentation we have opacity on some shadow elements which messes firefox 2 on mac by not allowing sifr flash to show
				// so reset opacity to 1 to fix it
				// done here as we have a way of checking the browser version, and we are about to do some sifr...
				if(isMac() && isRequiredVersion(currBrowser.version, '1.8.1', '1.9')){
					$('.sContainerShadow').css('opacity', 1);
					$(document).ready(function(){
						$('.sContainerShadow').css('opacity', 1);
					});
				}
				// end of only for this implimentation
			} else if (currBrowser.opera) {
				supported = isRequiredVersion(currBrowser.version, supported_versions.opera);
			}
		}
		// THE FOLLOWING LINE DISABLES THIS ROUTINE AND FORCES sIFR TO ALWAYS RUN.
		// THIS WAS DONE BECAUSE OF A CURRENT WEBKIT ISSUE WITH THE @font-face DECLARATION.
		// IN FUTURE, WHEN NEW RELEASES ARE AVAILABLE, THIS COULD BE RE-ENABLED.
		supported = false;

		return supported;
	}
	
	
	
	
	jQuery.fn.sifr3 = function(options) {
		
		if (!nativeSupportAvailable) {
			var opts = $.extend({}, options);
			
			if (!activated) {
				sIFR.activate();
				sIFR.initialize();
				activated = true;
			}
			
			return this.each(function() {
				var el = $(this);
				var font = { src : opts.font };
				var options = $.extend(
					{
						elements : [this],
						css : {
							'.sIFR-root' : {
								'color' : rgbToHex(el.css('color')),
								'text-align' : el.css('text-align').match(/left|center|right/) || 'left',
								'text-transform' : el.css('text-transform'),
								'letter-spacing' : el.css('letter-spacing').match('normal') ? 0 : el.css('letter-spacing').match(/-?\d/)[0]
							}
						},
						transparent : true
					},
					opts
				);
				try {
				
					sIFR.replace(font, options);
	
					// AND FIX BUG WITH FLASH + SIFR3 plugin version by overriding __flash__removeCallback
					window.__flash__removeCallback = function (instance, name) {
						if ( instance ) {
							instance[name] = null;
						}
					}
					
				} catch(e) {
					// do nothing...
				}
				
			});
		}
	}
	
})(jQuery);

/**
 * 8 - CliCenterSIFRContentVertically
 * 
 * function to center sIFR replaced text inside its parent (uses CSS top property). It is to be used as
 * a callback after sIFR performs its text replacement.
 * 
 * usage: $('.selector').sifr3({font : 'font.swf', onReplacement : CliCenterSIFRContentVertically});
 */
function CliCenterSIFRContentVertically(flashInteractorObj) {
	var currElementObj = $(flashInteractorObj.getFlashElement()).parent();
	var available_height = currElementObj.parent().height();
	var element_height = currElementObj.height();
	currElementObj.css('top',parseInt((available_height-element_height)/2)+'px');
}




/**
 * 9 - CliIsSilverlightInstalled
 * 
 * function to check if an appropriate Silverlight version is currently installed.
 * 
 * usage: CliIsSilverlightInstalled(version); - version is a string, eg "2.0.31005.0", returns true/false
 */
function CliIsSilverlightInstalled(version) {
	
	var isVersionSupported = false;
	var container = null;
	
	try {
		var control = null;
		try {
			control = new ActiveXObject('AgControl.AgControl');
			if ( version == null ) {
				isVersionSupported = true;
			} else if (control.IsVersionSupported(version) ) {
				isVersionSupported = true;
			}
			control = null;
		} catch (e) {
			var plugin = navigator.plugins["Silverlight Plug-In"];
			if ( plugin ) {
				if (version === null) {
					isVersionSupported = true;
				} else {
					var actualVer = plugin.description;
					if (actualVer === "1.0.30226.2") {
						actualVer = "2.0.30226.2";
					}
					var actualVerArray = actualVer.split(".");
					while (actualVerArray.length > 3) {
						actualVerArray.pop();
					}
					while (actualVerArray.length < 4) {
						actualVerArray.push(0);
					}
					var reqVerArray = version.split(".");
					while (reqVerArray.length > 4) {
						reqVerArray.pop();
					}
					var requiredVersionPart;
					var actualVersionPart;
					var index = 0;
					
					do {
						requiredVersionPart = parseInt(reqVerArray[index]);
						actualVersionPart = parseInt(actualVerArray[index]);
						index++;
					}
					while (index < reqVerArray.length && requiredVersionPart === actualVersionPart);
					
					if (requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart)) {
						isVersionSupported = true;
					}
				}
			}
		}
	} catch (e) {
		isVersionSupported = false;
	}
	if (container) {
		document.body.removeChild(container);
	}
	
	return isVersionSupported;
};


/**
 * 10 - CliFixInlineLinks jQuery plugin
 * 
 * routine to fix inline links for IE. This is necessary because the background of inline elements
 * in IE does not wrap (remains fixed by the largest containing dimensions, hence the end arrows of
 * links used in SVOD show in the wrong place. This plugin wraps the last word in the matched element
 * within a <span></span> and adds a class to the matched element allow selection and hence prevent
 * it having a background (hence only the last word has a background).
 * 
 * usage: $('.three-video-component h3 a').CliFixInlineLinks();
 */

(function($) {
	$.fn.extend({
		CliFixInlineLinks: function(options) {

			var defaults = {
			       override_css_class: 'nobkg',
				   targeted_browser: 'msie',
				   for_all_browsers: false
			};

			var options = $.extend(defaults, options);
				
			if (options.for_all_browsers || jQuery.browser[options.targeted_browser]) {

	    		return this.each(function() {
					
					var obj = $(this);
					
					if (!obj.hasClass(options.override_css_class)) {
						var link_text = jQuery.trim(obj.text());
						var last_space_pos = link_text.lastIndexOf(' ', link_text.length - 3) + 1; // look for at least three characters.. to avoid series numbers problems
						var link_text_kept = link_text.slice(0, last_space_pos);
						var last_word = link_text.slice(last_space_pos);
						
						obj.addClass(options.override_css_class).text(link_text_kept).append('<span>' + last_word + '</span>');
					}
					
				});

			} else {
				return function() {};
			}

		}
	});
})(jQuery);


/** 
 * 11 - CliInitTopNavChannelsSelectMenu
 * 
 * Initialises top navigation Browse Channels Dropdown.
 */

function CliInitTopNavChannelsSelect() {
	$(".menuBrowseChannelsSelect").change(function() {
		if ($(".menuBrowseChannelsSelect").val() != "") {
			show_waiting();
			window.location = ($(".menuBrowseChannelsSelect").val());
		}
	});
}
