/*
 * Ad: an individual ad package to be displayed.  Includes all co-ad elements.
 */
function Ad( pPrerollFormat, pAfterFunction )
{
	this.PrerollVideo = null; // a Video object
	this.BigBox = ""; // the URL of the ad javascript that will serve a Big Box ad unit
	this.StartImageTracker = ""; // the URL of an image to serve when the preroll video starts
	this.EndImageTracker = ""; // the URL of an image to serve when the preroll video ends
	this.PrerollFormat = pPrerollFormat; // the format of the PrerollVideo
	
	this.AfterFunction = pAfterFunction; // the function to call after an ad is loaded
	this.IsLoaded = false;
	this.IsDestroyed = false;
	
	this.LastAdCall = "";
	this.LoaderTag = null;
	
	this.AdIndex = Ad.SetInstance( this );
	return this.AdIndex;
	
}
Ad.DARTSite = "video.ctv";

Ad.GetInstance = function( i )
{
	if( ! Ad.__instance )
	{
		throw "Trying to get an instance of the Ad before it has been initialized";
		return;
	}
	else if( i != null && i >= 0 )
	{	
		return Ad.__instance[i];
	}
	else
	{
		return Ad.__instance[ Ad.__instance.length - 1 ];
	}
}
Ad.SetInstance = function( pAd )
{
	if( ! Ad.__instance )
	{
		Ad.__instance = new Array();
	}
	
	Ad.__instance.push( pAd );
	
	return Ad.__instance.length - 1;
}

Ad.DARTVideoTag = function( pVideo )
{
    if( ! pVideo.SiteMap )
    {
        return "default;permalink=;clip=" + pVideo.ClipId;
    }
    else
    {
        var AdCall = "";
        for( var i = pVideo.SiteMap.length - 1; i >= 0; i-- )
        {
            if( AdCall == "" )
            {
                AdCall += pVideo.SiteMap[i][0].replace( /[^a-zA-Z0-9]/ig, "" ) + ";permalink=";
            }
            
            AdCall += "/" + pVideo.SiteMap[i][0].replace( /[^a-zA-Z0-9]/ig, "" );
        }
        
        AdCall += "/ClipId" + pVideo.ClipId; 
        
        AdCall += ";clip=" + pVideo.ClipId;
        

        return AdCall;
    }
}


Ad.GetPreroll = function( pFormat, pAfterFunction )
{
	var NewAd = new Ad( pFormat, pAfterFunction );
	var AdIndex = Ad.SetInstance( NewAd );

	// Load the Javascript on the page
	
	var AdCall = "http://ad.doubleclick.net/pfadx/" + Ad.DARTSite + "/";
	
	var UpcomingVideo = Playlist.GetInstance().FindNext();
	
    AdCall += Ad.DARTVideoTag( UpcomingVideo );
    
    AdCall += ";sz=1x1";
    
    AdCall += ";ord=" + Math.round( 10000000 * Math.random() );
    
    
	// Javascript will call back to Ad.Load(...)
	//********DEBUG*********//
	if( pFormat == Format.FlashVideo )
	{
		var AdScript = document.createElement("script");
		AdScript.src = AdCall + ";format=flv";
		Log( "Getting an ad from " + AdScript.src );
		AdScript.type = "text/javascript";

		document.getElementsByTagName("head")[0].appendChild( AdScript );

		NewAd.LoaderTag = AdScript;
		
		NewAd.LastAdCall = AdScript.src;
	}
	else
	{

		var AdScript = document.createElement("script");
		AdScript.src = AdCall + ";format=wmv";
		Log( "Getting an ad from " + AdScript.src );
		AdScript.type = "text/javascript";
		document.getElementsByTagName("head")[0].appendChild( AdScript );
		
		NewAd.LoaderTag = AdScript;
		
		NewAd.LastAdCall = AdScript.src;
	}
	//********DEBUG*********//
	
	setTimeout( "Ad.GetInstance(" + AdIndex + ").CheckForLoadFailure()", 4000 );
	
	return NewAd;
	
}
Ad.Load = function( pAdInfo )
{
	var _Ad = Ad.GetInstance();
	
	if( ! pAdInfo.Preroll )
	{
		Log( "Ad.Load was called with invalid parameters.  A standard big box ad will be served." );
		
		if( Interface.SetBigBoxAd ) { Interface.SetBigBoxAd(); }
		
		return;
	}
	
	if( ! _Ad.IsDestroyed )
	{
		_Ad.PrerollVideo = new Video( { Url:pAdInfo.Preroll, Format:_Ad.PrerollFormat, IsAd:true, Duration:pAdInfo.PrerollDuration, Permalink:pAdInfo.CoAdLink } );
		_Ad.BigBox = pAdInfo.CoAdCode;
		_Ad.StartImageTracker = pAdInfo.StartPlayImage;
		_Ad.EndImageTracker = pAdInfo.EndPlayImage;

		if( Interface.SetBigBoxAd ) { Interface.SetBigBoxAd( _Ad.BigBox ); }
		
		_Ad.PrerollVideo.OnStart = function()
		{
			Log( "Started playing the ad" );
			if( _Ad.StartImageTracker ) ( new Image() ).src = _Ad.StartImageTracker;
			
			//if( Interface.SetBigBoxAd ) { Interface.SetBigBoxAd( _Ad.BigBox ); }
		}
		
		_Ad.PrerollVideo.OnEnd = function()
		{
			Log( "Ended playing the ad" );
			if( _Ad.EndImageTracker ) ( new Image() ).src = _Ad.EndImageTracker;
		}
		
		
		_Ad.IsLoaded = true;
		
		setTimeout( function() { _Ad.AfterFunction( _Ad.PrerollVideo ) }, 350 );
	}
}

Ad.prototype.BigBoxImage = function()
{
	if( Interface && Interface.GetInstance && Interface.GetInstance() )
	{
		var _Interface	= Interface.GetInstance();
		var iFrameDoc	= _Interface.BigBoxHolder.contentDocument ? _Interface.BigBoxHolder.contentDocument : ( _Interface.BigBoxHolder.contentWindow ? _Interface.BigBoxHolder.contentWindow.document : document.frames[ 0 ] );
		var images		= iFrameDoc.getElementsByTagName("img");
		
		if( images && images.length > 0 )
		{
			return images[ 0 ].src;	
		}
	}
	
	return "";
}

Ad.prototype.BigBoxSWF = function()
{
	if( Interface && Interface.GetInstance && Interface.GetInstance() )
	{
		var _Interface	= Interface.GetInstance();
		var iFrameDoc	= _Interface.BigBoxHolder.contentDocument ? _Interface.BigBoxHolder.contentDocument : ( _Interface.BigBoxHolder.contentWindow ? _Interface.BigBoxHolder.contentWindow.document : document.frames[ 0 ] );
		
		var flashObject = iFrameDoc.getElementsByTagName( "object" );
		var embed		= iFrameDoc.getElementsByTagName( "embed" );
		
		if( flashObject &&  flashObject.length > 0 )
		{
			flashObject = flashObject[ 0 ];
			
			var params	= flashObject.getElementsByTagName( "param" );
			
			for( i=0; i< params.length; i++ )
			{
				if( params[ i ].name.toLowerCase() == "movie" || params[ i ].value.toLowerCase().indexOf(".swf") > -1 )
				{
					if( params[ i ].value )
					{
						return params[ i ].value;
					}
				}
			}
		}

		if( embed &&  embed.length > 0 )
		{
			if( embed[ 0 ].src )
			{
				return embed[ 0 ].src;
			}
		}
		
	}
	
	return "";
}

Ad.prototype.BigBoxTargetURL = function()
{
	if( Interface && Interface.GetInstance && Interface.GetInstance() )
	{
		var _Interface	= Interface.GetInstance();
		var iFrameDoc	= _Interface.BigBoxHolder.contentDocument ? _Interface.BigBoxHolder.contentDocument : ( _Interface.BigBoxHolder.contentWindow ? _Interface.BigBoxHolder.contentWindow.document : document.frames[ 0 ] );
		
		var anchors		= iFrameDoc.getElementsByTagName("a");
		if( anchors && anchors.length > 0 )
		{
			return anchors[ 0 ].href;	
		}
	}
	
	return "";
}

Ad.prototype.CheckForLoadFailure = function() 
{
	if( ! this.IsLoaded )
	{
		this.Destroy();
		Playlist.GetInstance().Next( true ); // continue with the playlist without loading the ad
		throw "Failed to load Ad with '" + this.PrerollFormat + "' format." /*+ "The ad was " + this.LastAdCall*/;
	}
	else
	{
		this.IsVerified = true;
	}
	
	this.LastAdCall = "";
}
Ad.prototype.Destroy = function()
{
	this.IsDestroyed = true;
	
	try
	{
		this.LoaderTag.parentNode.removeChild( this.LoaderTag ); 
	}
	catch( Error )
	{}
	
	Log( "Destroyed Ad " + this.AdIndex );
	
	Ad.__instance[ this.AdIndex ] = null;	
		
}


/**
 * SWFObject v1.5.1: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
 *
 * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */
if(typeof deconcept=="undefined"){var deconcept={};}if(typeof deconcept.util=="undefined"){deconcept.util={};}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil={};}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params={};this.variables={};this.attributes=[];if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10]||"";},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15]||"";},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=[];var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="<embed type=\"application/x-shockwave-flash\" src=\""+this.getAttribute("swf")+"\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+(this.getAttribute("style")||"")+"\"";_19+=" id=\""+this.getAttribute("id")+"\" name=\""+this.getAttribute("id")+"\" ";var _1a=this.getParams();for(var key in _1a){_19+=[key]+"=\""+_1a[key]+"\" ";}var _1c=this.getVariablePairs().join("&");if(_1c.length>0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="<object id=\""+this.getAttribute("id")+"\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+(this.getAttribute("style")||"")+"\">";_19+="<param name=\"movie\" value=\""+this.getAttribute("swf")+"\" />";var _1d=this.getParams();for(var key in _1d){_19+="<param name=\""+key+"\" value=\""+_1d[key]+"\" />";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="<param name=\"flashvars\" value=\""+_1f+"\" />";}_19+="</object>";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.major<fv.major){return false;}if(this.major>fv.major){return true;}if(this.minor<fv.minor){return false;}if(this.minor>fv.minor){return true;}if(this.rev<fv.rev){return false;}return true;};deconcept.util={getRequestParameter:function(_2b){var q=document.location.search||document.location.hash;if(_2b==null){return q;}if(q){var _2d=q.substring(1).split("&");for(var i=0;i<_2d.length;i++){if(_2d[i].substring(0,_2d[i].indexOf("="))==_2b){return _2d[i].substring((_2d[i].indexOf("=")+1));}}}return "";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var _2f=document.getElementsByTagName("OBJECT");for(var i=_2f.length-1;i>=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;


/*
 * FlashController: controls a Flash video player
 */
function FlashController( pTheme, pPrePlayImageUrl )
{
    this.thePlayerID = null;
    this.theHTMLwrapperID = null;
	
	this.Format = Format.FlashVideo;
	this.Theme = "http://watch.ctv.ca/news/themes/CTVNews/player/theme.aspx";
	
	FlashController.__instance = this;
	FlashController.IsOneClipPlayer = false;

	if( pTheme )
	{
	    this.Theme = pTheme;
	    FlashController.IsOneClipPlayer = true;
	}

	if( pPrePlayImageUrl )
	{
	    this.Instantiate( Interface.GetInstance().PlayerViewer.id, "__FlashPlayer", "http://watch.ctv.ca/news/Flash/player.swf", this.Theme, "", "", false, "", "", pPrePlayImageUrl );
	}
}

FlashController.GetInstance = function()
{
	if( ! FlashController.__instance )
	{
		FlashController.__instance = new FlashController();
	}
	
	return FlashController.__instance;
}
FlashController.prototype.Wait = function()
{
	if( this.thePlayerID && document.getElementById( this.thePlayerID ) )
	{
		document.getElementById( this.thePlayerID ).Wait();
	}
}
FlashController.prototype.Loading = function()
{
	if( this.thePlayerID && document.getElementById( this.thePlayerID ) && document.getElementById( this.thePlayerID ).Loading )
	{
		document.getElementById( this.thePlayerID ).Loading();
	}
}

FlashController.prototype.Destroy = function()
{
	try
	{
		 document.getElementById( this.theHTMLwrapperID ).innerHTML = "";
	}
	catch(e) {}
}

FlashController.prototype.Play = function( pVideo )
{
	Log( "Loading into Flash player: " + pVideo.Url );
	
	var permalinkToPass = "";
	
	if( 
	    pVideo.IsAd 
	    || FlashController.IsOneClipPlayer	    
	)
	{
	    permalinkToPass = pVideo.Permalink;
	}
	
	if( this.thePlayerID && document.getElementById( this.thePlayerID ) && document.getElementById( this.thePlayerID ).PlayUrl )
	{
	    document.getElementById( this.thePlayerID ).PlayUrl( pVideo.Url, pVideo.IsAd, pVideo.BugUrl, pVideo.Title, permalinkToPass );
	}
	else
	{
	    this.Instantiate( Interface.GetInstance().PlayerViewer.id, "__FlashPlayer", "http://watch.ctv.ca/news/Flash/player.swf", this.Theme, pVideo.Url, pVideo.BugUrl , pVideo.IsAd, pVideo.Title, permalinkToPass, null );
	}
}

FlashController.prototype.Instantiate = function( htmlID, flashID, swfURL, themeURL, videoURL, bugURL, isAd, Title, Permalink, pPrePlayImageUrl )
{

	this.thePlayerID = flashID;	
	this.theHTMLwrapperID = htmlID;

	var alreadyExists = document.getElementById(this.thePlayerID) && document.getElementById(this.thePlayerID).PlayUrl ;
	if( alreadyExists )
	{
	    document.getElementById( this.thePlayerID ).PlayUrl( videoURL, isAd, bugURL, Title, Permalink );
		return;	
	}

	// if less than 6.0.65, express install won't be able to upgrade them.
	// we should just show a message with a link to go get the player, I guess?

	var fpVersion = deconcept.SWFObjectUtil.getPlayerVersion();
	var goodForExpressInstall = false;
	
	if (fpVersion['major'] > 6) 
	{
		goodForExpressInstall = true;
	}
	
	if (fpVersion['major'] == 6) 
	{
		// we need to check the minor and revision numbers
		
		if (fpVersion['minor'] > 0) 
		{
			goodForExpressInstall = true;
		} 
		else if (fpVersion['minor'] == 0) 
		{
			if (fpVersion['rev'] >= 65) 
			{
				goodForExpressInstall = true;
			}
		}
		
	}

	if ( goodForExpressInstall ) 
	{
		//var isOneClipPlayer = false;
		
		var so = new SWFObject(swfURL+"?themeURL="+themeURL, flashID, "100%", "100%", "8", "#000000");
		so.addParam("allowScriptAccess", "always");
		
		var isSafeForTransparent = FlashController.BrowserCanDoTransparentFlashPlugin();
		
		if( isSafeForTransparent )
		{
			so.addParam("wmode", "transparent");		
		}
		
		so.addParam("allowFullScreen", "true");
		
		if( pPrePlayImageUrl )
		{
		    so.addVariable("PrePlayImageUrl", pPrePlayImageUrl);
		}
		else
		{
		    // ROSSMAN: Bug #5481: I added the ESCAPE below, because it was breaking the player without it...?
		    so.addVariable("videoURL", escape( videoURL ) );
		}
		so.addVariable("bugURL", bugURL);
		so.addVariable("isAd", isAd);
		so.addVariable("nowPlaying", Title);
		
		if( true || FlashController.IsOneClipPlayer )
		{
			so.addVariable("permalinkURL", Permalink);
			so.addParam("wmode", "transparent");		
		}
	
		so.useExpressInstall('http://watch.ctv.ca/news/Flash/expressinstall.swf');
		so.write(htmlID);

		/* NT added this for flash compliance with IE on 3/19/08 */
		window.__FlashPlayer = document.getElementById("__FlashPlayer");
	}
	else 
	{
		if( Interface.DisplayFlashNeedsToBeManuallyUpgradedMessage )
		{
			Interface.DisplayFlashNeedsToBeManuallyUpgradedMessage();
			Log("The users flash player plugin is older than v6.0.65 - user will need to manually upgrade.");
		}
		else
		{
			Player.Error( "No Flash Player detected" );
		}	
	}
}

FlashController.BrowserCanDoTransparentFlashPlugin = function()
{
	if( BrowserDetect && BrowserDetect.browser )
	{
		return BrowserDetect.browser.indexOf("Explorer") > -1;
	}
	
	return false;
}



/*
 * SilverlightController: controls a Silverlight video player
 */
function SilverlightController( pTheme )
{
	this.Format = Format.WindowsMediaVideo;
	
	this.includeCounter		= 1;
	this.internalController = null;
	this.hasStartedJSInstantation	= false;
	this.JSisInstantiated	= false;
	
	this.theme				= "http://watch.ctv.ca/news/themes/CTVNews/player/theme.aspx";

	SilverlightController.IsCrossDomainLoad = pTheme!=null && pTheme != 'undefined' && ( ( SilverlightController.DetermineDomain( pTheme ) != SilverlightController.DetermineDomain( this.theme ) ) || ( SilverlightController.DetermineDomain( this.theme ) != SilverlightController.DetermineDomain( document.location ) ) ); 
	
	if( pTheme )
	{
		this.theme = pTheme;
	}
	
	SilverlightController.__instance = this;
	
	
	this.LoadHtml( );
}

SilverlightController.DetermineDomain = function( url )
{
	return parseUri( url ).host;
}

SilverlightController.GetInstance = function()
{
	if( ! SilverlightController.__instance )
	{
		SilverlightController.__instance = new SilverlightController();
	}
	
	return SilverlightController.__instance;
}

SilverlightController.prototype.Destroy = function()
{
   this.internalController = null;
}


SilverlightController.prototype.Play = function( pVideo )
{
	var permalinkToPass = ( pVideo.IsAd || FlashController.IsOneClipPlayer ) ? pVideo.Permalink : "";
	var shouldWait = ! this.JSisInstantiated;

	if(	this.internalController == null )
	{
		var Me = this;

		if( shouldWait )
		{
			if(! this.hasStartedJSInstantation )
			{
				this.LoadHtml();
			}
		}
		else
		{
			shouldWait = SilverlightController.IsCrossDomainLoad && document.getElementById( "xamlContent" ) == null;
		}
		
		if( shouldWait )
		{
			Log("Silverlight Player is not yet instantiated, sleeping 100 milliseconds.");
			
			setTimeout( function() { Me.Play( pVideo ); }, 100 );
			return;
		}
		else
		{
			Log("Silverlight Player is ready to play");
		}
		
		var parentElement		= Interface.GetInstance().PlayerViewer;
		parentElement.innerHTML = "";
		
		var SceneFile = "http://watch.ctv.ca/news/SilverlightPlayer/Scene.xml";

		
		try
		{
			this.internalController = new SilverlightPlayer( parentElement, SceneFile, this.theme, pVideo.Url, pVideo.IsAd, pVideo.BugUrl, pVideo.Title, permalinkToPass, null);
		}
		catch(e)
		{ 
			try
			{
				setTimeout( function() { Me.internalController = new SilverlightPlayer( parentElement, SceneFile, this.theme, pVideo.Url, pVideo.IsAd, pVideo.BugUrl, pVideo.Title, permalinkToPass, null); }, 350  ); 
			}
			catch(ee)
			{
				setTimeout( function() { Me.internalController = new SilverlightPlayer( parentElement, SceneFile, this.theme, pVideo.Url, pVideo.IsAd, pVideo.BugUrl, pVideo.Title, permalinkToPass, null ); }, 1000  ); 
			}
		}
	}
	else
	{
		this.internalController.PlayUrl( pVideo.Url, pVideo.IsAd, pVideo.BugUrl, pVideo.Title, permalinkToPass, null );
	}
}

SilverlightController.prototype.Wait = function()
{
	if( this.internalController )
	{
		this.internalController.Wait()
	}
}

SilverlightController.prototype.Loading = function()
{
	if( this.internalController )
	{
		this.internalController.Loading();
	}
}

SilverlightController.IsInstalled = function()
{
	return Silverlight.isInstalled( SilverlightPlayer.SilverlightVersion );
}

SilverlightController.prototype.LoadHtml = function()
{
	this.hasStartedJSInstantation = true;
	
	var includes = [ "createSilverlight.js",
					 "HttpRequest.js",
					 "Scene.xaml.js",
					 "MovieSlider.js",
					 "VolumeSlider.js",
					 "XAMLfactory.aspx",
					 "XAMLdata.js",
					 "ConfigXamlMapper.js",
					 "VideoPlayer.js"
					];
	

	if( SilverlightController.IsCrossDomainLoad )
	{
		this.AddFirstSceneFile();
	}
	
	this.AddJSIncludes( includes );	
}

SilverlightController.prototype.AddFirstSceneFile = function()
{
	var sceneId		= "xamlContent";
	
	if( ! document.getElementById( sceneId ) )
	{
		var body		= document.getElementsByTagName("body")[0];
		var newScript	= document.createElement("script");
		
		newScript.id	= sceneId;
		newScript.type	= "text/xaml";
		
		
		newScript.text = '<Canvas   xmlns="http://schemas.microsoft.com/client/2007"   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   Loaded="canvas_loaded"><Canvas.Resources><Storyboard Name="BufferingAnimation" Storyboard.TargetProperty="Angle" ><DoubleAnimation  From="0" To="360" Duration="0:0:2.16" RepeatBehavior="Forever" /></Storyboard><Storyboard Name="TextScrollAnimation" BeginTime="0:0:00" Storyboard.TargetProperty="(Canvas.Left)" ><DoubleAnimation Storyboard.TargetName="ScrollingText"   /><DoubleAnimation Storyboard.TargetName="ScrollingText2"  /><DoubleAnimation Storyboard.TargetName="ScrollingTextShadow"   /><DoubleAnimation Storyboard.TargetName="ScrollingText2Shadow"  /></Storyboard></Canvas.Resources><Canvas Name="PreloadImages" Opacity="0"></Canvas></Canvas>';

		body.appendChild( newScript );
		
		Log("Added the initial Silverlight scene to the page");
	}
	else
	{
		Log("Silverlight scene is already on the page");
	}
}

SilverlightController.prototype.AddJSIncludes = function( filePaths )
{
	this.includeCounter = filePaths.length;
	
	for( var i=0; i < filePaths.length; i++ )
	{
		var newID			= "SilverlightScript" + (i+1);
		
		var Me				= this;
		var fileName		= filePaths[ i ];
		var handlerFunction	= new function() { Me.JSisInstantiated = ( --Me.includeCounter <= 0 );  Log("INCLUDE ADDED:" + fileName + "  " + Me.includeCounter + " left"); };
			
		if( ! document.getElementById( newID ) )
		{
			var head		= document.getElementsByTagName("head")[0];
			var newScript	= document.createElement("script");
			
			newScript.type	= "text/javascript";
			newScript.src	= "http://watch.ctv.ca/news/SilverlightPlayer/" + filePaths[ i ];
			newScript.id	= newID;
			
			newScript.onload = handlerFunction;
			if( newScript.onload == handlerFunction )
			{
				// DO NOTHING
			}
			else if( newScript.addEventListener )
			{
				newScript.addEventListener( "load", handlerFunction, false );
			}
			else if( newScript.attachEvent ) 
			{
				newScript.attachEvent( "onload", handlerFunction );
			}
			
			head.appendChild( newScript );
		}
		else
		{
			Log( fileName + " is already on the page." );
			this.JSisInstantiated = ( --this.includeCounter <= 0 );
		}
	}
}


///////////////////////////////////////////////////////////////////////////////
//
//  Silverlight.js   			version 2.0.30523.6
//
//  This file is provided by Microsoft as a helper file for websites that
//  incorporate Silverlight Objects. This file is provided under the Microsoft
//  Public License available at 
//  http://code.msdn.microsoft.com/silverlightjs/Project/License.aspx.  
//  You may not use or distribute this file or the code in this file except as 
//  expressly permitted under that license.
// 
//  Copyright (c) Microsoft Corporation. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////

if (!window.Silverlight)
{
    window.Silverlight = { };
}

//////////////////////////////////////////////////////////////////
//
// _silverlightCount:
//
// Counter of globalized event handlers
//
//////////////////////////////////////////////////////////////////
Silverlight._silverlightCount = 0;

//////////////////////////////////////////////////////////////////
//
// fwlinkRoot:
//
// Prefix for fwlink URL's
//
//////////////////////////////////////////////////////////////////
Silverlight.fwlinkRoot='http://go2.microsoft.com/fwlink/?LinkID=';

//////////////////////////////////////////////////////////////////
//  
// onGetSilverlight:
//
// Called by Silverlight.GetSilverlight to notify the page that a user
// has requested the Silverlight installer
//
//////////////////////////////////////////////////////////////////
Silverlight.onGetSilverlight = null;

//////////////////////////////////////////////////////////////////
//
// onSilverlightInstalled:
//
// Called by Silverlight.WaitForInstallCompletion when the page detects
// that Silverlight has been installed. The event handler is not called
// in upgrade scenarios.
//
//////////////////////////////////////////////////////////////////
Silverlight.onSilverlightInstalled = function () {window.location.reload(false);};

//////////////////////////////////////////////////////////////////
//
// isInstalled:
//
// Checks to see if the correct version is installed
//
//////////////////////////////////////////////////////////////////
Silverlight.isInstalled = function(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;
}
//////////////////////////////////////////////////////////////////
//
// WaitForInstallCompletion:
//
// Occasionally checks for Silverlight installation status. If it
// detects that Silverlight has been installed then it calls
// Silverlight.onSilverlightInstalled();. This is only supported
// if Silverlight was not previously installed on this computer.
//
//////////////////////////////////////////////////////////////////
Silverlight.WaitForInstallCompletion = function()
{
    if ( ! Silverlight.isBrowserRestartRequired && Silverlight.onSilverlightInstalled )
    {
        try
        {
            navigator.plugins.refresh();
        }
        catch(e)
        {
        }
        if ( Silverlight.isInstalled(null) )
        {
            Silverlight.onSilverlightInstalled();
        }
        else
        {
              setTimeout(Silverlight.WaitForInstallCompletion, 3000);
        }    
    }
}
//////////////////////////////////////////////////////////////////
//
// __startup:
//
// Performs startup tasks
//////////////////////////////////////////////////////////////////
Silverlight.__startup = function()
{
    Silverlight.isBrowserRestartRequired = Silverlight.isInstalled(null);
    if ( !Silverlight.isBrowserRestartRequired)
    {
        Silverlight.WaitForInstallCompletion();
    }
    if (window.removeEventListener) { 
       window.removeEventListener('load', Silverlight.__startup , false);
    }
    else { 
        window.detachEvent('onload', Silverlight.__startup );
    }
}

if (window.addEventListener) 
{
    window.addEventListener('load', Silverlight.__startup , false);
}
else 
{
    window.attachEvent('onload', Silverlight.__startup );
}

///////////////////////////////////////////////////////////////////////////////
// createObject:
//
// Inserts a Silverlight <object> tag or installation experience into the HTML
// DOM based on the current installed state of Silverlight. 
//
/////////////////////////////////////////////////////////////////////////////////

Silverlight.createObject = function(source, parentElement, id, properties, events, initParams, userContext)
{
    var slPluginHelper = new Object();
    var slProperties = properties;
    var slEvents = events;
    
    slPluginHelper.version = slProperties.version;
    slProperties.source = source;    
    slPluginHelper.alt = slProperties.alt;
    
    //rename properties to their tag property names. For bacwards compatibility
    //with Silverlight.js version 1.0
    if ( initParams )
        slProperties.initParams = initParams;
    if ( slProperties.isWindowless && !slProperties.windowless)
        slProperties.windowless = slProperties.isWindowless;
    if ( slProperties.framerate && !slProperties.maxFramerate)
        slProperties.maxFramerate = slProperties.framerate;
    if ( id && !slProperties.id)
        slProperties.id = id;
    
    // remove elements which are not to be added to the instantiation tag
    delete slProperties.ignoreBrowserVer;
    delete slProperties.inplaceInstallPrompt;
    delete slProperties.version;
    delete slProperties.isWindowless;
    delete slProperties.framerate;
    delete slProperties.data;
    delete slProperties.src;
    delete slProperties.alt;


    // detect that the correct version of Silverlight is installed, else display install

    if (Silverlight.isInstalled(slPluginHelper.version))
    {
        //move unknown events to the slProperties array
        for (var name in slEvents)
        {
            if ( slEvents[name])
            {
                if ( name == "onLoad" && typeof slEvents[name] == "function" && slEvents[name].length != 1 )
                {
                    var onLoadHandler = slEvents[name];
                    slEvents[name]=function (sender){ return onLoadHandler(document.getElementById(id), userContext, sender)};
                }
                var handlerName = Silverlight.__getHandlerName(slEvents[name]);
                if ( handlerName != null )
                {
                    slProperties[name] = handlerName;
                    slEvents[name] = null;
                }
                else
                {
                    throw "typeof events."+name+" must be 'function' or 'string'";
                }
            }
        }
        slPluginHTML = Silverlight.buildHTML(slProperties);
    }
    //The control could not be instantiated. Show the installation prompt
    else 
    {
        slPluginHTML = Silverlight.buildPromptHTML(slPluginHelper);
    }

    // insert or return the HTML
    if(parentElement)
    {
        parentElement.innerHTML = slPluginHTML;
    }
    else
    {
        return slPluginHTML;
    }

}

///////////////////////////////////////////////////////////////////////////////
//
//  buildHTML:
//
//  create HTML that instantiates the control
//
///////////////////////////////////////////////////////////////////////////////
Silverlight.buildHTML = function( slProperties)
{
    var htmlBuilder = [];

    htmlBuilder.push('<object type=\"application/x-silverlight\" data="data:application/x-silverlight,"');
    if ( slProperties.id != null )
    {
        htmlBuilder.push(' id="' + slProperties.id + '"');
    }
    if ( slProperties.width != null )
    {
        htmlBuilder.push(' width="' + slProperties.width+ '"');
    }
    if ( slProperties.height != null )
    {
        htmlBuilder.push(' height="' + slProperties.height + '"');
    }
    htmlBuilder.push(' >');
    
    delete slProperties.id;
    delete slProperties.width;
    delete slProperties.height;
    
    for (var name in slProperties)
    {
        if (slProperties[name])
        {
            htmlBuilder.push('<param name="'+Silverlight.HtmlAttributeEncode(name)+'" value="'+Silverlight.HtmlAttributeEncode(slProperties[name])+'" />');
        }
    }
    htmlBuilder.push('<\/object>');
    return htmlBuilder.join('');
}



//////////////////////////////////////////////////////////////////
//
// createObjectEx:
//
// takes a single parameter of all createObject 
// parameters enclosed in {}
//
//////////////////////////////////////////////////////////////////

Silverlight.createObjectEx = function(params)
{
    var parameters = params;
    var html = Silverlight.createObject(parameters.source, parameters.parentElement, parameters.id, parameters.properties, parameters.events, parameters.initParams, parameters.context);
    if (parameters.parentElement == null)
    {
        return html;
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////
//
// buildPromptHTML
//
// Builds the HTML to prompt the user to download and install Silverlight
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.buildPromptHTML = function(slPluginHelper)
{
    var slPluginHTML = "";
    var urlRoot = Silverlight.fwlinkRoot;
    var shortVer = slPluginHelper.version ;
    if ( slPluginHelper.alt )
    {
        slPluginHTML = slPluginHelper.alt;
    }
    else
    {
        if (! shortVer )
        {
            shortVer="";
        }
        slPluginHTML = "<a href='javascript:Silverlight.getSilverlight(\"{1}\");' style='text-decoration: none;'><img src='{2}' alt='Get Microsoft Silverlight' style='border-style: none'/></a>";
        slPluginHTML = slPluginHTML.replace('{1}', shortVer );
        slPluginHTML = slPluginHTML.replace('{2}', urlRoot + '108181');
    }
    
    return slPluginHTML;
}

///////////////////////////////////////////////////////////////////////////////////////////////
//
// getSilverlight:
//
// Navigates the browser to the appropriate Silverlight installer
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.getSilverlight = function(version)
{
    if (Silverlight.onGetSilverlight )
    {
        Silverlight.onGetSilverlight();
    }
    
    var shortVer = "";
    var reqVerArray = String(version).split(".");
    if (reqVerArray.length > 1)
    {
        var majorNum = parseInt(reqVerArray[0] );
        if ( isNaN(majorNum) || majorNum < 2 )
        {
            shortVer = "1.0";
        }
        else
        {
            shortVer = reqVerArray[0]+'.'+reqVerArray[1];
        }
    }
    
    var verArg = "";
    
    if (shortVer.match(/^\d+\056\d+$/) )
    {
        verArg = "&v="+shortVer;
    }
    
    Silverlight.followFWLink("114576" + verArg);
}


///////////////////////////////////////////////////////////////////////////////////////////////
//
// followFWLink:
//
// Navigates to a url based on fwlinkid
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.followFWLink = function(linkid)
{
    top.location=Silverlight.fwlinkRoot+String(linkid);
}

///////////////////////////////////////////////////////////////////////////////////////////////
//
// HtmlAttributeEncode:
//
// Encodes special characters in input strings as charcodes
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.HtmlAttributeEncode = function( strInput )
{
      var c;
      var retVal = '';

    if(strInput == null)
      {
          return null;
    }
      
      for(var cnt = 0; cnt < strInput.length; cnt++)
      {
            c = strInput.charCodeAt(cnt);

            if (( ( c > 96 ) && ( c < 123 ) ) ||
                  ( ( c > 64 ) && ( c < 91 ) ) ||
                  ( ( c > 43 ) && ( c < 58 ) && (c!=47)) ||
                  ( c == 95 ))
            {
                  retVal = retVal + String.fromCharCode(c);
            }
            else
            {
                  retVal = retVal + '&#' + c + ';';
            }
      }
      
      return retVal;
}
///////////////////////////////////////////////////////////////////////////////
//
//  default_error_handler:
//
//  Default error handling function 
//
///////////////////////////////////////////////////////////////////////////////

Silverlight.default_error_handler = function (sender, args)
{
    var iErrorCode;
    var errorType = args.ErrorType;

    iErrorCode = args.ErrorCode;

    var errMsg = "\nSilverlight error message     \n" ;

    errMsg += "ErrorCode: "+ iErrorCode + "\n";


    errMsg += "ErrorType: " + errorType + "       \n";
    errMsg += "Message: " + args.ErrorMessage + "     \n";

    if (errorType == "ParserError")
    {
        errMsg += "XamlFile: " + args.xamlFile + "     \n";
        errMsg += "Line: " + args.lineNumber + "     \n";
        errMsg += "Position: " + args.charPosition + "     \n";
    }
    else if (errorType == "RuntimeError")
    {
        if (args.lineNumber != 0)
        {
            errMsg += "Line: " + args.lineNumber + "     \n";
            errMsg += "Position: " +  args.charPosition + "     \n";
        }
        errMsg += "MethodName: " + args.methodName + "     \n";
    }
    alert (errMsg);
}

///////////////////////////////////////////////////////////////////////////////////////////////
//
// __cleanup:
//
// Releases event handler resources when the page is unloaded
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.__cleanup = function ()
{
    for (var i = Silverlight._silverlightCount - 1; i >= 0; i--) {
        window['__slEvent' + i] = null;
    }
    Silverlight._silverlightCount = 0;
    if (window.removeEventListener) { 
       window.removeEventListener('unload', Silverlight.__cleanup , false);
    }
    else { 
        window.detachEvent('onunload', Silverlight.__cleanup );
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////
//
// __getHandlerName:
//
// Generates named event handlers for delegates.
//
///////////////////////////////////////////////////////////////////////////////////////////////
Silverlight.__getHandlerName = function (handler)
{
    var handlerName = "";
    if ( typeof handler == "string")
    {
        handlerName = handler;
    }
    else if ( typeof handler == "function" )
    {
        if (Silverlight._silverlightCount == 0)
        {
            if (window.addEventListener) 
            {
                window.addEventListener('onunload', Silverlight.__cleanup , false);
            }
            else 
            {
                window.attachEvent('onunload', Silverlight.__cleanup );
            }
        }
        var count = Silverlight._silverlightCount++;
        handlerName = "__slEvent"+count;
        
        window[handlerName]=handler;
    }
    else
    {
        handlerName = null;
    }
    return handlerName;
}







/*
	parseUri 1.2.1
	(c) 2007 Steven Levithan <stevenlevithan.com>
	MIT License
*/

function parseUri (str) {
	var	o   = parseUri.options,
		m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
		uri = {},
		i   = 14;

	while (i--) uri[o.key[i]] = m[i] || "";

	uri[o.q.name] = {};
	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
		if ($1) uri[o.q.name][$1] = $2;
	});

	return uri;
};

parseUri.options = {
	strictMode: false,
	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
	q:   {
		name:   "queryKey",
		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
	},
	parser: {
		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
	}
};
/*
 * Metrics: tracks the user within the player via a metrics package
 */

// pProject: the Omniture project id
function Metrics( pAccountId, pProject )
{
    this.AccountId = pAccountId;
	this.Project = pProject;
	
	this.CurrentClip = null;
	this.CurrentLocation = -1;
	
	this.LastTrackedLocation = 0;
	this.LastTrackedIntervalLocation = 0;
	
	this.KeyInterval = [ [ 20, "event9" ] ]; //an array of "key times" to track. This case will track at 20 seconds.
	this.KeyIntervalPercentage = [ [ 80, "event10" ], [99, "event6"] ]; //an array of "key times" to track as a percentage of video duration. This case will track at 80% complete.
	
	this.KeyPoints = new Array();
	
	this.trackingIntervalToken = null;

	this.TRACKING_INTERVAL = 120; //in seconds
	this.REACHED_CLIP_POINT_INTERVAL = 10; //in seconds
	
	this.IsTrackingVideo = false;
	this.HasSentVideoStart = false;
	
	this.ShouldUseParallelTracking = false;
	
	Metrics.__instance = this;
}

Metrics.VIDEO_LABEL = "CustomLinkForVideoTracking";
Metrics.VIDEOPLAYER_SITESECTION = "VideoPlayer"

Metrics.GetInstance = function()
{
	if( ! Metrics.__instance )
	{
		Metrics.__instance = new Metrics( "chumtvctv", "CTV News Video Player" ); 
		return Metrics.__instance;
	}
	else
	{
		return Metrics.__instance;
	}
}

Metrics.GetVideoTitle = function( pVideo )
{
    if( pVideo.Title != undefined && pVideo.Title != "undefined" && pVideo.Title != null )
    {
        return Metrics.TrimLabel( pVideo.Title );
    }
    
     return Metrics.TrimLabel( pVideo.Permalink );
}

Metrics.GetVideoDuration = function( pVideo )
{
	if( pVideo.Duration != undefined && pVideo.Duration != "undefined" && pVideo.Duration != null && pVideo.Duration > 0 )
    {
        try
        {
			return parseInt( "" + pVideo.Duration );  
		}
		catch(e) {}
    }
    
     return 0;
}

Metrics.GetVideoId = function( pVideo )
{
    if( pVideo.ClipId != undefined && pVideo.ClipId != "undefined" && pVideo.ClipId != null )
    {
        return pVideo.ClipId;
    }
    
    return -1;
}

Metrics.GetVideoPath = function( pVideo )
{
    if( ! pVideo.SiteMap )
    {
        if( pVideo.Permalink )
        {
			return Metrics.TrimLabel( pVideo.Permalink );
		}
		
		return Metrics.TrimLabel( pVideo.Title );
    }
    else
    {
        var Label = "";
        for( var i = pVideo.SiteMap.length - 1; i >= 0; i-- )
        {
            if( Label != "" )
            {
                Label += "|";
            }
            Label += pVideo.SiteMap[i][0].replace( /[|]/ig, "" );
            try
            {
                Label += "[" + /[0-9]+$/i.exec( pVideo.SiteMap[i][1] ) + "]";
            }
            catch( err )
            {}
        }
        Label += "|Clip[" + pVideo.ClipId + "]"; 

        return Metrics.TrimLabel( Label );
    }
}


Metrics.TrimLabel = function( pLabel )
{
	if( pLabel.length > 100 )
	{
		return pLabel.substring( 0, 99 );
	}
	
	return pLabel;	 
}

Metrics.StartedClip = function( pVideo )
{
	var CurrentClip = pVideo;
	
	if( ! CurrentClip )
	{
	    CurrentClip = Playlist.GetInstance().Current;
	}
	
	if( ! CurrentClip.IsAd )
	{
	    if( CurrentClip != Metrics.GetInstance().CurrentClip )
	    {
	        Metrics.GetInstance().CurrentClip = CurrentClip;

	        Metrics.GetInstance().LastTrackedLocation = 0;
			Metrics.GetInstance().LastTrackedIntervalLocation = 0;
			Metrics.GetInstance().IsTrackingVideo = true;
			Metrics.GetInstance().HasSentVideoStart = false;
			
	        if( CurrentClip.Duration > 0 )
	        {
				Metrics.SendStartedClip( CurrentClip );	
				Metrics.InitializeKeyPoints( CurrentClip );
				
				Metrics.GetInstance().HasSentVideoStart = true;
			}
			/*else
			{
				//sometimes the clips don't have a duration immediately, so give it awhile...
				setTimeout( function() { Metrics.SendStartedClip( CurrentClip );Metrics.InitializeKeyPoints( CurrentClip ); }, 2500 );
			}*/
		
			if( Metrics.GetInstance().trackingIntervalToken != null )
			{
				clearInterval( Metrics.GetInstance().trackingIntervalToken );
				Metrics.GetInstance().trackingIntervalToken = null;
			}
			var _Metrics = Metrics.GetInstance();
			_Metrics.trackingIntervalToken = setInterval(	function() 
															{ 
																_Metrics.LastTrackedIntervalLocation  += _Metrics.TRACKING_INTERVAL;
																Metrics.OnIntervalClipTime	( CurrentClip,
																							 Metrics.NonZero( _Metrics.LastTrackedIntervalLocation )
																							);
															}, ( _Metrics.TRACKING_INTERVAL * 1000 ) );
	    }
    }
    
    
}

Metrics.InitializeKeyPoints = function ( pVideo )
{
	var CurrentClip = pVideo; 
	
	if( ! CurrentClip )
	{
	    CurrentClip = Playlist.GetInstance().Current;
	}
	
	Metrics.GetInstance().KeyPoints = new Array();
	
	for( var i=0; i< Metrics.GetInstance().KeyInterval.length; i++ )
	{
		var keyPoint =  parseInt( Metrics.GetInstance().KeyInterval[ i ][ 0 ] );
		Metrics.GetInstance().KeyPoints.push( [ keyPoint, ( Metrics.GetInstance().KeyInterval[ i ][ 1 ] ) ] );
	}
	
	if( CurrentClip.Duration > 0 )
	{
		for( var i=0; i< Metrics.GetInstance().KeyIntervalPercentage.length; i++ )
		{
			var keyPoint = parseInt( ( Metrics.GetInstance().KeyIntervalPercentage[ i ][ 0 ] / 100 ) * CurrentClip.Duration );
			Metrics.GetInstance().KeyPoints.push( [ keyPoint, ( Metrics.GetInstance().KeyIntervalPercentage[ i ][ 1 ] ) ]  );
		}
	}
}

Metrics.EndedClip = function( pVideo )
{
	var CurrentClip = Playlist.GetInstance().Current;
	
	if( ! CurrentClip )
	{
	    CurrentClip = pVideo;
	}

	if( ! CurrentClip.IsAd )
	{
		if( Metrics.GetInstance().IsTrackingVideo )
		{
			var VideoProbablyEndedNaturally = ( Metrics.GetInstance().KeyPoints.length == 0 ) && ( CurrentClip.Duration - Metrics.GetInstance().LastTrackedLocation ) < Metrics.GetInstance().TRACKING_INTERVAL;
			
			if( ! VideoProbablyEndedNaturally ) // we need to let them know that the video was watched until the end
			{
				Metrics.SendLeftClipBeforeEnd( CurrentClip );
			}
			
			Metrics.GetInstance().IsTrackingVideo = false;
		}
    }
}

Metrics.TrackSearch = function( pSearchTerm, pNumberOfResults )
{
	var s = Metrics.GetTrackingInstance( null );		
	
	var searchResults = parseInt( pNumberOfResults ) > 0 ? ("" + pNumberOfResults ) : "zero";
	
	s.linkTrackVars		= "prop1,eVar1,prop2,events";
	s.linkTrackEvents	= "event1";

	s.prop1= s.eVar1 = pSearchTerm.toLowerCase();
	s.prop2= searchResults;
	s.events = "event1";
	
	var label = Metrics.TrimLabel( "Search for " + pSearchTerm  + " had " + pNumberOfResults + " results." );
	Metrics.TrackLink( s, true, "o", Metrics.VIDEO_LABEL );
}

Metrics.ReachedClipKeyPoint = function( pSeconds )
{
	var CurrentClip = Metrics.GetInstance().CurrentClip;
	
	if( CurrentClip )
	{
		if( ! Metrics.GetInstance().HasSentVideoStart )
		{
			Metrics.SendStartedClip( CurrentClip );	
			Metrics.InitializeKeyPoints( CurrentClip );
					
			Metrics.GetInstance().HasSentVideoStart = true;
		}
		
		for( var i=0; i < Metrics.GetInstance().KeyPoints.length; i++ )
		{
			if( ( Metrics.GetInstance().KeyPoints[ i ][ 0 ] - pSeconds ) < Metrics.GetInstance().REACHED_CLIP_POINT_INTERVAL )
			{
				Metrics.OnKeyPointClipTime( CurrentClip, Metrics.NonZero(  Metrics.GetInstance().KeyPoints[ i ][ 0 ] ), Metrics.GetInstance().KeyPoints[ i ][ 1 ] );
				Metrics.GetInstance().KeyPoints.splice( i, 1 );

				break;
			}
		}
	}
}

Metrics.GetVideoLabel = function( pVideo )
{
    if( ! pVideo.SiteMap )
    {
        return pVideo.Permalink;
    }
    else
    {
        var Label = "";
        for( var i = pVideo.SiteMap.length - 1; i >= 0; i-- )
        {
            if( Label != "" )
            {
                Label += "|";
            }
            Label += pVideo.SiteMap[i][0].replace( /[|]/ig, "" );
            try
            {
                Label += "[" + /[0-9]+$/i.exec( pVideo.SiteMap[i][1] ) + "]";
            }
            catch( err )
            {}
        }
        Label += "|Clip[" + pVideo.ClipId + "]"; 
        return Label;
    }
}

Metrics.ApplyKnownSections = function( sInstance, pVideo )
{
	var hasSSiteSection = typeof( s_siteSection ) != undefined && typeof( s_siteSection ) != "undefined" && typeof( s_siteSection ) != null;
	var hasSSubSection1 = typeof( s_subSection1 ) != undefined && typeof( s_subSection1 ) != "undefined" && typeof( s_subSection1 ) != null;
	var hasSSiteCategory= typeof( s_siteCategory ) != undefined && typeof( s_siteCategory ) != "undefined" && typeof( s_siteCategory ) != null;
	var hasSSiteName	= typeof( s_siteName ) != undefined && typeof( s_siteName ) != "undefined" && typeof( s_siteName ) != null;
	var hasSSiteFamily  = typeof( s_siteFamily ) != undefined && typeof( s_siteFamily ) != "undefined" && typeof( s_siteFamily ) != null;
	var prefix = "";

	if( hasSSiteSection && s_siteSection != ""  )
	{
		sInstance.linkTrackVars += prefix + "prop6,eVar6";
		sInstance.prop6 = sInstance.eVar6 = sInstance.channel = sInstance.hier1 = s_siteSection;
	}
	else
	{
		sInstance.linkTrackVars += prefix + "prop6,eVar6";
		sInstance.prop6 = sInstance.eVar6 = sInstance.channel = sInstance.hier1 = Metrics.VIDEOPLAYER_SITESECTION;
	}
	
	prefix = sInstance.linkTrackVars == "" ? "" : ( ( sInstance.linkTrackVars.length > 0 && sInstance.linkTrackVars.substring( sInstance.linkTrackVars - 1 ) == "," ) ? "" : "," );

	if( hasSSubSection1 && s_subSection1 != ""  )
	{
		sInstance.linkTrackVars += prefix + "prop7,eVar7"
		sInstance.prop7 = sInstance.eVar7 = s_subSection1;
		
		sInstance.hier1 += prefix + s_subSection1;
	}
	
	prefix = sInstance.linkTrackVars == "" ? "" : ( ( sInstance.linkTrackVars.length > 0 && sInstance.linkTrackVars.substring( sInstance.linkTrackVars - 1 ) == "," ) ? "" : "," );

	
	if( hasSSiteCategory && s_siteCategory != "" && hasSSiteName && s_siteName != "" )
	{
		sInstance.linkTrackVars += prefix + "prop22,eVar22,prop23,eVar23,prop24,eVar24"
		
		sInstance.prop22 = sInstance.eVar22 = s_siteName;
		sInstance.prop23 = sInstance.eVar23 = s_siteCategory;
		sInstance.prop24 = sInstance.eVar24 = s_siteCategory + ":Video";
	}

	prefix = sInstance.linkTrackVars == "" ? "" : ( ( sInstance.linkTrackVars.length > 0 && sInstance.linkTrackVars.substring( sInstance.linkTrackVars - 1 ) == "," ) ? "" : "," );
	
	if( hasSSiteFamily && s_siteFamily != ""  )
	{
	    sInstance.linkTrackVars += prefix + "prop25,eVar25";
	    
	    sInstance.prop25 = sInstance.eVar25 = s_siteFamily;
	}
	
	prefix = sInstance.linkTrackVars == "" ? "" : ( ( sInstance.linkTrackVars.length > 0 && sInstance.linkTrackVars.substring( sInstance.linkTrackVars - 1 ) == "," ) ? "" : "," );

	s.linkTrackVars		+= prefix + "prop5,prop11,eVar11,prop12,eVar12,prop13,eVar13,prop16,eVar16,prop17,eVar17,prop18,eVar18,prop20,eVar20,prop21,eVar21,hier1";
	
	sInstance.prop16	= sInstance.eVar16 = Metrics.GetVideoTitle( pVideo );
	sInstance.prop17	= sInstance.eVar17 = Metrics.GetVideoId ( pVideo );
	sInstance.prop20	= sInstance.eVar20 = Metrics.GetVideoPath( pVideo );
	sInstance.prop21	= sInstance.eVar21 = Metrics.GetVideoDuration( pVideo );
	
	sInstance.prop5		= sInstance.eVar5 = "Video";
	sInstance.prop18	= sInstance.eVar18 ="One Clip Player";
}

Metrics.GetTrackingInstance = function( pVideo )
{
	var hasSAccount		= typeof( s_account ) != undefined && typeof( s_account ) != "undefined" && typeof( s_account ) != null;
	
	var accountName		= hasSAccount ? s_account : Metrics.GetInstance().AccountId;
	var s = null;
	
	s = s_gi( accountName );
	s.linkTrackVars = "";
	s.linkTrackEvents = "None";
	
	s.prop1 = s.eVar1 = "";
	s.prop2 = s.eVar2 = "";
	s.prop5 = s.eVar5 = "";
	s.prop6 = s.eVar6 = "";
	s.prop7 = s.eVar7 = "";
	s.prop8 = s.eVar8 = "";
	s.prop16 = s.eVar16 =  "";
	s.prop17 = s.eVar17 = "";
	s.prop20 = s.eVar20 = "";
	s.prop18 = s.eVar18 = "";
	s.prop20 = s.eVar20 = "";
	s.prop21 = s.eVar21 = "";
	
	s.hier1 = "";
	s.events= "";
	s.products= "";
	
	if( pVideo )
	{
		Metrics.ApplyKnownSections( s, pVideo );
	}
	
	return s;
}

Metrics.SendStartedClip = function( pVideo )
{
	var CurrentClip = pVideo; 
	
	if( ! CurrentClip )
	{
	    CurrentClip = Playlist.GetInstance().Current;
	}
	
	var s = Metrics.GetTrackingInstance( pVideo );
		
	s.linkTrackVars	  += ",products,events";
	s.linkTrackEvents = "event5,event7";
	
	s.events="event5,event7"; 
	s.products=";;;;event7=0";
	
	var label =  Metrics.TrimLabel( "[ClipId=" + Metrics.GetVideoId( pVideo ) + "] started"  );
	
	Metrics.TrackLink(s, true, "o", Metrics.VIDEO_LABEL );
}


Metrics.SendLeftClipBeforeEnd = function( pVideo, pSeconds )
{
	var CurrentClip = pVideo; 
	
	if( ! CurrentClip )
	{
	    CurrentClip = Playlist.GetInstance().Current;
	}

	var s = Metrics.GetTrackingInstance( pVideo );
	
	s.linkTrackVars	  += ",events";
	s.linkTrackEvents ="event17";
		
	s.events="event17";

	var label = Metrics.TrimLabel( "[ClipId=" + Metrics.GetVideoId( pVideo ) + "] ended un-naturally" );
	Metrics.TrackLink( s, true, "o", Metrics.VIDEO_LABEL );
}

Metrics.OnIntervalClipTime = function( pVideo, pSeconds )
{
	var timeDelta = pSeconds - Metrics.GetInstance().LastTrackedLocation;
		
	Metrics.GetInstance().LastTrackedLocation = pSeconds;
	
	Metrics.SendClipTime( pVideo, timeDelta );
}
Metrics.OnKeyPointClipTime = function( pVideo, pSeconds, pEvent )
{
	 var timeDelta = pSeconds - Metrics.GetInstance().LastTrackedLocation;	
	 
	 if( Metrics.ClipTimeIsInRange( timeDelta ) )
	 {
	    Metrics.GetInstance().LastTrackedLocation = pSeconds;
    	
	    var s = Metrics.GetTrackingInstance( pVideo );

	    s.linkTrackVars +=",events,products";
	    s.linkTrackEvents= "event7," + pEvent;
    	
	    s.events="event7," + pEvent;
	    s.products=";;;;event7=" + timeDelta;
    	
	    var label = Metrics.TrimLabel( "[ClipId=" + Metrics.GetVideoId( pVideo ) + "] reached " +  pSeconds + " seconds" );
	    Metrics.TrackLink( s, true, "o", Metrics.VIDEO_LABEL );
	 }
}
Metrics.SendClipTime = function( pVideo, pSeconds )
{
	if( Metrics.ClipTimeIsInRange( pSeconds ) )
	{
		var s= Metrics.GetTrackingInstance( pVideo );
		
		s.linkTrackVars +=",events,products";
		s.linkTrackEvents="event7";
		
		s.events="event7";
		s.products=";;;;event7=" + pSeconds;

		var elapsedTime = Metrics.GetInstance().LastTrackedLocation;
		var label = Metrics.TrimLabel( "[ClipId=" + Metrics.GetVideoId( pVideo ) + "] reached " +  elapsedTime + " seconds" );
		
		Metrics.TrackLink( s, true, "o", Metrics.VIDEO_LABEL );
	}
}

Metrics.TrackLink = function( sInstance, param1, param2, param3 )
{
	if( ! Metrics.CanTrack )
	{
		Metrics.CanTrack = ( typeof( s_gi ) == "function" ); //the h code is already on the page if s_gi is a function
	}
	
	if( Metrics.CanTrack )
	{
		sInstance.IsTrackLink = true;
		sInstance.tl( param1,param2,param3 );
		sInstance.IsTrackLink = false;
	}
}

// The user navigated to pLocation in the library interface
Metrics.NavigatedTo = function( pLocation )
{
	var s= Metrics.GetTrackingInstance();
	
	s.linkTrackEvents = "None";
	s.linkTrackVars = "None";
	
	s.prop5 = s.eVar5 = "AJAX Web Page";
	//try
	//{
		Metrics.TrackLink( s, true, "o", pLocation );
	//}
	//catch(e)
	//{}
}

// There was the error pError loading the video pVideo.
Metrics.ErrorPlayingClip = function( pVideo, pError )
{
    var s= Metrics.GetTrackingInstance();
    
    s.linkTrackEvents = "None";
	s.linkTrackVars = "None";
    
    s.prop5 = s.eVar5 = "AJAX Error Page";
    
    try
    {
        Metrics.TrackLink( s, true, "o", "Error_" + pError + "_" + Metrics.GetVideoPath( pVideo ) );
    }
    catch( err )
    {
        Metrics.TrackLink( s, this, "o", "Error_" + pError );
    }
    
    if( Metrics.GetInstance().trackingIntervalToken != null )
	{
		clearInterval( Metrics.GetInstance().trackingIntervalToken );
		Metrics.GetInstance().trackingIntervalToken = null;
	}
}



Metrics.InteractedWithElement = function( pElementName )
{
	var s= Metrics.GetTrackingInstance();
	
	s.linkTrackEvents = "None";
	s.linkTrackVars = "None";
	
	s.prop5 = s.eVar5 = "Web Page Element Interaction";
	
	 Metrics.TrackLink( s, this, "o", pElementName );
}

Metrics.ClipTimeIsInRange = function( pNumber )
{
    return ( ! isNaN( "" + pNumber ) ) && pNumber >= 0 && pNumber <= ( Metrics.GetInstance().TRACKING_INTERVAL * 2 );
}

Metrics.NonZero = function( pNumber )
{
    if( pNumber == -1 )
    {
        return 1;
    }
    else
    {
        return Math.abs( pNumber );
    }
}

//initialize

Metrics.CanTrack = ( typeof( s_gi ) == "function" ); //the h code is already on the page if s_gi is a function
var autoTrackDNE = typeof( _AUTO_TRACK ) == undefined || typeof( _AUTO_TRACK ) == "undefined";
var oldAutoTrack = false;

if( ( ! autoTrackDNE ) && ( ! Metrics.CanTrack ) )
{
	oldAutoTrack = _AUTO_TRACK;
}

var _AUTO_TRACK = oldAutoTrack;
	
if( !  Metrics.CanTrack )
{
	var handlerFunction	= function() { Metrics.CanTrack = true; };
	var head			= document.getElementsByTagName("body")[0];
	var newScript		= document.createElement("script");
	
	newScript.type		= "text/javascript";
	newScript.src		= "http://www.muchmusic.com/GlobalPageTracking.js";
	
	newScript.onload = handlerFunction;
	if( newScript.onload == handlerFunction )
	{
		// DO NOTHING
	}
	else if( newScript.addEventListener )
	{
		newScript.addEventListener( "load", handlerFunction, false );
	}
	else if( newScript.attachEvent ) 
	{
		newScript.attachEvent( "onload", handlerFunction );
	}

	var isIE = navigator && navigator.appName && navigator.appName.indexOf("Explorer") > -1;
	if( isIE )
	{
		var oldOnLoad = window.onload;
		
		var onloadFunction = function() { head.appendChild( newScript ); if( oldOnLoad ) { oldOnLoad(); } };
		
		window.onload = onloadFunction;
	}
	else
	{
		head.appendChild( newScript );
	}
}


/*
 * Video: an individual video that can be played
 */
function Video( pVideoInfo )
{
	this.Title = "";
	this.Description = "";
	this.Thumbnail = "";
	this.EpisodeThumbnail = "";
	this.Format = null;
	this.Rating = TVRating.ParentalGuidance;
	this.IsAd = false;  // Is this Video an Ad?
	this.Url = null;  // URL of the Video stream or file (for progressive downloading)
	this.BugUrl = "";  // URL of the video bug (image in the bottom-right corner)
	this.ClipId = null;  // The unique PIPE Clip Id of the video
	this.EpisodeId = null;  // The unique PIPE Episode Id of the video
	this.Duration = -1;  // The duration of the video
	this.Permalink = null;
	this.EpisodePermalink = null;
	this.IsCanadaOnly = false;
	
	this.Artist = "";
	
	this.MetaData = null;
	this.SiteMap = null;
	
	this.IgnoreSibling = false;
	
	this.SetInfo( pVideoInfo );
	
	this.OnStart = null;  // Function that is called when the Video is played
	this.OnEnd = null;  // Function that is called when the Video is stopped
	this.AfterRemoteLoad = null;  // Function that is called when the Video has finished loading remotely
	
	this.IsInErrorState = false;  // Is this Video object in an error state?
	
}

Video.prototype.SetInfo = function( pVideoInfo )
{
    if( pVideoInfo.Title )
    {
        this.Title = pVideoInfo.Title;
    }
    
    if ( pVideoInfo.Artist )
    {
        this.Artist = pVideoInfo.Artist;
    }
        
    if( pVideoInfo.Description )
    {
        this.Description = pVideoInfo.Description;
    }
    
    if( pVideoInfo.Url )
    {
        this.Url = pVideoInfo.Url;
    }
    else if( pVideoInfo.url )
    {
        this.Url = pVideoInfo.url;
    }
    
    if( pVideoInfo.Format )
    {
        this.Format = pVideoInfo.Format;
    }
    
    if( pVideoInfo.ClipId )
    {
        this.ClipId = pVideoInfo.ClipId;
    }
    
    if( pVideoInfo.EpisodeId )
    {
        this.EpisodeId = pVideoInfo.EpisodeId;
    }
    
    if( pVideoInfo.IsAd )
    {
        this.IsAd = pVideoInfo.IsAd;
    }
    
    if( pVideoInfo.Duration )
    {
        this.Duration = pVideoInfo.Duration;
    }
    
    if( pVideoInfo.Thumbnail )
    {
        this.Thumbnail = pVideoInfo.Thumbnail;
    }
    
    if( pVideoInfo.EpisodeThumbnail )
    {
        this.EpisodeThumbnail = pVideoInfo.EpisodeThumbnail;
    }
    
    if( pVideoInfo.Rating )
    {
        this.Rating = pVideoInfo.Rating;
    }
    
    if( pVideoInfo.BugUrl )
    {
        this.BugUrl = pVideoInfo.BugUrl;
    }
    
    if( pVideoInfo.IgnoreSibling )
    {
        this.IgnoreSibling = pVideoInfo.IgnoreSibling;
    }
    
    if( pVideoInfo.Permalink )
    {
        this.Permalink = pVideoInfo.Permalink;
    }
    else if( this.ClipId != null && FlashController.IsOneClipPlayer )
    {
		this.Permalink = Video.DeterminePermalink( this.ClipId );
    }
    
    if( pVideoInfo.EpisodePermalink )
    {
        this.EpisodePermalink = pVideoInfo.EpisodePermalink;
    }
    
    if( pVideoInfo.IsCanadaOnly )
    {
		this.IsCanadaOnly = pVideoInfo.IsCanadaOnly == 1;
    }
    
    if( pVideoInfo.SiteMap )
    {
		this.SiteMap = new Array();
		
		var maps = pVideoInfo.SiteMap.split( "||" );
		
		for( i = 0; i < maps.length; i++ )
		{
			var arr =  new Array( maps[i], maps[++i] );
			
			this.SiteMap.push( arr );
		}
    }
    
    if( pVideoInfo.MetaData )
    {
		this.MetaData = new Array();
		
		var meta = pVideoInfo.MetaData.split( "||" );
		
		for( i = 0; i < meta.length; i++ )
		{
			var innerMeta = meta[ i ].split( ": " );
			var arr =  new Array( innerMeta[0], innerMeta[1] );
			
			this.MetaData.push( arr );
		}
    }
}


Video.GetInstance = function( i )
{
	if( Video.__instance && Video.__instance[i] )
	{
		return Video.__instance[i];
	}
	else
	{
		throw "Could not find an instance of Video with index " + i;
	}
}

Video.SetInstance = function( pVideo )
{
	if( ! Video.__instance )
	{
		Video.__instance = new Array();
	}
	
	Video.__instance.push( pVideo );
	return Video.__instance.length - 1;
}

// Get information about the Video by calling pUrlToPassClipId appended with the ClipId
Video.prototype.GetRemoteUrl = function( pUrlToPassClipId )
{
    // Set this Video as the current Video being loaded remotely.
	Video.LoadingVideo = this;
	
	if( ! pUrlToPassClipId )
	{
	    if( 
	        this.Format == Format.WindowsMediaVideo 
	        || this.Format == Format.WindowsMediaVideoDRM 
	        || this.Format == Format.LiveStream
	    )
	    {
		    pUrlToPassClipId = "http://esi.ctv.ca/datafeed/urlgenjs.aspx?vid=";
		}
		else if( Format.FlashVideo )
		{
		    pUrlToPassClipId = "http://esi.ctv.ca/datafeed/flv/urlgenjs.aspx?vid=";
		}
	}
	
	var TimezoneOffset = ( new Date() ).getTimezoneOffset() / 60 * -1; // as a negative int, from UTC

    // Call the remote URL via a SCRIPT element in the header of the page.
	var VideoRemoteUrlScript = document.createElement("script");
	VideoRemoteUrlScript.src = pUrlToPassClipId + this.ClipId + "&timeZone=" + TimezoneOffset + "&random=" + Math.round( 10000000 * Math.random() );
	VideoRemoteUrlScript.type = "text/javascript";
	document.getElementsByTagName("head")[0].appendChild( VideoRemoteUrlScript );
	
	VideoIndex = Video.SetInstance( this );
	
	// Check after 4 seconds if the Video has loaded successfully.
	setTimeout( "Video.GetInstance(" + VideoIndex + ").CheckForLoadFailure()", 4000 );
}

// Called from a JS call from the remotely-loaded URL (via Video.prototype.GetRemoteUrl)
// pVideoLoadInfo: all the information about a Video clip in JSON format
Video.Load = function( pVideoLoadInfo )
{
	Log( "Loaded video " + pVideoLoadInfo.url );
	
	var _Video = Video.LoadingVideo;
	
	_Video.SetInfo( pVideoLoadInfo );
	
	// If we were not passed back a URL for the clip stream...
	if( ! _Video.Url )
	{
	    // If we don't have a URL of the video, we are really in trouble.  So throw an error and stop.
		throw "Error loading video " + _Video.ClipId + ": Could not find a URL to play";
		return;
	}
	
	// Check if we received an error from the server code while trying to grab the Clip information.
	// These errors can be things like "clip expired" and "geo-fenced".
	if( pVideoLoadInfo.err && pVideoLoadInfo.err != "" )
	{
		_Video.OnLoadFailure( pVideoLoadInfo.err );
	}
	else
	{
		if( _Video.AfterRemoteLoad )
		{
			_Video.AfterRemoteLoad( _Video );
		}
	}
	
}

Video.DeterminePermalink = function( clipId )
{
	return "http://watch.ctv.ca/news/Redirect/Default.aspx?ClipId=" + clipId;	
}

// There was an error loading the Video.
// pError: a message describing the error.
Video.prototype.OnLoadFailure = function( pError )
{
	this.IsInErrorState = true;
	
	if( pError.match( "blocked" ) != null )
	{
        if( Interface.DisplayPlayerControllerError )
        {
            Interface.DisplayPlayerControllerError( "Not available in your region", "Sorry, the video you are trying to watch is <a href='http://blog.ctvdigital.net/index.php/video-player/video-player-faq/#OutsideCanada' target='_blank'>not available in your region</a>." );
        }
        else
        {
            alert( "Canada only" );
        }
        Metrics.NavigatedTo( "Canada_Only" );
    }
    else if( pError.match( "expired" ) != null )
    {
        if( Interface.DisplayPlayerControllerError )
        {
            Interface.DisplayPlayerControllerError( "Clip expired", "The clip you are trying to watch is <a href='http://blog.ctvdigital.net/index.php/video-player/video-player-faq/#Expired' target='_blank'>no longer available</a>." );
        }
        else
        {
            alert( "Clip expired" );
        }
         Metrics.NavigatedTo( "Clip_Expired" );
    }
    else
    {
	    if( Interface.DisplayPlayerControllerError )
	    {
	        Interface.DisplayPlayerControllerError( "Sorry, there was an error", pError );
        }
        else
        {
            alert( "Sorry, there was an error" );
        }
	    //Metrics.NavigatedTo( "Error_Generic" );
	}
	
	Metrics.ErrorPlayingClip( this, pError );
}
	
// Check if the Video loaded remotely without failure (before this function is called).
Video.prototype.CheckForLoadFailure = function() 
{
	if( ! this.IsInErrorState )
	{
		var loaded = false;
		
		if( ! this.Url )
		{
			if( Playlist.GetInstance().Current.ClipId == this.ClipId && this.Url == null )
			{
				this.OnLoadFailure( "We are experiencing temporary difficulties downloading your lineup.  Please wait another few seconds and try again if you're still having problems.<br /><br />  Thanks for your patience." );
				return;
			}
		}
	}
}


/*
 * TV Rating: holds the possible tv ratings of video
 * "Won't somebody think about the children?!"
 */
function TVRating()
{
    this.DiscretionThreshold = TVRating.ParentalGuidance; // the maximum rating to display without advisory.
    
    this.DisplayedAdvisories = new Array();
    
    TVRating.__instance = this;
}
TVRating.GetInstance = function()
{
    if( TVRating.__instance )
    {
        return TVRating.__instance;    
    }
    else
    {
        return new TVRating();
    }
}
TVRating.prototype.MustAdvise = function( pRating )
{
    if( TVRating.Weight( pRating ) > TVRating.Weight( this.DiscretionThreshold ) )
    {
        for( var i = 0; i < this.DisplayedAdvisories.length; i++ )
        {
            if( this.DisplayedAdvisories[i] == pRating )
            {
                return false;
            }
        }
        this.DisplayedAdvisories.push( pRating );
        return true;
    }
    else
    {
        return false;
    }
}

TVRating.Weight = function( pRating ) 
{
    switch( pRating )
    {
        case TVRating.Children:
            return 0;
            break;
        case TVRating.ChildrenOver8:
            return 1;
            break;
        case TVRating.General:
            return 2;
            break;
        case TVRating.ParentalGuidance:
            return 3;
            break;
        case TVRating.Over14:
            return 4;
            break;
        case TVRating.Adults:
            return 5;
            break;
        default:
            return -1;
            break;
    }
}

TVRating.Children = "C";
TVRating.ChildrenOver8 = "C8+";
TVRating.General = "G";
TVRating.ParentalGuidance = "PG";
TVRating.Over14 = "14+";
TVRating.Adults = "18+";


/*
 * Playlist: handles the ordering and managing of the videos that will play in sequence
 */
function Playlist( pPrerollFrequency )
{
	this.History = new Array();  // Videos that you have already watched (does not include ads)
	this.Upcoming = new Array();  // Videos that you have added to your playlist
	
	
	
	this.SiblingVideos = new Array();  // Other clips in the same episode as your Current clip
	this.Current = null; // The Video you are currently watching
	
	this.ClipIdOnAddresBarAtLoadTime = Player.ParseClipIdFromAddress();
	
	// Set the frequency that preroll ads will appear
	// this.PrerollFrequency set to 0 will display no prerolls.
	if( pPrerollFrequency )
	{
	    // TEMPORARY: Watch for the old preroll frequency and make sure it's no less than 30 seconds
	    if( pPrerollFrequency > 0 && pPrerollFrequency < 10 )
	    {
	        this.PrerollFrequency = 300;
	    }
	    else
	    {
		    this.PrerollFrequency = pPrerollFrequency;
		}
	}
	else
	{
		this.PrerollFrequency = 0;
	}
	
	
	this.FeaturedVideosIndex = 0;  // The index of where you are in the static FeaturedVideos array
	
	Playlist.__instance = this;
}
Playlist.GetInstance = function( )
{
	if( ! Playlist.__instance )
	{
		throw "Trying to get an instance of the Playlist before it has been initialized";
	}
	
	return Playlist.__instance;
}

// A static list of the Featured videos in the current player
Playlist.FeaturedVideos = new Array();


        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/ctv-news-update/', Permalink:'http://watch.ctv.ca/news/clip237755#clip237755', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_9_22/470_newschannel_090922.jpg', Rating:'', Description:'Get the latest Canadian and international headlines from CTV News Channel.', Title:'Watch the latest CTV News update', Format:'FLV', ClipId:'237755', BugUrl: '' ,SiteMap:'', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/torture-scandal/', Permalink:'http://watch.ctv.ca/news/latest/torture-scandal/#clip237794', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_21/470_cp_colvin_091121.jpg', Rating:'', Description:'The executive director of the Federal Accountability Initiative for Reform says the way whistleblowers are treated is \'appalling\' and Richard Colvin has already been subject to reprisals.', Title:'Latest : Torture scandal : CTV News Channel: David Hutton, FAIR', Format:'FLV', ClipId:'237794', BugUrl: '' ,SiteMap:'Torture scandal||ShowId=1281&EpisodeId=39279||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/torture-scandal/', Permalink:'http://watch.ctv.ca/news/latest/torture-scandal/#clip237769', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_21/470_cp_colvin_091121.jpg', Rating:'', Description:'After suggesting Richard Colvin, the diplomat whose allegations about Afghan detainee transfers sparked a firestorm, is a Taliban dupe, the defence minister eased up on his attacks.', Title:'Latest : Torture scandal : CTV National News: Todd Battis on the firestorm', Format:'FLV', ClipId:'237769', BugUrl: '' ,SiteMap:'Torture scandal||ShowId=1281&EpisodeId=39279||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/one-on-one/', Permalink:'http://watch.ctv.ca/news/latest/one-on-one/#clip237643', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_mccain_091120.jpg', Rating:'', Description:'Steve Murphy sits down with U.S. Senator John McCain to discuss Canada\'s presence in Afghanistan, U.S. Canada relations, and his bid for the presidency.', Title:'Latest : One-on-one : CTV Atlantic: U.S. Senator John McCain, part one', Format:'FLV', ClipId:'237643', BugUrl: '' ,SiteMap:'One-on-one||ShowId=1281&EpisodeId=39260||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/one-on-one/', Permalink:'http://watch.ctv.ca/news/latest/one-on-one/#clip237644', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_mccain_091120.jpg', Rating:'', Description:'Steve Murphy sits down with U.S. Senator John McCain to discuss Canada\'s presence in Afghanistan, U.S. Canada relations, and his bid for the presidency.', Title:'Latest : One-on-one : CTV Atlantic: U.S. Senator John McCain, part two', Format:'FLV', ClipId:'237644', BugUrl: '' ,SiteMap:'One-on-one||ShowId=1281&EpisodeId=39260||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/uk-floods/', Permalink:'http://watch.ctv.ca/news/latest/uk-floods/#clip237773', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_ap_flood_091120.jpg', Rating:'', Description:'Flooding caused by record rainfall in northern England proved deadly and forced hundreds from their home.', Title:'Latest : U.K. floods : CTV National News: Tom Kennedy from London', Format:'FLV', ClipId:'237773', BugUrl: '' ,SiteMap:'U.K. floods||ShowId=1281&EpisodeId=39268||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/ctv-national-news/nov-20/', Permalink:'http://watch.ctv.ca/news/ctv-national-news/nov-20/#clip237765', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_7/470_lisa_laflamme_090807.jpg', Rating:'', Description:'A medical breakthrough brings hope to millions of MS patients, two rivers breach their banks in B.C, and cause major flooding, a security summit is overshadowed by the issue of detainee abuse, and Oprah makes a big announcement.', Title:'CTV National News : Nov. 20 : Part one', Format:'FLV', ClipId:'237765', BugUrl: '' ,SiteMap:'Nov. 20||ShowId=1209&EpisodeId=39267||CTV National News||ShowId=1209', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/ctv-national-news/nov-20/', Permalink:'http://watch.ctv.ca/news/ctv-national-news/nov-20/#clip237766', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_7/470_lisa_laflamme_090807.jpg', Rating:'', Description:'With no evidence of a firm recovery, there will be no new spending, announces the finance minister. As for the ballooning deficit, he says the government will take care of that when the time is right. ', Title:'CTV National News : Nov. 20 : Part two', Format:'FLV', ClipId:'237766', BugUrl: '' ,SiteMap:'Nov. 20||ShowId=1209&EpisodeId=39267||CTV National News||ShowId=1209', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/ctv-national-news/nov-20/', Permalink:'http://watch.ctv.ca/news/ctv-national-news/nov-20/#clip237772', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_7/470_lisa_laflamme_090807.jpg', Rating:'', Description:'Massive flooding, following a record amount of rain in England, forces a major rescue operation, causes deaths and drives hundreds from their homes.', Title:'CTV National News : Nov. 20 : Part three', Format:'FLV', ClipId:'237772', BugUrl: '' ,SiteMap:'Nov. 20||ShowId=1209&EpisodeId=39267||CTV National News||ShowId=1209', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/ctv-national-news/nov-20/', Permalink:'http://watch.ctv.ca/news/ctv-national-news/nov-20/#clip237774', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_7/470_lisa_laflamme_090807.jpg', Rating:'', Description:'Ask Us: After a 6.6-magnitude quake hit B.C.\'s northwest coast, Anna Daly from Calgary wants to know \'what research is done to monitor tremors in Canada, and how many occur each year?\'', Title:'CTV National News : Nov. 20 : Part four', Format:'FLV', ClipId:'237774', BugUrl: '' ,SiteMap:'Nov. 20||ShowId=1209&EpisodeId=39267||CTV National News||ShowId=1209', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/your-money/', Permalink:'http://watch.ctv.ca/news/latest/your-money/#clip237606', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_9_14/470_cp_canadian_money_090914.jpg', Rating:'', Description:'BNN reporter Tanya Gallus has all your interesting business headlines for Friday, Nov. 20, 2009.', Title:'Latest : Your Money : CTV News Channel: BNN\'s Tanya Gallus with \'Your Money\'', Format:'FLV', ClipId:'237606', BugUrl: '' ,SiteMap:'Your Money||ShowId=1281&EpisodeId=39231||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/w5-preview/', Permalink:'http://watch.ctv.ca/news/top-picks/w5-preview/#clip237767', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_w5_091023.jpg', Rating:'', Description:'A scientific breakthrough is challenging everything the medical community has known about Multiple Sclerosis, and a new treatment pioneered in Italy could change the lives of millions.', Title:'Top Picks : W5 Preview : CTV National News: Avis Favaro with an exclusive', Format:'FLV', ClipId:'237767', BugUrl: '' ,SiteMap:'W5 Preview||ShowId=1215&EpisodeId=39212||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/w5-preview/', Permalink:'http://watch.ctv.ca/news/top-picks/w5-preview/#clip237382', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_w5_091023.jpg', Rating:'', Description:'It\'s being called a breakthrough in the fight against Multiple Sclerosis. Now a new study at the University of Buffalo is looking into a possible cure for the disease. CTV\'s medical correspondent Avis Favaro weighs in on the study.', Title:'Top Picks : W5 Preview : Canada AM: Avis Favaro on the study', Format:'FLV', ClipId:'237382', BugUrl: '' ,SiteMap:'W5 Preview||ShowId=1215&EpisodeId=39212||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/bc-flooding/', Permalink:'http://watch.ctv.ca/news/latest/bc-flooding/#clip237768', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_bc_flood1_091120.jpg', Rating:'', Description:'Days of heavy rain caused two rivers to burst their banks on parts of Vancouver Island, catching residents by surprise and prompting a state of emergency.', Title:'Latest : B.C. flooding : CTV National News: Rob Brown covers the flood', Format:'FLV', ClipId:'237768', BugUrl: '' ,SiteMap:'B.C. flooding||ShowId=1281&EpisodeId=39266||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/bc-flooding/', Permalink:'http://watch.ctv.ca/news/latest/bc-flooding/#clip237736', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_bc_flood1_091120.jpg', Rating:'', Description:'Numerous neighbourhoods in Duncan, B.C. were hit by widespread flooding on Friday.', Title:'Latest : B.C. flooding : CTV British Columbia: Shannon Paterson reports', Format:'FLV', ClipId:'237736', BugUrl: '' ,SiteMap:'B.C. flooding||ShowId=1281&EpisodeId=39266||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/bc-flooding/', Permalink:'http://watch.ctv.ca/news/latest/bc-flooding/#clip237738', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_bc_flood1_091120.jpg', Rating:'', Description:'Uncertainty looms for hundreds of people evacuated from their homes due to flooding.', Title:'Latest : B.C. flooding : CTV British Columbia: Stephen Smart on flood aid', Format:'FLV', ClipId:'237738', BugUrl: '' ,SiteMap:'B.C. flooding||ShowId=1281&EpisodeId=39266||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/bc-flooding/', Permalink:'http://watch.ctv.ca/news/latest/bc-flooding/#clip237739', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_bc_flood1_091120.jpg', Rating:'', Description:'A family returns to rescue anything they can from their flood-ravaged home.', Title:'Latest : B.C. flooding : CTV British Columbia: Jim Beatty on the victims', Format:'FLV', ClipId:'237739', BugUrl: '' ,SiteMap:'B.C. flooding||ShowId=1281&EpisodeId=39266||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/budget-2010/', Permalink:'http://watch.ctv.ca/news/latest/budget-2010/#clip237771', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_flaherty_091120.jpg', Rating:'', Description:'Finance Minister Jim Flaherty announced there will be no new spending in next year\'s budget beyond the stimulus cash already pledged, but gave no specifics on battling the deficit.', Title:'Latest : Budget 2010 : CTV National News: Robert Fife on the spending', Format:'FLV', ClipId:'237771', BugUrl: '' ,SiteMap:'Budget 2010||ShowId=1281&EpisodeId=39247||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/budget-2010/', Permalink:'http://watch.ctv.ca/news/latest/budget-2010/#clip237647', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_flaherty_091120.jpg', Rating:'', Description:'Finance Minister Jim Flaherty says there will be no new stimulus measures and no new taxes. Opposition finance critics John McCallum and Thomas Mulcair say spending and assistance is still needed.', Title:'Latest : Budget 2010 : Power Play: Finance panel on spending', Format:'FLV', ClipId:'237647', BugUrl: '' ,SiteMap:'Budget 2010||ShowId=1281&EpisodeId=39247||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/budget-2010/', Permalink:'http://watch.ctv.ca/news/latest/budget-2010/#clip237577', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_flaherty_091120.jpg', Rating:'', Description:'Speaking to the Canadian and Empire Clubs, the federal finance minister emphasizes that Canadians shouldn\'t expect emergency stimulus measures to become permanent policy. ', Title:'Latest : Budget 2010 : CTV News Channel: Jim Flaherty speaks in Toronto', Format:'FLV', ClipId:'237577', BugUrl: '' ,SiteMap:'Budget 2010||ShowId=1281&EpisodeId=39247||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/budget-2010/', Permalink:'http://watch.ctv.ca/news/latest/budget-2010/#clip237578', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_flaherty_091120.jpg', Rating:'', Description:'The Liberal finance critic says the Tories are wasting billions and labelled the government \'the biggest spenders since Confederation.\'', Title:'Latest : Budget 2010 : CTV News Channel: Finance critic John McCallum', Format:'FLV', ClipId:'237578', BugUrl: '' ,SiteMap:'Budget 2010||ShowId=1281&EpisodeId=39247||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/illicit-sites/', Permalink:'http://watch.ctv.ca/news/latest/illicit-sites/#clip237775', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_keyboard_091120.jpg', Rating:'', Description:'A new report on Canadian involvement in the hosting of child porn sites may not be a reflection of Canada\'s laws because of the fact that the servers for illicit sites move around the world regularly.', Title:'Latest : Illicit sites : CTV News Channel: Signy Arnason, Cybertip.ca', Format:'FLV', ClipId:'237775', BugUrl: '' ,SiteMap:'Illicit sites||ShowId=1281&EpisodeId=39269||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/illicit-sites/', Permalink:'http://watch.ctv.ca/news/latest/illicit-sites/#clip237684', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_keyboard_091120.jpg', Rating:'', Description:'A new study suggests Canada is second only to the U.S. when it comes to the number of servers hosting websites that sell child porn.', Title:'Latest : Illicit sites : CTV Winnipeg: Kelly Dehn on the report', Format:'FLV', ClipId:'237684', BugUrl: '' ,SiteMap:'Illicit sites||ShowId=1281&EpisodeId=39269||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/tuts-back/', Permalink:'http://watch.ctv.ca/news/top-picks/tuts-back/#clip237659', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_tut_091120.jpg', Rating:'', Description:'A gala was being held at the AGO Friday night to mark the coming return of the King Tut exhibit, last on display in Toronto in 1979. Janice Golding reports.', Title:'Top Picks : Tut\'s back : CTV Toronto: Janice Golding on the return of Tut', Format:'FLV', ClipId:'237659', BugUrl: '' ,SiteMap:'Tut\'s back||ShowId=1215&EpisodeId=39146||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/tuts-back/', Permalink:'http://watch.ctv.ca/news/top-picks/tuts-back/#clip236979', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_tut_091120.jpg', Rating:'', Description:'30 years after the wonders of King Tut made its Canadian debut at the Art Gallery of Ontario, an even bigger exhibition - King Tut: The Golden King and the Great Pharaohs - will make its sole Canadian appearance at the AGO.', Title:'Top Picks : Tut\'s back : Canada AM: Mark Lach, creative director, AGO', Format:'FLV', ClipId:'236979', BugUrl: '' ,SiteMap:'Tut\'s back||ShowId=1215&EpisodeId=39146||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/power-play/nov-20/', Permalink:'http://watch.ctv.ca/news/power-play/nov-20/#clip237632', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_power_play.jpg', Rating:'', Description:'The former director general of Consular Affairs alleges the government is \'absolutely\' trying to cover up it\'s knowledge of Afghan detainee abuse and is now involved in \'gutter politics.\'', Title:'Power Play : Nov. 20 : Gar Pardy on the allegations', Format:'FLV', ClipId:'237632', BugUrl: '' ,SiteMap:'Nov. 20||ShowId=1213&EpisodeId=39257||Power Play||ShowId=1213', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/power-play/nov-20/', Permalink:'http://watch.ctv.ca/news/power-play/nov-20/#clip237635', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_power_play.jpg', Rating:'', Description:'U.S. Sen. John McCain, who was a victim of prisoner abuse in Vietnam, weighed in on the allegations of detainee abuse, saying such things often propel insurgent recruitment.', Title:'Power Play : Nov. 20 : U.S. Sen. John McCain', Format:'FLV', ClipId:'237635', BugUrl: '' ,SiteMap:'Nov. 20||ShowId=1213&EpisodeId=39257||Power Play||ShowId=1213', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/power-play/nov-20/', Permalink:'http://watch.ctv.ca/news/power-play/nov-20/#clip237640', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_power_play.jpg', Rating:'', Description:'Conservative MP Laurie Hawn, Liberal MP Ujjal Dosnajh and NDP MP Paul Dewar debate the allegations of Afghan prisoner torture and it\'s implications on the government and Canadian Forces.', Title:'Power Play : Nov. 20 : MPs debate detainee issue', Format:'FLV', ClipId:'237640', BugUrl: '' ,SiteMap:'Nov. 20||ShowId=1213&EpisodeId=39257||Power Play||ShowId=1213', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/power-play/nov-20/', Permalink:'http://watch.ctv.ca/news/latest/budget-2010/#clip237647', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_power_play.jpg', Rating:'', Description:'Finance Minister Jim Flaherty says there will be no new stimulus measures and no new taxes. Opposition finance critics John McCallum and Thomas Mulcair say spending and assistance is still needed.', Title:'Latest : Budget 2010 : Power Play: Finance panel on spending', Format:'FLV', ClipId:'237647', BugUrl: '' ,SiteMap:'Budget 2010||ShowId=1281&EpisodeId=39247||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/new-species/', Permalink:'http://watch.ctv.ca/news/top-picks/new-species/#clip237387', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_new_species_091120.jpg', Rating:'', Description:'Five new species of crocodiles have been discovered in the dunes of the Sahara. The odd crocs are believed to have lived in prehistoric times and more species are expected to be unveiled in the near future according to a professor at McGill University.', Title:'Top Picks : New species : Canada AM: Hans Larsson, McGill professor', Format:'FLV', ClipId:'237387', BugUrl: '' ,SiteMap:'New species||ShowId=1215&EpisodeId=39214||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/defence-talks/', Permalink:'http://watch.ctv.ca/news/latest/defence-talks/#clip237469', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_cp_gates_mackay_091120.jpg', Rating:'', Description:'Defence Minister Peter Mackay and U.S. Secretary of Defence Robert Gates both say the federal and U.S. government\'s realize big challenges are ahead in Afghanistan and they are committed to securing the safety of all Afghan citizens and solid defence relations with the country.', Title:'Latest : Defence talks : CTV News Channel: Peter Mackay and Robert Gates', Format:'FLV', ClipId:'237469', BugUrl: '' ,SiteMap:'Defence talks||ShowId=1281&EpisodeId=39235||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/deadly-crash/', Permalink:'http://watch.ctv.ca/news/latest/deadly-crash/#clip237762', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_truck_091120.jpg', Rating:'', Description:'One person is dead following a crash between a Department of National Defence Navy bus and an SUV near Halifax on Friday.', Title:'Latest : Deadly crash : CTV Atlantic: Jacqueline Foster on the collision', Format:'FLV', ClipId:'237762', BugUrl: '' ,SiteMap:'Deadly crash||ShowId=1281&EpisodeId=39222||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/deadly-crash/', Permalink:'http://watch.ctv.ca/news/latest/deadly-crash/#clip237431', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_truck_091120.jpg', Rating:'', Description:'CTV\'s Atlantic Bureau Chief says an SUV has collided head-on with a bus belonging to the Canadian Navy in Nova Scotia. One person has died in the crash and three others were taken to hospital. Investigators are trying figure out what went wrong.', Title:'Latest : Deadly crash : CTV News Channel: Todd Battis on the crash', Format:'FLV', ClipId:'237431', BugUrl: '' ,SiteMap:'Deadly crash||ShowId=1281&EpisodeId=39222||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/colbert-and-canada/', Permalink:'http://watch.ctv.ca/news/top-picks/colbert-and-canada/#clip237496', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_colbert_091120.jpg', Rating:'', Description:'TV host says American speed skaters shuts out of ice time.', Title:'Top Picks : Colbert and Canada : CTV News Channel: Colbert claims \'Olympic bias\'', Format:'FLV', ClipId:'237496', BugUrl: '' ,SiteMap:'Colbert and Canada||ShowId=1215&EpisodeId=39234||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/colbert-and-canada/', Permalink:'http://watch.ctv.ca/news/top-picks/colbert-and-canada/#clip236937', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_colbert_091120.jpg', Rating:'', Description:'The city of Richmond is jumping into a war of words with comedian Stephen Colbert over complaints that American athletes aren\'t getting fair access to the Olympic oval.', Title:'Top Picks : Colbert and Canada : CTV British Columbia: Mike Killeen on Colbert war of words', Format:'FLV', ClipId:'236937', BugUrl: '' ,SiteMap:'Colbert and Canada||ShowId=1215&EpisodeId=39234||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/off-the-air/', Permalink:'http://watch.ctv.ca/news/top-picks/off-the-air/#clip237770', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_ap_oprah_091120.jpg', Rating:'', Description:'The woman who coined the phrase \'an ah-ha moment\' gave one of her own. In a tearful TV moment, Oprah Winfrey announced her show will come to an end after next season -- its 25th.', Title:'Top Picks : Off the air : CTV National News: Tom Walters on her career', Format:'FLV', ClipId:'237770', BugUrl: '' ,SiteMap:'Off the air||ShowId=1215&EpisodeId=39215||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/off-the-air/', Permalink:'http://watch.ctv.ca/news/top-picks/off-the-air/#clip237470', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_ap_oprah_091120.jpg', Rating:'', Description:'The queen of daytime television says she\'ll take her show off the air in 2011. Toronto fans say they\'re sad but insiders say Oprah has big plans in the works.', Title:'Top Picks : Off the air : CTV Toronto: Galit Solomon with reaction from fans', Format:'FLV', ClipId:'237470', BugUrl: '' ,SiteMap:'Off the air||ShowId=1215&EpisodeId=39215||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/off-the-air/', Permalink:'http://watch.ctv.ca/news/top-picks/off-the-air/#clip237519', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_ap_oprah_091120.jpg', Rating:'', Description:'etalk\'s Traci Melchor and Torontonians weigh in on Oprah\'s departure and what it will mean for the daytime talk landscape.', Title:'Top Picks : Off the air : TALKback Toronto: Will you miss Oprah?', Format:'FLV', ClipId:'237519', BugUrl: '' ,SiteMap:'Off the air||ShowId=1215&EpisodeId=39215||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/off-the-air/', Permalink:'http://watch.ctv.ca/news/top-picks/off-the-air/#clip237392', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_ap_oprah_091120.jpg', Rating:'', Description:'According to a Harpo staffer, talk show queen Oprah Winfrey will end her 25-season show in 2011; a representative discusses why Oprah is deciding to call it suits and what may be in her future.', Title:'Top Picks : Off the air : Canada AM: Greg David, TV Guide Canada', Format:'FLV', ClipId:'237392', BugUrl: '' ,SiteMap:'Off the air||ShowId=1215&EpisodeId=39215||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/off-the-air/', Permalink:'http://watch.ctv.ca/news/top-picks/off-the-air/#clip237342', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_ap_oprah_091120.jpg', Rating:'', Description:'Oprah Winfrey decision to end her daytime talk show after 25 years on the air will likely free her up to play a more behind-the-scenes role at her new network.', Title:'Top Picks : Off the air : CTV News Channel: Rob Salem, TV columnist', Format:'FLV', ClipId:'237342', BugUrl: '' ,SiteMap:'Off the air||ShowId=1215&EpisodeId=39215||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/precious-gold/', Permalink:'http://watch.ctv.ca/news/top-picks/precious-gold/#clip237394', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_9_15/470_precious_090915.jpg', Rating:'', Description:'The film \'Precious,\' is receiving rave reviews and generating endless amounts of Oscar-buzz. The director and young star discuss the powerful message of hope in the film and how Oprah became an executive producer on the project.', Title:'Top Picks : Precious gold : Canada AM: Lee Daniels and Gabourey Sidibe', Format:'FLV', ClipId:'237394', BugUrl: '' ,SiteMap:'Precious gold||ShowId=1215&EpisodeId=39216||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/unfair-lead/', Permalink:'http://watch.ctv.ca/news/top-picks/unfair-lead/#clip237386', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_ap_para_athelete_091120.jpg', Rating:'', Description:'What\'s ca ompetitive edge? A new study says a South African double-amputee sprinter\'s prosthetic legs give him a 10-second advantage in a 400-metre race. A director of sports science weighs in on whether paralympian\'s have an advantage over able-bodied athletes.', Title:'Top Picks : Unfair lead : Canada AM: Greg Wells, director of sport science, The Canadian Centre', Format:'FLV', ClipId:'237386', BugUrl: '' ,SiteMap:'Unfair lead||ShowId=1215&EpisodeId=39213||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/el-nino/', Permalink:'http://watch.ctv.ca/news/top-picks/el-nino/#clip237359', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_19/470_whistler_snow_091119.jpg', Rating:'', Description:'The city of Whistler, B.C. set a new record for snowfall in November on Thursday with more than 400 centimetres so far. But unseasonably warm temperatures in the rest of the country could be a prelude to El Nino.', Title:'Top Picks : El Nino : CTV National News: Jill Macyshon on the strange weather', Format:'FLV', ClipId:'237359', BugUrl: '' ,SiteMap:'El Nino||ShowId=1215&EpisodeId=39196||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/el-nino/', Permalink:'http://watch.ctv.ca/news/top-picks/el-nino/#clip237320', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_19/470_whistler_snow_091119.jpg', Rating:'', Description:'Whistler surpassed its record for snowfall in the month of November.', Title:'Top Picks : El Nino : CTV British Columbia: Sarah Galashan on record Whistler snow', Format:'FLV', ClipId:'237320', BugUrl: '' ,SiteMap:'El Nino||ShowId=1215&EpisodeId=39196||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/el-nino/', Permalink:'http://watch.ctv.ca/news/top-picks/el-nino/#clip237312', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_19/470_whistler_snow_091119.jpg', Rating:'', Description:'Usually by mid-November, the city has seen some snow. But due to recent mild temperatures, city crews are busy sweeping streets and filling potholes instead of plowing snow.', Title:'Top Picks : El Nino : CTV Edmonton: Mild weather has city crews sweeping instead of plowing', Format:'FLV', ClipId:'237312', BugUrl: '' ,SiteMap:'El Nino||ShowId=1215&EpisodeId=39196||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/50-cent/', Permalink:'http://watch.ctv.ca/news/top-picks/50-cent/#clip237399', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_20/470_50_cent_091120.jpg', Rating:'', Description:'Hip hop artist 50 Cent discusses his move from music to movies and what it was like to put on a different hat and sit in the director\'s chair.', Title:'Top Picks : 50 Cent : Canada AM: 50 Cent, rapper and actor', Format:'FLV', ClipId:'237399', BugUrl: '' ,SiteMap:'50 Cent||ShowId=1215&EpisodeId=39217||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/bad-batch/', Permalink:'http://watch.ctv.ca/news/latest/bad-batch/#clip237354', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_19/470_flushot_091119.jpg', Rating:'', Description:'More than 100,000 doses of the H1N1 vaccine were withdrawn on Thursday after a number of people who got the shot suffered a potentially deadly allergic reaction.', Title:'Latest : Bad batch : CTV National News: John Vennavally-Rao reports', Format:'FLV', ClipId:'237354', BugUrl: '' ,SiteMap:'Bad batch||ShowId=1281&EpisodeId=39190||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/bad-batch/', Permalink:'http://watch.ctv.ca/news/latest/bad-batch/#clip237282', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_19/470_flushot_091119.jpg', Rating:'', Description:'Manitoba\'s Chief Medical Officer of Health says health officials in the province have not yet concluded if there is a problem with a particular batch of the vaccine. Kettner stresses that flu vaccine deaths are a rare occurrence.', Title:'Latest : Bad batch : CTV News Channel: Dr. Joel Kettner, health officer', Format:'FLV', ClipId:'237282', BugUrl: '' ,SiteMap:'Bad batch||ShowId=1281&EpisodeId=39190||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/bad-batch/', Permalink:'http://watch.ctv.ca/news/latest/shots-for-all/#clip236895', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_19/470_flushot_091119.jpg', Rating:'', Description:'The family of a woman is left with questions after she died days after getting the H1N1 vaccine.', Title:'Latest : Shots for all : CTV Winnipeg: Stacey Ashley on a woman\'s death', Format:'FLV', ClipId:'236895', BugUrl: '' ,SiteMap:'Shots for all||ShowId=1281&EpisodeId=39100||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/bad-batch/', Permalink:'http://watch.ctv.ca/news/latest/bad-batch/#clip237291', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_11_19/470_flushot_091119.jpg', Rating:'', Description:'An expert on infectious diseases explains the nature of the adverse reactions some are having to a particular batch of the H1N1 vaccine.', Title:'Latest : Bad batch : CTV News Channel: Dr. Neil Rau on the concerns', Format:'FLV', ClipId:'237291', BugUrl: '' ,SiteMap:'Bad batch||ShowId=1281&EpisodeId=39190||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/caster-semenya/', Permalink:'http://watch.ctv.ca/news/latest/caster-semenya/#clip237224', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_20/470_ap_gender_090820.jpg', Rating:'', Description:'South African runner Caster Semenya will be allowed to keep her gold medal and the results of her gender test will remain confidential.', Title:'Latest : Caster Semenya : CTV News Channel: Caster Semenya to keep gold medal', Format:'FLV', ClipId:'237224', BugUrl: '' ,SiteMap:'Caster Semenya||ShowId=1281&EpisodeId=39182||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
     


// Start working your way through the playlist, starting with the clip id on the address bar
// if you have one.
Playlist.prototype.Start = function( )
{
	var ClipIdOnAddressBar =  this.ClipIdOnAddresBarAtLoadTime;

	if( ClipIdOnAddressBar )
	{
	    for( var i = 0; i < this.Upcoming.length; i++ )
	    {
	        if( this.Upcoming[i].ClipId == ClipIdOnAddressBar )
	        {
	            this.Next();
	            return;
	        }
	        else
	        {
	            this.History.push( this.Upcoming.shift() );
	            i--;
	        }
	    }
	    // else
		this.GetEpisode( null, ClipIdOnAddressBar, "Playlist.GetInstance().AddEpisodeClips" );
		//this.Next();
	}
	else
	{
		this.Next();
	}	
}

Playlist.prototype.AddEpisodeClips = function( AllClips )
{
    var ClipIdOnAddressBar = this.ClipIdOnAddresBarAtLoadTime;

    var FoundClip = false;
        
    this.SiblingVideos.length = 0;

    for( var i = 0; i < AllClips.length; i++ )
    {
        if( FoundClip )
        {
            this.SiblingVideos.push( AllClips[i] ); 
        }
        else if( AllClips[i].ClipId == ClipIdOnAddressBar )
        {
            if( this.Current && ! this.Current.IsAd )
            {
				this.Play( AllClips[i] );
			}
			else
			{
				this.AddClip( AllClips[i] );

				Interface.SetUpNext( this.FindNext() );
				Interface.SetNowPlaying( this.FindNext() );
			}
			
            FoundClip = true;
        }
    }
    
    if( FoundClip )
    {
        this.SiblingVideos.push( AllClips[ AllClips.length - 1 ] ); 
    }
    
    this.Next();    
}

Playlist.prototype.AddEpisode = function( pEpisode )
{
    Playlist.LoadingEpisodeId = null;
    
    if( pEpisode.length )
    {
        this.AddClip( pEpisode );
    }
    else
    {
        this.GetEpisode( pEpisode, null, "Playlist.GetInstance().AddEpisode", true );
    }

}

Playlist.prototype.PlayEpisode = function( pEpisode )
{
    var isArray = pEpisode.length && typeof( pEpisode ) == "object";
        
    if( isArray )
    {        
        var shouldPlay = Playlist.PlayEpisodeId == Playlist.LoadingEpisodeId;
        Playlist.LoadingEpisodeId = null;
        
        if( shouldPlay )
        {
			Playlist.PlayEpisodeId = null;
			this.Play( pEpisode );
		}
    }
    else
    {
        Playlist.PlayEpisodeId = pEpisode;
        
        var timeout;
        timeout = setTimeout( function() { if( Playlist.PlayEpisodeId  ) Interface.ShowEpisodeIsLoadingMessage() }, 50 );
        
        this.GetEpisode( pEpisode, null, "Playlist.GetInstance().PlayEpisode" );
    }
}

Playlist.prototype.AddEpisodeClipsAfter = function( pClipId, pEpisodeId )
{
    var isArray = ( typeof( pClipId ) == "object" );
    
    if( ( ! pClipId ) || pClipId <= 0 )
    {
		return;
    }
    
    if( isArray )
    {
        var FoundClip = false;
        
        this.SiblingVideos.length = 0;
    
        for( var i = 0; i < pClipId.length; i++ )
        {
            if( FoundClip )
            {
                this.SiblingVideos.push( pClipId[i] ); 
            }
            else if( pClipId[i].ClipId == Playlist.LoadingEpisodeViaClipId )
            {
                FoundClip = true;
            }
        }
        
        Playlist.LoadingEpisodeViaClipId = null;
        Playlist.LoadingLongEpisodeViaClipId = null;
        
	    Interface.SetUpNext( this.FindNext() );

    }
    else
    {
        Playlist.LoadingEpisodeViaClipId = null;
        Playlist.LoadingLongEpisodeViaClipId = null;
         
        if( pEpisodeId && pEpisodeId < -1 )
        {
			pEpisodeId = null 
		}

		this.GetEpisode( pEpisodeId, pClipId, "Playlist.GetInstance().AddEpisodeClipsAfter" );
    }   
}

Playlist.prototype.LookUpMoreClips = function( pEpisodeId, pClipId, pOffset )
{
	//Playlist.LoadingLongEpisodeViaClipId = pClipId;
	//this.GetEpisode( pEpisodeId, pClipId, "Playlist.GetInstance().AddAdditionalEpisodeClipsAfter", true, null, pOffset );
}

Playlist.prototype.AddAdditionalEpisodeClipsAfter = function( pVideoArr )
{
	//drop stale requests
	if( Playlist.LoadingLongEpisodeViaClipId != Playlist.LoadingEpisodeViaClipId )
	{
		return;
	}

	var FoundClip =  false;
	for( var i = 0; i < pVideoArr.length; i++ )
    {
        if( FoundClip )
        {
            if( pVideoArr[i].ClipId != Playlist.LoadingEpisodeViaClipId )
            {
				this.SiblingVideos.push( pVideoArr[i] ); 
			}
        }
        else if( pVideoArr[i].ClipId == Playlist.LoadingEpisodeViaClipId )
        {
            FoundClip = true;
        }
    }
    
	Playlist.LoadingEpisodeViaClipId = null;
	
	Interface.SetUpNext( this.FindNext() );
}

Playlist.PlayClipFromId = function( pClipId )
{
	Playlist.prototype.GetEpisode( null, pClipId, "Playlist.GetInstance().Play", false );
}

Playlist.CanDetermineEpisodeInfo = function()
{
	return ! FlashController.IsOneClipPlayer;
}

Playlist.prototype.GetEpisode = function( pEpisodeId, pClipId, pCallbackFunctionName, dontPlay, additionalParams, firstResult )
{
    if( ! Playlist.CanDetermineEpisodeInfo() )
    {
		//can't AJAX across domains, we just can't know the sibling clips...maybe we could use JSON?
		return;
    }
    
    dontPlay = dontPlay == true;
    
    if( ! pEpisodeId )
    {
        pEpisodeId = "";
    }
    else
    {
        Playlist.LoadingEpisodeId = pEpisodeId;
    }
    
    if( ! pClipId )
    {
        pClipID = "";
    }
    else
    {
        Playlist.LoadingEpisodeViaClipId = pClipId;
    }

	// Call the remote URL via a SCRIPT element in the header of the page.
	var EpisodeRemoteUrlScript = document.createElement("script");
	
	var scriptUrl = "/news/AJAX/ClipLookup.aspx?callfunction=" + escape( pCallbackFunctionName ) + "&episodeid=" + pEpisodeId + "&clipid=" + pClipId + "&firstResult=" + firstResult + "&additionalParams=" + additionalParams;
	
	if( pCallbackFunctionName == "Playlist.GetInstance().Play" ) //just want to play one clip
	{
		scriptUrl += "&justPlayClip=true";
	}
	else if( pCallbackFunctionName == "Playlist.GetInstance().AddAdditionalEpisodeClipsAfter" )  
	{
		scriptUrl += "&maxResults=50";
	}
	else if( pCallbackFunctionName == "Playlist.GetInstance().AddEpisodeClipsAfter" )  
	{
		scriptUrl += "&maxResults=15";
	}
	
	EpisodeRemoteUrlScript.src = scriptUrl;
	EpisodeRemoteUrlScript.type = "text/javascript";
		
	if( ! dontPlay )
	{	
		if( this.Current && this.Current.IsAd )
		{
			var CurrentOnEnd = this.Current.OnEnd;
			this.Current.OnEnd = null;
		    	    
			if( ! CurrentOnEnd )
			{
				CurrentOnEnd = function() {}
			}
		    
			this.Current.OnEnd = function() { CurrentOnEnd(); setTimeout( function() { Playlist.CheckForLoadFailure(pEpisodeId); }, 3000 ); }
		    
		}
		else
		{
			setTimeout( "Playlist.CheckForLoadFailure(" + pEpisodeId + ")", 12000 );
			
			var _Controller = Player.GetInstance().Controller;
		
			if( _Controller && _Controller.Loading )
			{
				_Controller.Loading();
			}
		}
		
		if( Interface.Play_Clicked )
		{
			Interface.Play_Clicked();
		}
	}
	
	document.getElementsByTagName("head")[0].appendChild( EpisodeRemoteUrlScript );
}

Playlist.CheckForLoadFailure = function( pEpisodeId ) 
{
    /* Neil changed this Jan 28 @ 3:00PM -- keep an eye that it's not broken */
    
    if( Playlist.PlayEpisodeId && Playlist.PlayEpisodeId == pEpisodeId )
	{
		Interface.DisplayPlayerControllerError( "Please Wait", "It's taking a little while to load your video. It'll be ready to go soon...", "", "" );
	}
	else if( Playlist.LoadingEpisodeViaClipId && Playlist.LoadingEpisodeViaClipId == pEpisodeId )
	{
		Log( "Could not load any sibling clips for Clip Id " + Playlist.LoadingEpisodeViaClipId );
		Playlist.LoadingEpisodeViaClipId = null;
	}
}



// Add a Video or an array of videos to your Playlist
Playlist.prototype.AddClip = function( pVideo, dontSetUpNext )
{
    dontSetUpNext = dontSetUpNext == true;
    this.SiblingVideos.length = 0;

    if( pVideo.length )
    {
        for( var i = 0; i < pVideo.length; i++ )
        {
            this.Upcoming.push( pVideo[i] );    
        }
    }
    else
    {
        this.Upcoming.push( pVideo );
    }	
	
	// If you are already watching a Video...
	if( this.Current )
	{
		// If you are already watching an Ad...
		if( this.Current.IsAd )
		{
			// Display the next videos that will play after the Ad
			Interface.SetNowPlaying( this.FindNext() );
			if( ! dontSetUpNext )
			{
				Interface.SetUpNext( this.FindNext() );
			}
		}
		else
		{
			// Display the next videos that will play
			Interface.SetNowPlaying( this.Current );
			if( ! dontSetUpNext )
			{
				Interface.SetUpNext( this.FindNext() );
			}
		}
	}
	else
	{
		// Display what will be playing next (when the Playlist is started)
		Interface.SetNowPlaying( this.FindNext() );
		if( ! dontSetUpNext )
		{
			Interface.SetUpNext( this.FindNext( 1 ) );
		}
	}
	
	if( Interface.UpdatePlaylist ) { Interface.UpdatePlaylist( this ); }
}

// Play the Video, or array of videos, immediately, disregarding whatever might already be loaded into your
// Upcoming list of videos.
Playlist.prototype.Play = function( pVideo, wasCalledFromUI, clipIsPartOfEpisode )
{
	wasCalledFromUI = wasCalledFromUI == true;
	
	//dont set up next is the clip is part of an episode, we need to look up the "sibling" clips first
	var dontSetUpNext = clipIsPartOfEpisode == true; 
	
	Playlist.PlayEpisodeId = null; //NT: trying to avoid the false loading error bug	

    this.SiblingVideos.length = 0;

    // If you are already watching a Video...
	if( this.Current )
	{
		var WasPlayingAd = this.Current.IsAd;

		// If you were NOT watching an Ad
		if( ! WasPlayingAd )
		{
		    // Stop the Video you are watching
		    Player.EndClip();
		
		    // Move what you were watching to your History
			this.History.push( this.Current );
			this.Current = null;
		}

	    // Take all the Upcoming videos and move them to your History
		while( this.Upcoming.length > 0 )
		{
			this.History.push( this.Upcoming.shift() );
		}

		// Add pVideo to your Playlist
		this.AddClip( pVideo, dontSetUpNext );

		// If you were not playing an Ad, go on to the next Video immediately
		if( ! WasPlayingAd )
		{
			this.Next( null, null, dontSetUpNext );		
		}
	}
	else
	{
	    // Add pVideo to your Playlist
		this.AddClip( pVideo, dontSetUpNext );
		
		// Go on to the next Video immediately
		this.Next( null, null, dontSetUpNext );
	}
	
	if( wasCalledFromUI )
	{
		Interface.Play_Clicked();
		return false;
	}
}

Playlist.prototype.ClearHistory = function()
{
    this.History = new Array();
    
    if( Interface.UpdatePlaylist ) { Interface.UpdatePlaylist( this ); }
}

Playlist.prototype.ClearUpcoming = function()
{
    this.Upcoming = new Array();
    
    if( Interface.UpdatePlaylist ) { Interface.UpdatePlaylist( this ); }
}


Playlist.prototype.MovePlayhead = function( Offset )
{
    if( Offset == null || Offset == undefined )
    {
	    Offset = 1;
    }
    
    var CurrentIsAd = this.Current.IsAd;
    
    // Moving the playhead back (Offset is negative)
    if( Offset < 0 && ( Offset * -1 ) <= this.History.length )
    {
        var IndexOfOldestVideo = this.History.length + Offset;
        
        if( ! CurrentIsAd )
        {
            Player.EndClip();
            this.Upcoming = ( new Array( this.Current ) ).concat( this.Upcoming );
            this.Current = null;
        }
        
        this.Upcoming = this.History.slice( IndexOfOldestVideo ).concat( this.Upcoming );
        this.History = this.History.slice( 0, IndexOfOldestVideo );
        
        if( ! CurrentIsAd )
        {
            this.Next();
        }
        else
        {
            Interface.SetNowPlaying( this.FindNext() );
	        Interface.SetUpNext( this.FindNext() );
        }
    }
    // Moving the playhead forward (Offset is positive)
    else if( Offset > 0 )
    {
        if( ! CurrentIsAd )
        {
            Player.EndClip();
            this.MovePlaylistForward( Offset - 1 );
            this.Next();
        }
        else
        {
            this.MovePlaylistForward( Offset );

            Interface.SetNowPlaying( this.FindNext() );
	        Interface.SetUpNext( this.FindNext() );
        }        
    }
    
        	
	if( Interface.UpdatePlaylist ) { Interface.UpdatePlaylist( this ); }
}

Playlist.prototype.MovePlaylistForward = function( Offset )
{
    if( Offset == null || Offset == undefined )
    {
	    Offset = 1;
    }

	for( var i = 0; i < Offset; i++ )
	{
	
	    if( this.Upcoming.length > 0 )
	    {
		    this.History.push( this.Upcoming.shift() );
	    }
	    else if( this.SiblingVideos.length > 0 )
	    {
		    this.History.push( this.SiblingVideos.shift() );
	    }
	    else if( Playlist.FeaturedVideos.length > 0 )
	    {
		    if( this.FeaturedVideosIndex < Playlist.FeaturedVideos.length - 1 )
		    {
		        this.FeaturedVideosIndex++;			    
		    }
		    else
		    {
			    this.FeaturedVideosIndex = 0;
		    }
	    }
	}
}

// Go on to the next Video in your Playlist.
// SkipAd (boolean): If true, move on to the next video without watching a preroll ad.
Playlist.prototype.Next = function( SkipAd, AllowWait, DontSetUpNext )
{
    DontSetUpNext	= DontSetUpNext == true;
    SkipAd			= SkipAd == true;
    
    if( Interface.ClearAlertMessages ) { Interface.ClearAlertMessages(); }

    var shouldWaitForEpisodeToLoad =  Playlist.PlayEpisodeId != null && ! isNaN( Playlist.PlayEpisodeId ) && Playlist.PlayEpisodeId  > -1;
    if( shouldWaitForEpisodeToLoad )
    {
        Log("Next() was skipped, waiting for episode to load..");
        return;
    }
	
	if( AllowWait == null )
	{
	    AllowWait = true;
	}
	
	var _Player = Player.GetInstance();
	var JustPlayedAd = false;

	// If you are currently watching a Video
	if( this.Current != null )
	{	
	    // If the video you are watching is not an Ad, move it to your history
		if( ! this.Current.IsAd )
		{
		    Player.EndClip();
			this.History.push( this.Current );
		}
		else
		{
		    // You were just watching an Ad
			JustPlayedAd = true;
		}
		this.Current = null;
	}
	
	// If it is time to play an Ad...
	var playAd = ! SkipAd && ! JustPlayedAd && this.PrerollFrequency > 0
	    && _Player.TimeWatchedSinceAd() >= this.PrerollFrequency
	    && ( ! Playlist.HasNoAdCookie() );
	
	var isFirstPlay = _Player.TimeWatchedSinceAd() >= 999999;
	if( ! playAd && isFirstPlay )
	{
		if( Interface.SetBigBoxAd ) 
		{ 
			Interface.SetBigBoxAd(); 
		}
	}
	
	if( playAd )
	{
		var AdFormat = Format.FlashVideo;
		if( _Player.Controller )
		{
		    // Get the Video format that the current Player Controller is capable of playing
			AdFormat = _Player.Controller.Format;
		}

		// Get a preroll Ad in the same Video format as the video you are watching.
		Ad.GetPreroll( 
			AdFormat, 
			// Play the Ad Video when it's done loading 
			function( pVideo ) 
			{   

				Playlist.GetInstance().Current = pVideo; 

				if( ! DontSetUpNext )
				{
					Interface.SetUpNext(  Playlist.GetInstance().FindNext() );
				}

				Interface.SetNowPlaying( Playlist.GetInstance().FindNext() );
				Player.GetInstance().Play( pVideo ); 
			} 
		);
	}
	// If there is a Video in the list of Upcoming videos...
	else if( this.Upcoming.length > 0 )
	{
	    // Play the next Upcoming Video
		this.Current = this.Upcoming.shift();
		
		Interface.SetNowPlaying( this.Current );
		_Player.Play( this.Current );
		
		if( this.Upcoming.length == 0 && this.Current.IgnoreSibling != true )
		{
			this.SiblingVideos.length = 0;
			
			if( ! DontSetUpNext )
			{
				Interface.SetUpNext( this.FindNext() );
			}
			
			this.AddEpisodeClipsAfter( this.Current.ClipId, this.Current.EpisodeId );
		}
		else
		{
			 this.SiblingVideos.length = 0;
			 Interface.SetUpNext( this.FindNext() );
		}
	}
	// If there is a Video in the list of Sibling videos...
	else if( this.SiblingVideos.length > 0 )
	{
		this.Current = this.SiblingVideos.shift();

		if( ! DontSetUpNext )
		{
			Interface.SetUpNext( this.FindNext() );
		}
		
		Interface.SetNowPlaying( this.Current );
		_Player.Play( this.Current );
	}
	// If we haven't played all the FeaturedVideos yet...
	else if( Playlist.FeaturedVideos.length > 0 && Playlist.FeaturedVideos.length > this.FeaturedVideosIndex )
	{
	    // Get the next FeaturedVideo
		this.Current = Playlist.FeaturedVideos[ this.FeaturedVideosIndex ];
		
		if( this.FeaturedVideosIndex > Playlist.FeaturedVideos.length )
		{
			this.FeaturedVideosIndex = 0;
		}
		else
		{
			this.FeaturedVideosIndex++;
		}
		if( ! DontSetUpNext )
		{
			Interface.SetUpNext( this.FindNext() );
		}
				
		Interface.SetNowPlaying( this.Current );
		_Player.Play( this.Current );
	}
	else if( !AllowWait && Playlist.FeaturedVideos.length > 0 )
	{
	    // Get the next FeaturedVideo
		this.Current = Playlist.FeaturedVideos[ 0 ];
	    this.FeaturedVideosIndex = 0;
				
		if( ! DontSetUpNext )
		{
			Interface.SetNowPlaying( this.Current );
			Interface.SetUpNext( this.FindNext() );
		}
		
		_Player.Play( this.Current );
	}
	else
	{
	    // Set the player into the STOPPED state
	    _Player.Wait();
	    // Reset the FeaturedVideosIndex so the FeaturedVideos will play again when 
	    // the playlist starts up again.
	    this.FeaturedVideosIndex = 0;
	    Interface.SetNowPlaying( this.FindNext() );
	    Interface.SetUpNext( this.FindNext( 1 ) );
		
	}	
	if( Interface.UpdatePlaylist ) { Interface.UpdatePlaylist( this ); }
}
Playlist.HasNoAdCookie = function()
{
	var NoAdValue = getCookie( "NoAd" );
	
	return NoAdValue != null && NoAdValue != "";
}
// Finds the next content video (not ad) that will play theoretically, without going to that video.
Playlist.prototype.FindNext = function( Offset )
{
	var toReturn;
	var hasAlreadyBeenPlayed = false;
	var isFromFeatured		= false;
	var ignoreHistory = ! Playlist.CanDetermineEpisodeInfo(); //one clip player doesnt need this added recursion
	
	if( Offset == null || Offset == undefined )
	{
		Offset = 0;
	}

	if( this.Upcoming.length > 0 && this.Upcoming.length > Offset )
	{
		toReturn = this.Upcoming[ Offset ];
	}
	else if( 
		this.SiblingVideos.length > 0 
		&& this.SiblingVideos.length > ( Offset - this.Upcoming.length ) 
	)
	{
		toReturn = this.SiblingVideos[ ( Offset - this.Upcoming.length ) ];
	}
	else if( 
		Playlist.FeaturedVideos.length > 0 
		&& Playlist.FeaturedVideos.length > this.FeaturedVideosIndex + ( Offset - this.Upcoming.length - this.SiblingVideos.length ) 
	)
	{
		toReturn = Playlist.FeaturedVideos[ this.FeaturedVideosIndex + ( Offset - this.Upcoming.length - this.SiblingVideos.length ) ];
		isFromFeatured = true;
	}
	else
	{
		toReturn = Playlist.FeaturedVideos[ ( this.FeaturedVideosIndex + ( Offset - this.Upcoming.length - this.SiblingVideos.length ) ) % Playlist.FeaturedVideos.length ];
	}
	
	
	/*if( toReturn.ClipId && isFromFeatured && ! ignoreHistory ) //dont replay videos from the featured bin
	{
		for( i = 0; i < this.History.length; i++ )
		{
			if( this.History[ i ].ClipId == toReturn.ClipId )
			{
				hasAlreadyBeenPlayed = true;
				break;
			}
		}
		
		if(  this.Current && this.Current.ClipId == toReturn.ClipId )
		{
			hasAlreadyBeenPlayed = true;
		}
	}*/
	
	if( ! hasAlreadyBeenPlayed )
	{
		return toReturn; //exit recursion
	}
	else //recurisive step
	{
		return this.FindNext( Offset+1 );
	}
}

Playlist.DeterminePermalink = function( clipId )
{
	return "http://watch.ctv.ca/news/Redirect/Default.aspx?ClipId=" + clipId;	
}
/*
 * Framework: wrapper class for the whole broadband experience
 */
function Framework( DefaultFormat, AdInterval, OmnitureAccountId, OmniturePlayerName, DartSiteId, Theme, PrePlayImage )
{
	DefaultFormat = DefaultFormat ? DefaultFormat : Format.FlashVideo;
	Framework.__instance = this;

	/*
	var handlerFunction = function( msg, page, line )
		{
			Log( msg );
		}
		
	window.onerror = handlerFunction;
	if( window.onerror == handlerFunction )
	{
		// DO NOTHING
	}
	else if( window.addEventListener )
	{
		window.addEventListener( "error", handlerFunction, false );
	}
	else if( window.attachEvent ) 
	{
		window.attachEvent( "onerror", handlerFunction );
	}
	*/
	Ad.DARTSite = DartSiteId;
	this.DefaultFormat = DefaultFormat;
	
	new Metrics( OmnitureAccountId, OmniturePlayerName );
	
	this.Playlist = new Playlist( AdInterval );

	var _Player = new Player( Theme, PrePlayImage );
    
	if( ! PrePlayImage )
	{   
        this.Playlist.Start( ); // starts the playlist running	
	}
}

Framework.GetInstance = function()
{
	return Framework.__instance;
}


/*
 * Player: handles all the video player interaction (e.g. Play, Pause, etc.)
 */
function Player( pTheme, pPrePlayImage )
{
    
    this.Theme = pTheme;
    
    this.PrePlayImage = pPrePlayImage;

	this.Controller = new FlashController( this.Theme, this.PrePlayImage ); // loads Flash as the default controller
	this.SuccessfulPlays = 0;   // keeps track of how many videos have successfully played
	                            // **DOES NOT INCLUDE ADS**
    this.RejectedSilverlight = false;
    
    this.ClipKeyPointsSinceAd = -1; // keeps track of how many clip key points have been reached since the
                                    // last ad was played.  Set to -1 at Player instantiation.
                                    
    
	

	var OnUnLoad = function() { Player.EndClip(); }
	
	window.onunload = OnUnLoad;
	if( window.onunload == OnUnLoad )
	{
		// DO NOTHING
	}
	else if( window.addEventListener )
	{
		window.addEventListener( "unload", OnUnLoad, false );
	}
	else if( window.attachEvent ) 
	{
		window.attachEvent( "onunload", OnUnLoad );
	}
	
	if( getCookie( "Volume" ) != null && getCookie( "Volume" ) != "" )
	{
	    Player.Volume = getCookie( "Volume" );
	}

	Player.__instance = this;
}

Player.Volume = 50;

Player.GetInstance = function( pTheme, pPrePlayImage )
{
	if( ! Player.__instance )
	{
		Player.__instance = new Player( pTheme, pPrePlayImage );
	}

	
	return Player.__instance;
}

Player.prototype.Play = function( pVideo )
{
	if( Interface.DisplayViewerDiscretionIsAdvised && TVRating.GetInstance().MustAdvise( pVideo.Rating )  )
	{
	    if( this.Controller && this.Controller.Destroy ) { this.Controller.Destroy(); }
	    Interface.DisplayViewerDiscretionIsAdvised( pVideo );
	    this.Controller = null;
	    return;
	}
	
	var IsSilverlightControllerAvailable = true;	
	try
	{
	    if( SilverlightController )
	    {
	        IsSilverlightControllerAvailable = true;
	    }
	    else
	    {
	        IsSilverlightControllerAvailable = false;
	    }
	}
	catch( err )
	{
	    IsSilverlightControllerAvailable = false;
	}
	
	var IsWindowsMediaControllerAvailable = true;
	try
	{
	    if( WindowsMediaController )
	    {
	        IsWindowsMediaControllerAvailable = true;
	    }
	    else
	    {
	        IsWindowsMediaControllerAvailable = false;
	    }
	}
	catch( err )
	{
	    IsWindowsMediaControllerAvailable = false;
	}

	if( 
		! this.Controller 
		|| this.Controller.Format != pVideo.Format 
		|| ( BrowserDetect.OS != "Windows" && pVideo.Format == Format.WindowsMediaVideoDRM )
	)
	{	
		if( IsSilverlightControllerAvailable && ( pVideo.Format == Format.WindowsMediaVideo || pVideo.Format == Format.LiveStream || pVideo.Format == Format.WindowsMediaAudio ) )
		{
		    if( this.Controller && this.Controller.Destroy ) { this.Controller.Destroy(); }
			var NewController;
			if( SilverlightController.IsInstalled() || ! Interface.DisplaySilverlightChoice )
			{
				NewController = new SilverlightController( this.Theme );
			}
			else if( ! this.RejectedSilverlight && Interface.DisplaySilverlightChoice )
			{
			    if( this.Controller && this.Controller.Destroy ) { this.Controller.Destroy(); }
			    Interface.DisplaySilverlightChoice();
			    this.Controller = null;
			    return;
			}
			else
			{
			    NewController = new WindowsMediaController( this.Theme );
			}
			this.Controller = NewController;
		}
		else if( pVideo.Format == Format.FlashVideo || pVideo.Format == Format.MP3 )
		{
			if( this.Controller && this.Controller.Destroy ) { this.Controller.Destroy(); }
			var NewController = new FlashController( this.Theme );			
			this.Controller = NewController;
		}
		else if( IsWindowsMediaControllerAvailable && pVideo.Format == Format.WindowsMediaVideoDRM )
		{
			if( BrowserDetect.OS != "Windows" )
			{
				if( this.Controller && this.Controller.Destroy ) { this.Controller.Destroy(); }
				Interface.DisplayPlayerControllerError( "Windows only", "Sorry, you must be using the Microsoft Windows operating system to view this video." );
				this.Controller = null;
				
				setTimeout( "Playlist.GetInstance().Next( true )", 60000 );
				
				return;
			}
			else
			{
				if( this.Controller && this.Controller.Destroy ) { this.Controller.Destroy(); }
				var NewController = new WindowsMediaController( this.Theme );
				this.Controller = NewController;
			}
		}
		else
		{
    	    //this.Controller.Wait();
			throw "No controller available to play format " + pVideo.Format; 
			return;
		}
	}
	
	if( pVideo.Url )
	{
	    if( Interface.GetInstance().AllowUrlRewriting )
	    {
	        var urlSuffix;
	        if( pVideo.IsAd )
	        {
	            var _Playlist;
	            _Playlist = Playlist.GetInstance();
    	        
	            var NextVideo = _Playlist.FindNext();
    	        
	            if( NextVideo && NextVideo.ClipId )
	            {
	                urlSuffix = "#clip" + NextVideo.ClipId;
	            }
	            else
	            {
		            urlSuffix = "#ad";
		        }
	        }
	        else if( pVideo.ClipId )
	        {
		        urlSuffix = "#clip" + pVideo.ClipId;
	        }
	        else
	        {
		        urlSuffix = "#";
	        }

	        //document.getElementById("Video").name = urlSuffix.substring(1);
			
			document.location = urlSuffix;
	    }
	    
	    if( pVideo.OnStart != null )
		{
			pVideo.OnStart();
		}
	    
	    this.Controller.Play( pVideo );
		Metrics.StartedClip( pVideo );
	    
		if( ! pVideo.IsAd )
		{
			this.SuccessfulPlays++;
		}
		else
		{
			this.ClipKeyPointsSinceAd = 0;
		}
	}
	else
	{
	    var PlayerController = this.Controller;
	    var _Player = this;
		pVideo.AfterRemoteLoad = function( pVideo ) { Player.GetInstance().Play( pVideo ); }
		pVideo.GetRemoteUrl();
	}	
}

Player.ParseClipIdFromAddress = function()
{
	var ClipIdRegExp = new RegExp( "#clip([0-9]+)$" );
	
	var Match = ClipIdRegExp.exec( document.location + "" );
	
	if( Match && Match.length > 0 )
	{
		Log( "Found clip " + Match[1] + " on the query string" );
		return Match[1];
	}
	else
	{
		ClipIdRegExp = new RegExp( "\/clip([0-9]+)[\/\?#]?" );	
		Match = ClipIdRegExp.exec( document.location + "" );
		
		if( Match && Match.length > 0 )
		{
			Log( "Found clip " + Match[1] + " on the query string" );
			return Match[1];
		}
	}

	Log( "No clip was passed on the query string" );
	return false;
}

Player.prototype.Wait = function()
{
	if( this.Controller && this.Controller.Wait )
	{
		this.Controller.Wait();
	}
}

Player.EndClip = function()
{
    var _Playlist = Playlist.GetInstance();
	
	if( _Playlist.Current )
	{
	    if( Player.GetInstance().Controller && Player.GetInstance().Controller.Loading ) 
	    {
	        Player.GetInstance().Controller.Loading();
	    }
	    
	    Metrics.EndedClip( _Playlist.Current );
    	
	    if( _Playlist.Current.OnEnd )
	    {
		    _Playlist.Current.OnEnd();
	    }	
	    
	  //  _Playlist.Current = null;
	}
}


Player.Error = function( Message )
{
    if( Playlist.GetInstance().Current && Playlist.GetInstance().Current.IsAd )
    {
        Playlist.GetInstance().Next();
    }
    else
    {
        Metrics.ErrorPlayingClip( Playlist.GetInstance().Current, Message );
        
        /*
        if( Interface.DisplayPlayerControllerError )
        {
            Interface.DisplayPlayerControllerError( "Sorry, there was an error", Message );
        }
        */
    }
	throw "Error from the Player controller: " + Message;
}

// return a result in seconds
Player.prototype.TimeWatchedSinceAd = function()
{
    // If ClipKeyPointsSinceAd is negative, we haven't watched an ad this session yet, so return 
    // a high number corresponding to a long time since the last ad was seen.
    if( this.ClipKeyPointsSinceAd < 0 )
    {
        return 999999;
    }
    else
    {
        return this.ClipKeyPointsSinceAd * 10; // multiply by 10 because keypoints are sent every 10 seconds
    }
}

Player.OnClipKeyPoint = function( KeyPoint, pDuration )
{
    if( pDuration )
    {
        try
        {
            Playlist.GetInstance().Current.Duration = pDuration;
        }
        catch( Error )
        {
            Log( "Error setting Current Video Duration: " + Error );
        }
    }
    
    var _Playlist = Playlist.GetInstance();
    
    if( KeyPoint > 0 && ! _Playlist.Current.IsAd )
    {
        Player.GetInstance().ClipKeyPointsSinceAd++;
    }
    
    if( KeyPoint == 0 && _Playlist.Current )
    {
		if( _Playlist.Current.IsAd )
		{
			Log( "Ad was loaded successfully" );
		}
		else
		{
			Log( "Video " + _Playlist.Current.ClipId + " was loaded successfully" );
		}
    }

	Metrics.ReachedClipKeyPoint( KeyPoint );
}

Player.OnClipEnded = function()
{
	Player.EndClip();
	
	Playlist.GetInstance().Next();
}

Player.OnNextClicked = function()
{
	Playlist.GetInstance().Next();
}

Player.OnBigBoxClicked = function()
{
	var url = Ad.GetInstance().BigBoxTargetURL;
	
	if( url && url != "" && url != "undefined"  && url != undefined )
	{
		Player.PermalinkClicked( url );
	}
}

Player.SetVolume = function( pLevel )
{
    if( ( "" + Number(pLevel) ).indexOf("NaN") == -1 )
    {	
		Player.Volume = pLevel;
	    
		setCookie( "Volume", pLevel );    
	}
}
Player.GetVolume = function()
{
    return Player.Volume;
}

Player.Fullscreen = false;
Player.IsFullscreen = function( pIsFullscreen )
{
    if( pIsFullscreen != null )
    {
        Player.Fullscreen = pIsFullscreen;
    }
    return Player.Fullscreen;
}

Player.PermalinkClicked = function( pUrl )
{
    if( Interface.PermalinkClicked )
    {
        Interface.PermalinkClicked( pUrl );
    }
    else
    {
        document.location = pUrl;
    }
}























/*
 * Format: holds the possible formats of video
 */
function Format()
{}
Format.FlashVideo = "FLV";
Format.WindowsMediaVideo = "WMV";
Format.WindowsMediaVideoDRM = "WMV+DRM";
Format.LiveStream = "WMV";
Format.WindowsMediaAudio = "WMA";
Format.MP3 = "MP3";



















function Log( pMessage )
{
    if( document.getElementById("ErrorLogs") )
    {
        if( document.getElementById("ErrorLogs").style.display.toLowerCase() != "none" )
        {
			LogToNewWindow( pMessage );
			return;
		}
        
        if( Log.Count && Log.Count < 50 )
	    {   
	        document.getElementById("ErrorLogs").innerHTML += pMessage + "<br/>";
	        Log.Count++;
	    }
	    else
	    {
	        document.getElementById("ErrorLogs").innerHTML += pMessage + "<br/>";
	        Log.Count = 0;
	    }
    }
}

var _OpenWindow;
var _LastWasWhite = false;

function LogToNewWindow( pMessage )
{
	if( ! _OpenWindow )
	{
		_OpenWindow=window.open("", "newwin", "height=800, width=450,resizable=1,toolbar=0,menubar=0,scrollbars=1");
		_OpenWindow.document.write("<html><head><TITLE>Log Window</TITLE></head><body style='font-size:10pt;font-family:verdana;line-spacing:170%' ><div id='innerLogArea'></div></body></html>")		
	}
	
	var toWriteTo = _OpenWindow && _OpenWindow.document ? _OpenWindow.document.getElementById("innerLogArea") : null;
	
	if( toWriteTo )
	{
		var colour = _LastWasWhite ? "#CCCCCC" : "#FFFFFF";
		_LastWasWhite = ! _LastWasWhite;
		
		toWriteTo.innerHTML = '<span style=\'background-color:'+ colour +'\'>' + pMessage + '</span><br />' + toWriteTo.innerHTML;
	}
}





var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};

BrowserDetect.init();

function setCookie(name, value, expires, path, domain, secure)
{
	if( expires == null || expires == 'undefined' )
	{
		expires = new Date();
		
		// 7 days from now
		expires.setTime( expires.getTime() +  (7 * 24 * 60 * 60 * 1000) );
	}
	document.cookie= name + "=" + escape(value) +
		((expires) ? "; expires=" + expires.toGMTString() : "") +
		((path) ? "; path=" + path : "") +
		((domain) ? "; domain=" + domain : "") +
		((secure) ? "; secure" : "");
}

function getCookie(name)
{
	var dc = document.cookie;
	var prefix = name + "=";
	var begin = dc.indexOf("; " + prefix);
	if (begin == -1)
	{
		begin = dc.indexOf(prefix);
		if (begin != 0) return null;
	}
	else
	{
		begin += 2;
	}
	var end = document.cookie.indexOf(";", begin);
	if (end == -1)
	{
		end = dc.length;
	}
	
	return unescape(dc.substring(begin + prefix.length, end));
}
function SilverlightPlayer( DOMparent, SceneFile, ThemeFile, Url, IsAd, BugUrl,VideoTitle, PermalinkUrl, ImageUrl )
{
	this.url			= Url;
	this.isAd			= IsAd;
	this.bugUrl			= BugUrl;
	this.imageUrl		= ImageUrl;
	this.permalinkUrl	= PermalinkUrl;
	this.videoTitle		= VideoTitle;
	
	_silverlightPlayer	= this;
	
	SilverlightPlayer.ThemeFile = ThemeFile;
	
	if( SilverlightController.IsCrossDomainLoad )
	{
		//give the xaml script time to initialize...
		setTimeout( function() { createMySilverlightPlugin( DOMparent, SceneFile, ThemeFile ); }, 200 );
}	
	else
	{
		//
		createMySilverlightPlugin( DOMparent, SceneFile, ThemeFile );
	}
}

SilverlightPlayer.ThemeFile;
SilverlightPlayer.ThemeNodes;
SilverlightPlayer.SilverlightVersion = '1.0';//'0.90.0';

SilverlightPlayer.prototype.PlayUrl = function( url, isAd, bugUrl,PermalinkUrl, ImageUrl )
{	
	var __Player = getPlayerInstance();
	
	if( __Player )
	{
		__Player.playUrl( url, isAd, bugUrl, PermalinkUrl, ImageUrl  );
	}
}

SilverlightPlayer.prototype.Wait = function()
{	
	var __Player = getPlayerInstance();
	
	if( __Player )
	{
		__Player.wait();
	}
}

SilverlightPlayer.prototype.Loading = function()
{	
	var __Player = getPlayerInstance();
	
	if( __Player )
	{
		__Player.loading();
	}
}
var _width;
var _height;
var _theme;

function getPlayerHeight()
{
	return _height;
}
function getPlayerWidth()
{
	return _width;
}
function getPlayerTheme()
{
	return _theme;
}

function createMySilverlightPlugin( DOMparent, SceneFile, ThemeFile )
{  
    _width = '' + DOMparent.clientWidth;
    _height = '' + DOMparent.clientHeight;
    _theme  = ThemeFile;
	
     var sceneParameter = SilverlightController.IsCrossDomainLoad ? '#xamlContent' : SceneFile;
	
     Silverlight.createObject(
        sceneParameter,
        DOMparent,                  // DOM reference to hosting DIV tag.
        "SilverlightPlayer",         // Unique plug-in ID value.
        {                               // Per-instance properties.
            width: _width,   // Width of rectangular region of 
                                        // plug-in area in pixels.
            height: _height, // Height of rectangular region of 
                                        // plug-in area in pixels.
            inplaceInstallPrompt:true, // Determines whether to display 
                                        // in-place install prompt if 
                                        // invalid version detected.
            background:'#000000',       // Background color of plug-in.
            isWindowless:'true',       // Determines whether to display plug-in 
                                        // in Windowless mode.
                                        
            framerate:'30',             // MaxFrameRate property value.
            version:SilverlightPlayer.SilverlightVersion // Silverlight version to use.
        },
        {
            onError:_HandleError,        // OnError property value -- 
                                        // event handler function name.
            onLoad:null        // OnLoad property value -- 
                                        // event handler function name.
        },
        null);                          // Context value -- event handler function name.
}

function _HandleError( sender, errorArgs )
{
	 // The error message to display.
    var errorMsg = "Silverlight Player Error: \n\n";
    
    // Error information common to all errors.
    errorMsg += "Error Type:    " + errorArgs.errorType + "\n";
    errorMsg += "Error Message: " + errorArgs.errorMessage + "\n";
    errorMsg += "Error Code:    " + errorArgs.errorCode + "\n";
    
    // Determine the type of error and add specific error information.
    switch(errorArgs.errorType)
    {
        case "RuntimeError":
            // Display properties specific to RuntimeErrorEventArgs.
            if (errorArgs.lineNumber != 0)
            {
                errorMsg += "Line: " + errorArgs.lineNumber + "\n";
                errorMsg += "Position: " +  errorArgs.charPosition + "\n";
            }
            errorMsg += "MethodName: " + errorArgs.methodName + "\n";
            break;
        case "ParserError":
            // Display properties specific to ParserErrorEventArgs.
            errorMsg += "Xaml File:      " + errorArgs.xamlFile      + "\n";
            errorMsg += "Xml Element:    " + errorArgs.xmlElement    + "\n";
            errorMsg += "Xml Attribute:  " + errorArgs.xmlAttribute  + "\n";
            errorMsg += "Line:           " + errorArgs.lineNumber    + "\n";
            errorMsg += "Position:       " + errorArgs.charPosition  + "\n";
            break;
        case "ImageError":
            break;
        default:
            break;
    }

	Player.Error( errorMsg );
}


function Interface()
{
    this.AllowUrlRewriting = false;
}

Interface.GetInstance = function()
{
	if( ! Interface.__instance )
	{
		Interface.__instance = new Interface();
	}
	
	return Interface.__instance;
}

Interface.SetUpNext = function( pVideo ){}
Interface.SetNowPlaying = function( pVideo ){}