/**
 * 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.
 *
 */


/**
 * 1 - CliChannelsRowManager - functions to support the channel row - requires jQuery framework
 */

var CliChannelsRowManager = function() {
	this.init();
};

CliChannelsRowManager.prototype = {
	
	logo_interspace: 40,
	default_delta_x: 1,
	max_deltax_delta: 10,
	inertia: 4,
	slider_timer_interval: 50,
	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,
	
	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;
		
		// 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)) {
				CS.curr_deltax += (CS.target_deltax - CS.curr_deltax) / CS.inertia;
				CS.curr_offset += Math.round(CS.curr_deltax);
				if (CS.curr_offset > CS.slider_max_width) {
					CS.curr_offset = 0;
				} else if (CS.curr_offset < 0) {
					CS.curr_offset = CS.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() {
		for (var i = 0; i < this.num_channel_strip_items; i++) {
			var new_left_pos = this.logo_default_X[i] + this.curr_offset;
			if (new_left_pos >= this.slider_max_width) {
				new_left_pos -= this.slider_max_width;
			} else if (new_left_pos < 0) {
				new_left_pos += this.slider_max_width;
			}
			new_left_pos -= this.fade_in_buffer;
			if (new_left_pos < this.channel_strip_width) {
				var logo_opacity = 1.0;
				if (new_left_pos < this.fade_in_buffer - this.logo_widths[i]) {
					logo_opacity = Math.max(Math.sin((new_left_pos + this.logo_widths[i]) / this.fade_in_buffer * Math.PI / 2), 0);
				} else if (new_left_pos > this.channel_strip_width - this.fade_in_buffer) {
					logo_opacity = Math.max(Math.sin((this.channel_strip_width - new_left_pos) / this.fade_in_buffer * Math.PI / 2), 0);
				}
				$(this.channel_strip_items[i]).css({
					display: 'block',
					left: new_left_pos + 'px',
					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
 */

var CliHeroRowManager = function() {
	this.init();
};

CliHeroRowManager.prototype = {
	
	init: function() {
		var HR = this;
		$(".hero-row .rowMenu .activeItem").parent().next().addClass('hideBorder');
		$(".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);
			});
		});
		$(window).unload(HR.deallocate);
		
	},
	
	showTab: function(tab_ndx) {
		$(".hero-row .rowBackground .heroRowTab").eq(tab_ndx).fadeIn('slow').siblings('.heroRowTab').fadeOut('slow');
	},
	
	deallocate: function() {
		$(".hero-row .rowMenu a").unbind('click');
	}
};




/**
 * 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() {
	
	var moreSkySitesLinkID = '#moreSkySitesLink';
	var moreSkySitesLinksArea = '#moreSkySitesLinkArea';
	
	try {
		if ($(moreSkySitesLinkID).length == 1) {
			$(moreSkySitesLinksArea).fadeTo(0,0);
			$(moreSkySitesLinksArea).load($(moreSkySitesLinkID + " a").attr('href') + " #FOOTER_MORE");
			$(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')});
				}
			);
		}
	} catch(e) {}
}



/**
 * 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'];
	
	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];
	}
	
	jQuery.fn.sifr3 = function(options) {
		
		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;
}
