/* File: videoFacade.js
*  Version: 1.0
*  Author: Thomas Kim
*  Date: 1/29/09
*  Description: This files sets and captures the onclick event for the $$('.cnnVPFlashCollapsed') divs.
** It also provides an interface for shrinking the divs. Ex. storyVidPlayers[index].shrink();
*  Modifications:
** Var effect controls the type of effect. Currently, there are three. 0 turns the effect off. 1 makes the expansion take place
*    vertically and horizontally.  2 makes it grow vertically only.
*  Add more functions and additional cases to the switch statement in the SVideoEffects controllers to add different types of effects.
*  Load lazy load when the screen has been painted (chain of command)
*/
var effect = 2;

var SVideoEffects = function() {
	/*Unique Player Identifier*/
	var i = null;
	/*Time at which the effect starts*/
	var startTime = null;
	/*variable used to clear intervals*/
	var animationInterval = null;
	/*Iframe Dimensions*/
	var iTargetHE = 272;
	var iTargetWE = 384;
	var iTargetHS = 0;
	var iTargetWS = 0;
	/*Change this to make the animation slower or faster*/
	var totalTime = 350;
	var freq = Math.PI / (2 * totalTime);
	var clicked2open = true;
	var initialClick = false;
	var that = this;

	function getiTargetWS() { return iTargetWS; }
	function setclicked2open(bool) { clicked2open = bool; }
	function setinitialClick(bool){ initialClick = bool; }
	function setiTargetWS(n) { iTargetWS = n; }
	function setStartTime(){ startTime = new Date().getTime(); }
	function setI(n){ i = n; }

	function stop(){
		if(animationInterval != null) {
			clearInterval(animationInterval);
			animationInterval=null;
		}
	}

	function contract(){
		var elapsedTime = new Date().getTime() - startTime;
		if (elapsedTime < totalTime) {
			var contH = $('vid'+i).getHeight();
			var contW = $('vid'+i).getWidth();
			var f = Math.abs(Math.sin(elapsedTime * freq));
			$('vid'+i).style.height = Math.round(f * (iTargetHS-contH) + contH)+"px";
			$('vid'+i).style.width = Math.round(f * (iTargetWS-contW) + contW)+"px";
		}
		else {
			stop();
			if(!(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)))
				$('vid'+i).style.marginBottom = "0px";
			$('vid'+i).style.width = iTargetWS+"px";
			$('vid'+i).style.height = iTargetHS+"px";
		}
	}

	function expand()
	{
		var elapsedTime = new Date().getTime() - startTime;
		if (elapsedTime < totalTime)
		{
			var startH = $('vid'+i).getHeight();
			var startW = $('vid'+i).getWidth();
			var f = Math.abs(Math.sin(elapsedTime * freq));
			$('vid'+i).style.height = Math.round(f * (iTargetHE-startH) + startH)+"px";
			$('vid'+i).style.width = Math.round(f * (iTargetWE-startW) + startW)+"px";
		}
		else
		{
			stop();
			if(!(/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)))
				$('vid'+i).style.marginBottom = "15px";
			$('player'+i).style.height = iTargetHE+"px";
			$('player'+i).style.width = iTargetWE+"px";
			$('vid'+i).style.width = iTargetWE+"px";
			$('vid'+i).style.height = iTargetHE+"px";

			if(clicked2open){
				// rewind the playlist unless playing a collapsed video's playing for the first time
				//if( ($('player'+i).contentWindow.cnnConfig['collapsed'] == true)&&(initialClick==false) ){
				if( ($('player'+i).contentWindow.cnnConfig['collapsed'] == false)&&(initialClick==false) )
				{
					setinitialClick(true);
				}
				else
				{
					try{$('player'+i).contentWindow.rewind2zero();}catch(e){}
				}
			}
		}
	}

	//function to insert the iframe video player
	function playerInsert(videoTargetDivId)
	{
		//generate random so we dont cache.
		//TODO:
		// - check to see if we need this random hack
		var rnd = Math.floor(Math.random()*101010101);
		//player iframe
		var str = '<iframe id="player'+i+'" src="/.element/ssi/video/3.0/story.player.html?p='+i+'&d='+(rnd)+'" width="384" height="0" frameborder="0" scrolling="no" allowtransparency="true" style=""></iframe>';
		//show the player div -> moving this over to the priv. expand function to make sure that the iframe's height is 0px before making the player visible
		//try{ console.log('showing the player div'); }catch(e){}
		$('vid' +i).style.height = '0px';
		$('vid'+i).show();
		//insert player iframe into div
		$('vid'+i).update(str);
		//Register cnn player
		cnnPlayers[i] = i;
		//try{ console.log('adding player'+i) }catch(e){}
	}

	/*Priv. Functions accessible to the outside*/
	//controller for shrinking action
	this.shrink = function() {
		//$('player'+i).style.marginBottom = "0";
		switch (effect)
		{
			case 0:
				$('player'+i).style.height = '0px';
				break;
			case 1:
				if(animationInterval == null)
				{
          			setStartTime();
          			animationInterval = setInterval(contract, 25 );
        		}
		        break;
			case 2:
				if(animationInterval == null)
				{
					$('player'+i).style.height=iTargetHS+"px";
					$('player'+i).style.width=iTargetWS+"px";
					setStartTime();
					animationInterval = setInterval(contract, 25 );
				}
				break;
			default:
				break;
		}
	};

	/*This function is only called when no effect is chosen (line 13: var effect = 0;)*/
	this.insertSPlayer = function(click)
	{
		var id = 'player'+i;
		switch (effect)
		{
			case 0:
				if($(id))
				{
					$(id).contentWindow.expandVideo();
					$('vid'+i+'Title').hide();
					$('player' +i).style.height = '';
				}
				else
				{
					insertSPlayer();
				}
				break;
			default:
				if(animationInterval == null)
				{
					if($(id))
					{
						$(id).contentWindow.expandVideo();
					}
					else
					{
						insertSPlayer();
					}
				}
				break;
		}
		if(!click){ setclicked2open(false); } else{ setclicked2open(true); }
	};

	//insert the player if it's not there...add the throbber, then choose which expand effect to use
	this.expand = function(callback){
		var id = 'player'+i;
		if(!document.getElementById(id))
		{
			//add the throbber
			$('vid'+i+'Title').innerHTML = $('vid'+i+'Title').innerHTML+'<img class="vidthrobber" src="http://i.cdn.turner.com/money/.element/img/1.0/misc/throbber.gif" />';
			//add the iframe
			playerInsert();
		}
		else
		{
			//if the iframe is found, then expand it
			switch (effect){
				case 0:
					if($(id))
					{
						$(id).contentWindow.expandVideo();
						$('vid'+i+'Title').hide();
						$('player' +i).style.height = '';
					}
					else
					{
						insertSPlayer();
					}
					break;
				case 1:
					if(animationInterval == null)
					{
						$('vid'+i+'Title').style.visibility="hidden"; $('vid'+i).show();
						setStartTime();
						animationInterval = setInterval(expand, 25 );
					}
					break;
				case 2:
					if(animationInterval == null)
					{
						$('vid'+i+'Title').addClassName('collapsed');
						setStartTime();
						$('vid'+i).style.display="block";
						animationInterval = setInterval(expand, 25 );
					}
					break;
				default:
					break;
			}
			setActivePlayer(i);
			//remove the throbber if it exists
			var vidthrobber = $('vid'+i+'Title').getElementsByTagName("img");
			if(vidthrobber.length > 0)
			{
				vidthrobber[0].parentNode.removeChild(vidthrobber[0]);
			}
		}
	};

	this.getEffect = function()
	{
		return effect;
	};

	this.init = function(el,i)
	{
		/*If effect ==2, set the collapsed width to 384, so that the effect only takes place vertically*/
		if(effect==2)
		{
			setiTargetWS(384);
		}
		setI(i);
		Event.observe(el, 'click', function(event){ that.expand(false);Event.stop(event); } );
		return this;
	};
}

var SVideoFacade = function()
{
	var videoInterfaces = [];
	this.init = function(){
		jQuery('.cnnVPFlashCollapsed').each(function(index,value) {
			videoInterfaces[index] = new SVideoEffects().init(value,index);
		});
		return videoInterfaces;
	};
	return this;
}

/*Upgrade jquery a bit w/ screen calculation functionality*/
/*
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 */
jQuery.fn._height=jQuery.fn.height;
jQuery.fn._width=jQuery.fn.width;
jQuery.fn.height=function(){if(this[0]==window)return self.innerHeight||jQuery.boxModel&&document.documentElement.clientHeight||document.body.clientHeight;if(this[0]==document)return Math.max(document.body.scrollHeight,document.body.offsetHeight);return this._height(arguments[0])};
jQuery.fn.width=function(){if(this[0]==window)return self.innerWidth||jQuery.boxModel&&document.documentElement.clientWidth||document.body.clientWidth;if(this[0]==document)return Math.max(document.body.scrollWidth,document.body.offsetWidth);return this._width(arguments[0])};
jQuery.fn.innerHeight=function(){return this[0]==window||this[0]==document?this.height():this.css('display')!='none'?this[0].offsetHeight-(parseInt(this.css("borderTopWidth"))||0)-(parseInt(this.css("borderBottomWidth"))||0):this.height()+(parseInt(this.css("paddingTop"))||0)+(parseInt(this.css("paddingBottom"))||0)};
jQuery.fn.innerWidth=function(){return this[0]==window||this[0]==document?this.width():this.css('display')!='none'?this[0].offsetWidth-(parseInt(this.css("borderLeftWidth"))||0)-(parseInt(this.css("borderRightWidth"))||0):this.height()+(parseInt(this.css("paddingLeft"))||0)+(parseInt(this.css("paddingRight"))||0)};
jQuery.fn.outerHeight=function(){return this[0]==window||this[0]==document?this.height():this.css('display')!='none'?this[0].offsetHeight:this.height()+(parseInt(this.css("borderTopWidth"))||0)+(parseInt(this.css("borderBottomWidth"))||0)+(parseInt(this.css("paddingTop"))||0)+(parseInt(this.css("paddingBottom"))||0)};
jQuery.fn.outerWidth=function(){return this[0]==window||this[0]==document?this.width():this.css('display')!='none'?this[0].offsetWidth:this.height()+(parseInt(this.css("borderLeftWidth"))||0)+(parseInt(this.css("borderRightWidth"))||0)+(parseInt(this.css("paddingLeft"))||0)+(parseInt(this.css("paddingRight"))||0)};
jQuery.fn.scrollLeft=function(){if(this[0]==window||this[0]==document)return self.pageXOffset||jQuery.boxModel&&document.documentElement.scrollLeft||document.body.scrollLeft;return this[0].scrollLeft};
jQuery.fn.scrollTop=function(){if(this[0]==window||this[0]==document)return self.pageYOffset||jQuery.boxModel&&document.documentElement.scrollTop||document.body.scrollTop;return this[0].scrollTop};
jQuery.belowthefold = function(element, settings) {var fold = jQuery(window).height() + jQuery(window).scrollTop();return parseInt(fold) <= parseInt(jQuery(element).offset().top);};
jQuery.rightoffold = function(element, settings) {var fold = jQuery(window).width() + jQuery(window).scrollLeft();return parseInt(fold) <= parseInt(jQuery(element).offset().left);};

/*Capture the scroll event of the page and expand the video player when it is viewable on the screen*/
var LazyLoad = function() {

	var that = this;

	function appear(i)
	{
		storyVidPlayers[i].expand();
	}

	this.init = function()
	{

		var settings = { threshold : 0, failurelimit : 0, event : "scroll", effect : "show", container : window };

		//videos ignored by the lazy loader
		var videos2ignore = [];

		//Add the Array.indexOf() function if it doesn't already exist and use it to see if a video is in the ignore list.
		if(!Array.indexOf){ Array.prototype.indexOf = function(obj){ for(var i=0; i<this.length; i++){ if(this[i]==obj){ return i; } } return -1; } }

		/*
			This runs once. Add a video to the ignore list if it's collapsed.
			If it's not collapsed + within the screen, add it to the ignore list and expand it.
		*/
		jQuery('.cnnVPFlashCollapsed').each(function(i,val) {
			if (vidConfig[i].collapsed == true)
				videos2ignore.push(i);
			else if ( !jQuery(this).hasClass('expired') && !jQuery.belowthefold(this, settings) && !jQuery.rightoffold(this, settings) ) {
				videos2ignore.push(i);
				//Within the viewport, so do something
				appear(i);
			}
		});

		//this runs whenever the user scrolls
		if ("scroll" == settings.event) {
			jQuery(settings.container).bind("scroll", function(event) {
				jQuery('.cnnVPFlashCollapsed').each(function(i,val) {
					if( !jQuery(this).hasClass('expired') && videos2ignore.indexOf(i) == -1 ) {
						if ( !jQuery.belowthefold(this, settings) && !jQuery.rightoffold(this, settings) ) {
							videos2ignore.push(i);
							//Within the viewport, so do something
							appear(i);
						}
						else {
							return false;
						}
					}
				});
			});
		}
		return this;
	};
}

/*Paint screen waits for the browser to paint the screen, then calls the Lazy Loader*/
var PaintScreen = function() {
	var that = this;
	var paintCheck = 0;
	var maxPaintCheck = 20;

	this.init = function() {
		if( parseInt(jQuery('.cnnVPFlashCollapsed').eq(0).offset().top) > 0 ) {
			//alert( parseInt(jQuery('.cnnVPFlashCollapsed').eq(0).offset().top) );
			var lazyload = new LazyLoad().init();
		}
		else if( paintCheck < maxPaintCheck ) {
			//alert('trying again');
			paintCheck++;
			setTimeout(that.init,350);
		}
		else {
			//alert('max tries reached');
			return false;
		}
	};
}

try{ var storyVidPlayers = new SVideoFacade().init(); } catch(e){}

