/*
 * 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/clip265237#clip265237', 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:'265237', BugUrl: '' ,SiteMap:'', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/autosctvca/car-care/', Permalink:'http://watch.ctv.ca/news/autosctvca/car-care/#clip265369', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_car_care_100209.jpg', Rating:'', Description:'An average household spends about $800 per year on vehicle maintenance. Pat Foran has advice on how to keep those costs to a minimum.', Title:'Autos.CTV.ca : Car care : CTV Toronto: Pat Foran with car care tips', Format:'FLV', ClipId:'265369', BugUrl: '' ,SiteMap:'Car care||ShowId=1611&EpisodeId=43921||Autos.CTV.ca||ShowId=1611', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/lifetime-ban/', Permalink:'http://watch.ctv.ca/news/top-picks/lifetime-ban/#clip265037', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_tims1_100209.jpg', Rating:'', Description:'It\'s one of the most unspeakable punishments any Canadian can imagine -- a lifetime ban from the local Tim Hortons - and one a New Brunswick man is fighting back against.', Title:'Top Picks : Lifetime ban : CTV Atlantic: Mike Cameron with the banned man', Format:'FLV', ClipId:'265037', BugUrl: '' ,SiteMap:'Lifetime ban||ShowId=1215&EpisodeId=43870||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/ttc-fights-back/', Permalink:'http://watch.ctv.ca/news/latest/ttc-fights-back/#clip265137', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_ttc_union1_100209.jpg', Rating:'', Description:'The transit union boss had some stern words for the media, riders and TTC management after a slew of embarrassing videos and pictures of questionable staff behaviour was posted on the Internet.', Title:'Latest : TTC fights back : CTV Toronto: Union boss slams TTC riders', Format:'FLV', ClipId:'265137', BugUrl: '' ,SiteMap:'TTC fights back||ShowId=1281&EpisodeId=43897||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/ttc-fights-back/', Permalink:'http://watch.ctv.ca/news/latest/ttc-fights-back/#clip265300', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_ttc_union1_100209.jpg', Rating:'', Description:'Disgruntled commuters will have a chance to vent their frustrations at a series of town hall meetings being set up by the TTC, according to the head of the public transit union.', Title:'Latest : TTC fights back : CTV Toronto Extended: Bob Kinnear speaks to media', Format:'FLV', ClipId:'265300', BugUrl: '' ,SiteMap:'TTC fights back||ShowId=1281&EpisodeId=43897||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/power-play/feb-9/', Permalink:'http://watch.ctv.ca/news/power-play/feb-9/#clip265325', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_power_play.jpg', Rating:'', Description:'Toronto mayoral candidate Adam Giambrone has acknowledged having a \'inappropriate\' relationship with a younger woman. The controversy was exaggerated by comments he supposedly made about his partner.', Title:'Power Play : Feb. 9 : Reporters on the T.O. mayoral race', Format:'FLV', ClipId:'265325', BugUrl: '' ,SiteMap:'Feb. 9||ShowId=1213&EpisodeId=43915||Power Play||ShowId=1213', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/power-play/feb-9/', Permalink:'http://watch.ctv.ca/news/power-play/feb-9/#clip265333', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_power_play.jpg', Rating:'', Description:'The Tories will take their fight against injection sites to the Supreme Court because they say it raises the issue of federal and provincial jurisdiction, but opposition MPs suggest the reason is \'disingenuous.\'', Title:'Power Play : Feb. 9 : MPs discuss safe injection sites', Format:'FLV', ClipId:'265333', BugUrl: '' ,SiteMap:'Feb. 9||ShowId=1213&EpisodeId=43915||Power Play||ShowId=1213', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/power-play/feb-9/', Permalink:'http://watch.ctv.ca/news/latest/alberta-budget/#clip265336', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_power_play.jpg', Rating:'', Description:'The Alberta government has tabled a budget for the coming year that leaves the province with a record $4.7 billion deficit. A former Conservative cabinet minister expects many people will be concerned.', Title:'Latest : Alberta budget : Power Play: Monte Solberg, former Tory MP', Format:'FLV', ClipId:'265336', BugUrl: '' ,SiteMap:'Alberta budget||ShowId=1281&EpisodeId=43898||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/power-play/feb-9/', Permalink:'http://watch.ctv.ca/news/power-play/feb-9/#clip265338', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_power_play.jpg', Rating:'', Description:'The government will cut funding for the First Nations University of Canada. The minister of Indian Affairs says attempts were made to keep it in place, but problems kept creeping up in the governance system.', Title:'Power Play : Feb. 9 : Chuck Strahl, Indian Affairs', Format:'FLV', ClipId:'265338', BugUrl: '' ,SiteMap:'Feb. 9||ShowId=1213&EpisodeId=43915||Power Play||ShowId=1213', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/power-play/feb-9/', Permalink:'http://watch.ctv.ca/news/power-play/feb-9/#clip265322', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_10_23/470_power_play.jpg', Rating:'', Description:'The minister of state for sport explains that \'Own the Podium,\' funded in part by taxpayers, should really pay off during the Olympics, and says his government has committed to maintaining the funding.', Title:'Power Play : Feb. 9 : Minister Gary Lunn', Format:'FLV', ClipId:'265322', BugUrl: '' ,SiteMap:'Feb. 9||ShowId=1213&EpisodeId=43915||Power Play||ShowId=1213', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/safe-injection/', Permalink:'http://watch.ctv.ca/news/power-play/feb-9/#clip265333', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_injection_100209.jpg', Rating:'', Description:'The Tories will take their fight against injection sites to the Supreme Court because they say it raises the issue of federal and provincial jurisdiction, but opposition MPs suggest the reason is \'disingenuous.\'', Title:'Power Play : Feb. 9 : MPs discuss safe injection sites', Format:'FLV', ClipId:'265333', BugUrl: '' ,SiteMap:'Feb. 9||ShowId=1213&EpisodeId=43915||Power Play||ShowId=1213', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/surviving-haiti/', Permalink:'http://watch.ctv.ca/news/latest/surviving-haiti/#clip264950', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_haiti_survivor_100209.jpg', Rating:'', Description:'A man was reportedly pulled from the rubble in Port-au-Prince, Haiti after being trapped for 27 days.', Title:'Latest : Surviving Haiti : Canada AM: Survivor pulled out after 27 days', Format:'FLV', ClipId:'264950', BugUrl: '' ,SiteMap:'Surviving Haiti||ShowId=1281&EpisodeId=43850||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/surviving-haiti/', Permalink:'http://watch.ctv.ca/news/latest/surviving-haiti/#clip264676', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_haiti_survivor_100209.jpg', Rating:'', Description:'It is the final week for Canadians to donate funds to Haiti and have their contributions matched by the federal government, and officials say the need is still great.', Title:'Latest : Surviving Haiti : CTV News Channel: Janice Golding on helping Haiti', Format:'FLV', ClipId:'264676', BugUrl: '' ,SiteMap:'Surviving Haiti||ShowId=1281&EpisodeId=43850||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/autosctvca/volt/', Permalink:'http://watch.ctv.ca/news/autosctvca/volt/#clip264928', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_11/470_volt_090811.jpg', Rating:'', Description:'With the world\'s media in Vancouver, Chevy is taking advantage of the Olympic spotlight to show off the newest generation of electric vehicles.', Title:'Autos.CTV.ca : Volt : CTV British Columbia: Chris Olsen with a test drive', Format:'FLV', ClipId:'264928', BugUrl: '' ,SiteMap:'Volt||ShowId=1611&EpisodeId=43853||Autos.CTV.ca||ShowId=1611', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/catch-rule/', Permalink:'http://watch.ctv.ca/news/latest/catch-rule/#clip264973', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_8/470_brain_100208.jpg', Rating:'', Description:'A doctor with Children\'s Hospital of Eastern Ontario talks about the concerns surrounding CT scans on children, and how the \'CATCH\' rule will be used to determine whether the high radiation scan is really necessary.', Title:'Latest : CATCH rule : Canada AM: Dr. Martin Osmond, study co-author', Format:'FLV', ClipId:'264973', BugUrl: '' ,SiteMap:'CATCH rule||ShowId=1281&EpisodeId=43854||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/euro-crisis/', Permalink:'http://watch.ctv.ca/news/latest/euro-crisis/#clip265317', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_ap_euros_100105.jpg', Rating:'', Description:'Europe\'s currency union is facing an unprecedented crisis as Greece\'s outstanding debt could negatively impact the entire eurozone and spark a bailout.', Title:'Latest : Euro crisis : CTV News Channel: BNN\'s Mark Bunting reports', Format:'FLV', ClipId:'265317', BugUrl: '' ,SiteMap:'Euro crisis||ShowId=1281&EpisodeId=43912||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/alberta-budget/', Permalink:'http://watch.ctv.ca/news/latest/alberta-budget/#clip265397', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_budget_100209.jpg', Rating:'', Description:'In an effort to increase health care funding by 44 per cent over the next five years, the province plans to make cuts to more than a dozen ministries and drain the majority of the provincial sustainability fund.', Title:'Latest : Alberta budget : CTV Edmonton: Provincial budget increases health and spending', Format:'FLV', ClipId:'265397', BugUrl: '' ,SiteMap:'Alberta budget||ShowId=1281&EpisodeId=43898||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/alberta-budget/', Permalink:'http://watch.ctv.ca/news/latest/alberta-budget/#clip265398', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_budget_100209.jpg', Rating:'', Description:'Post secondary students will be facing more financial pressure after the province revealed it\'s slashing millions in grants.', Title:'Latest : Alberta budget : CTV Edmonton: More debt for students after gov\'t slashes grants', Format:'FLV', ClipId:'265398', BugUrl: '' ,SiteMap:'Alberta budget||ShowId=1281&EpisodeId=43898||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/alberta-budget/', Permalink:'http://watch.ctv.ca/news/latest/alberta-budget/#clip265336', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_budget_100209.jpg', Rating:'', Description:'The Alberta government has tabled a budget for the coming year that leaves the province with a record $4.7 billion deficit. A former Conservative cabinet minister expects many people will be concerned.', Title:'Latest : Alberta budget : Power Play: Monte Solberg, former Tory MP', Format:'FLV', ClipId:'265336', BugUrl: '' ,SiteMap:'Alberta budget||ShowId=1281&EpisodeId=43898||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/tamoxifen-block/', Permalink:'http://watch.ctv.ca/news/latest/tamoxifen-block/#clip264958', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_paxil_pill_100209.jpg', Rating:'', Description:'A doctor with the Institute for Clinical Evaluative Sciences explains a new study that found a particular anti-depressant known as Paxil can block the life-saving benefits of the breast cancer drug Tamoxifen.', Title:'Latest : Tamoxifen block : Canada AM: Dr. David Juurlink, study co-author', Format:'FLV', ClipId:'264958', BugUrl: '' ,SiteMap:'Tamoxifen block||ShowId=1281&EpisodeId=43852||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/talking-literacy/', Permalink:'http://watch.ctv.ca/news/top-picks/talking-literacy/#clip264976', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_power_of_promise_100209.jpg', Rating:'', Description:'The author talks about his new book, helping to free Rubin \'The Hurricane\' Carter from prison and his battle with illiteracy, plus his Canadian connection.', Title:'Top Picks : Talking literacy : Canada AM: Lesra Martin, \'The Power of a Promise\'', Format:'FLV', ClipId:'264976', BugUrl: '' ,SiteMap:'Talking literacy||ShowId=1215&EpisodeId=43855||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/isotope-concern/', Permalink:'http://watch.ctv.ca/news/latest/isotope-concern/#clip264809', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_12/470_isotope_090812.jpg', Rating:'', Description:'Galloway says doctors are worried about an isotope shortage caused by a Dutch reactor closure. They fear people with suspected cancer or heart disease may have scheduling issues or may even get dismissed.', Title:'Latest : Isotope concern : CTV News Channel: Gloria Galloway, Globe and Mail', Format:'FLV', ClipId:'264809', BugUrl: '' ,SiteMap:'Isotope concern||ShowId=1281&EpisodeId=43815||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/isotope-concern/', Permalink:'http://watch.ctv.ca/news/latest/isotope-concern/#clip264723', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_12/470_isotope_090812.jpg', Rating:'', Description:'The isotope concerns caused by the Dutch shut down are exacerbated by the closure of the Chalk River reactor, because the two facilities produced about 60 per cent of the world\'s isotope supply.', Title:'Latest : Isotope concern : CTV News Channel: Tonda McCharles with details', Format:'FLV', ClipId:'264723', BugUrl: '' ,SiteMap:'Isotope concern||ShowId=1281&EpisodeId=43815||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/', Permalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/#clip265335', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_prius.jpg', Rating:'', Description:'Toyota has announced another recall in the midst of a massive recall last week. The auto giant has now recalled 437,000 Prius and other hybrids globally for brake problems.', Title:'Autos.CTV.ca : Toyota recall : CTV News: Roger Smith on the recalls', Format:'FLV', ClipId:'265335', BugUrl: '' ,SiteMap:'Toyota recall||ShowId=1611&EpisodeId=43851||Autos.CTV.ca||ShowId=1611', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/', Permalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/#clip265379', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_prius.jpg', Rating:'', Description:'Some Winnipeg Toyota owners are worried a recall will lower the resale value of their vehicles.', Title:'Autos.CTV.ca : Toyota recall : CTV Winnipeg: Eleanor Coopsammy reports', Format:'FLV', ClipId:'265379', BugUrl: '' ,SiteMap:'Toyota recall||ShowId=1611&EpisodeId=43851||Autos.CTV.ca||ShowId=1611', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/', Permalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/#clip265363', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_prius.jpg', Rating:'', Description:'Toyota announced Tuesday that 437,000 Prius and other hybrid models are being recalled worldwide so that brake problems can be fixed. ', Title:'Autos.CTV.ca : Toyota recall : CTV Montreal: Cindy Sherwin on the recall', Format:'FLV', ClipId:'265363', BugUrl: '' ,SiteMap:'Toyota recall||ShowId=1611&EpisodeId=43851||Autos.CTV.ca||ShowId=1611', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/', Permalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/#clip265287', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_prius.jpg', Rating:'', Description:'The latest recall goes beyond quality, but until Toyota comes up with a solution to the problem, consumer confidence in the auto giant will continue to weaken.', Title:'Autos.CTV.ca : Toyota recall : CTV News Channel: George Magliano, auto expert', Format:'FLV', ClipId:'265287', BugUrl: '' ,SiteMap:'Toyota recall||ShowId=1611&EpisodeId=43851||Autos.CTV.ca||ShowId=1611', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/', Permalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/#clip265016', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_prius.jpg', Rating:'', Description:'A business professor discusses how Toyota is handling the PR nightmare of so many recalled vehicles and whether this will impact future sales of the car brand.', Title:'Autos.CTV.ca : Toyota recall : CTV News Channel: Ian Lee, Carleton University', Format:'FLV', ClipId:'265016', BugUrl: '' ,SiteMap:'Toyota recall||ShowId=1611&EpisodeId=43851||Autos.CTV.ca||ShowId=1611', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/', Permalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/#clip264993', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_prius.jpg', Rating:'', Description:'A discussion about the future of consumer confidence in Toyota after it announced a major expansion to its current list of vehicle recalls -  including 437,000 Prius and other hybrid models are being recalled so that brake problems can be fixed.', Title:'Autos.CTV.ca : Toyota recall : CTV News Channel: BNN\'s Michael Kane explains', Format:'FLV', ClipId:'264993', BugUrl: '' ,SiteMap:'Toyota recall||ShowId=1611&EpisodeId=43851||Autos.CTV.ca||ShowId=1611', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/', Permalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/#clip264963', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_prius.jpg', Rating:'', Description:'An automotive industry analyst says the magnitude of the Toyota recall is significant coming on the heels of another recall, and especially since it is a company that has built its name on quality.', Title:'Autos.CTV.ca : Toyota recall : Canada AM: Charlotte Yates, McMaster Univ.', Format:'FLV', ClipId:'264963', BugUrl: '' ,SiteMap:'Toyota recall||ShowId=1611&EpisodeId=43851||Autos.CTV.ca||ShowId=1611', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/', Permalink:'http://watch.ctv.ca/news/autosctvca/toyota-recall/#clip264531', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_prius.jpg', Rating:'', Description:'While Toyota has done the right things to deal with problems with their vehicles, they may not have reacted quickly enough to prevent it from becoming a crisis.', Title:'Autos.CTV.ca : Toyota recall : Canada AM: Allen Adamson, Landor Associates', Format:'FLV', ClipId:'264531', BugUrl: '' ,SiteMap:'Toyota recall||ShowId=1611&EpisodeId=43851||Autos.CTV.ca||ShowId=1611', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/investigation-on/', Permalink:'http://watch.ctv.ca/news/latest/investigation-on/#clip265337', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_williams_100209.jpg', Rating:'', Description:'As police continue to investigate Col. Russ Williams, neighbours in the area are in disbelief, as accusations against the high ranking military officer continues to mount.', Title:'Latest : Investigation on : CTV News: Richard Madan in Ottawa', Format:'FLV', ClipId:'265337', BugUrl: '' ,SiteMap:'Investigation on||ShowId=1281&EpisodeId=43849||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/investigation-on/', Permalink:'http://watch.ctv.ca/news/latest/investigation-on/#clip265373', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_williams_100209.jpg', Rating:'', Description:'Col. Russell Williams has been charged with two murders in Ontario and was once posted in Manitoba.', Title:'Latest : Investigation on : CTV Winnipeg: Rachel Lagace reports', Format:'FLV', ClipId:'265373', BugUrl: '' ,SiteMap:'Investigation on||ShowId=1281&EpisodeId=43849||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/investigation-on/', Permalink:'http://watch.ctv.ca/news/latest/investigation-on/#clip265355', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_williams_100209.jpg', Rating:'', Description:'Old-fashioned police work led to the arrest of a senior Air Force officer in connection with two murder and two home invasions. Austin Delaney reports.', Title:'Latest : Investigation on : CTV Toronto: Austin Delaney on the break in the case', Format:'FLV', ClipId:'265355', BugUrl: '' ,SiteMap:'Investigation on||ShowId=1281&EpisodeId=43849||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/investigation-on/', Permalink:'http://watch.ctv.ca/news/latest/investigation-on/#clip265356', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_williams_100209.jpg', Rating:'', Description:'The sex-related murder of a 19-year-old at CFB Trenton is but one to be re-opened following the arrest Monday of Col. Russell Williams on two counts of first-degree murder. Jim Junkin reports.', Title:'Latest : Investigation on : CTV Toronto: Jim Junkin on the re-opened case', Format:'FLV', ClipId:'265356', BugUrl: '' ,SiteMap:'Investigation on||ShowId=1281&EpisodeId=43849||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/investigation-on/', Permalink:'http://watch.ctv.ca/news/latest/investigation-on/#clip265340', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_williams_100209.jpg', Rating:'', Description:'While police continue to search for evidence in a murder case against an accused military official, focus is also shifting to Ottawa, where the suspect lived for the past 15 years.', Title:'Latest : Investigation on : CTV Ottawa: Joanne Schnurr on the reaction', Format:'FLV', ClipId:'265340', BugUrl: '' ,SiteMap:'Investigation on||ShowId=1281&EpisodeId=43849||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/investigation-on/', Permalink:'http://watch.ctv.ca/news/latest/investigation-on/#clip265157', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_williams_100209.jpg', Rating:'', Description:'Shock and disbelief are the primary feelings in the community where Col Russell Williams was arrested, an area where the military plays a big role in community affairs.', Title:'Latest : Investigation on : CTV News Channel: John Williams, Quinte West mayor', Format:'FLV', ClipId:'265157', BugUrl: '' ,SiteMap:'Investigation on||ShowId=1281&EpisodeId=43849||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/investigation-on/', Permalink:'http://watch.ctv.ca/news/latest/investigation-on/#clip264991', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_williams_100209.jpg', Rating:'', Description:'A reporter for the Belleville Intelligencer explains how information obtained during a roadside canvass reportedly led to the arrest of Col. Russell Williams, who was a so-called \'shining star\' in the military.', Title:'Latest : Investigation on : CTV News Channel: Brice McVicar in Belleville', Format:'FLV', ClipId:'264991', BugUrl: '' ,SiteMap:'Investigation on||ShowId=1281&EpisodeId=43849||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/investigation-on/', Permalink:'http://watch.ctv.ca/news/latest/investigation-on/#clip264955', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_williams_100209.jpg', Rating:'', Description:'Many who were knew Col. Russell Williams are finding it very difficult to reconcile his reputation with the charges he now faces in the murders of two women. Meanwhile the investigation continues in other areas of the country where he served.', Title:'Latest : Investigation on : Canada AM: Sue Sgambati, CP24 crime specialist', Format:'FLV', ClipId:'264955', BugUrl: '' ,SiteMap:'Investigation on||ShowId=1281&EpisodeId=43849||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/investigation-on/', Permalink:'http://watch.ctv.ca/news/latest/investigation-on/#clip264670', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_williams_100209.jpg', Rating:'', Description:'Col. Russ Williams of Tweed, Ont., has been arrested in the death of 27-year-old Jessica Lloyd, and first-degree murder charges have also been laid in the death of a second woman. Charges have also been laid for two additional home invasions.', Title:'Latest : Investigation on : CTV News Channel: OPP Det. Insp. Chris Nicholas', Format:'FLV', ClipId:'264670', BugUrl: '' ,SiteMap:'Investigation on||ShowId=1281&EpisodeId=43849||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/investigation-on/', Permalink:'http://watch.ctv.ca/news/latest/investigation-on/#clip264665', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_9/470_cp_williams_100209.jpg', Rating:'', Description:'OPP Dep. Commissioner Vince Hawkes says an arrest has been made in the murder of 27-year-old Jessica Lloyd. Belleville Police Chief Cory McMullen says that the conclusion of the case would not have come about without the co-operation of several police services.', Title:'Latest : Investigation on : CTV News Channel: Police speak in Belleville, Ont.', Format:'FLV', ClipId:'264665', BugUrl: '' ,SiteMap:'Investigation on||ShowId=1281&EpisodeId=43849||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/mla-spending/', Permalink:'http://watch.ctv.ca/news/latest/mla-spending/#clip264821', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_8/470_darrell_dexter2_100208.jpg', Rating:'', Description:'N.S. Premier Darrell Dexter returned from holidays Monday and released a list of MLAs and their expenses. It turns out it was Yarmouth PC MLA Richard Hurlburt who expensed a $2,500 television.', Title:'Latest : MLA spending : CTV Atlantic: Rick Grant on the expense list', Format:'FLV', ClipId:'264821', BugUrl: '' ,SiteMap:'MLA spending||ShowId=1281&EpisodeId=43831||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/unfit-for-trial/', Permalink:'http://watch.ctv.ca/news/latest/unfit-for-trial/#clip264835', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_8/470_rauzon_mugshot_100208.jpg', Rating:'', Description:'Prosecutors and defense lawyers have agreed that the man who killed Sister Estelle Lauzon did so during an epilectic seizure. ', Title:'Latest : Unfit for trial : CTV Montreal: Stephane Giroux on the case', Format:'FLV', ClipId:'264835', BugUrl: '' ,SiteMap:'Unfit for trial||ShowId=1281&EpisodeId=43839||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/ctv-national-news/feb-8/', Permalink:'http://watch.ctv.ca/news/ctv-national-news/feb-8/#clip264941', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_7/470_tom_clark_090807.jpg', Rating:'', Description:'Canada\'s Armed Forces is rocked by murder charges, Michael Jackson\'s doctor is charged with manslaughter and the weather in Vancouver is a big concern heading into the 2010 Olympic Games. Plus, Canada\'s Olympic team sets their eyes on the gold.', Title:'CTV National News : Feb. 8 : Part one', Format:'FLV', ClipId:'264941', BugUrl: '' ,SiteMap:'Feb. 8||ShowId=1209&EpisodeId=43838||CTV National News||ShowId=1209', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/ctv-national-news/feb-8/', Permalink:'http://watch.ctv.ca/news/ctv-national-news/feb-8/#clip264943', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_7/470_tom_clark_090807.jpg', Rating:'', Description:'A remarkable tale of survival in Haiti, as a survivor is pulled out of the rubble one month after the quake, and CTV gives an update on a radical new approach to treating Multiple Sclerosis.', Title:'CTV National News : Feb. 8 : Part two', Format:'FLV', ClipId:'264943', BugUrl: '' ,SiteMap:'Feb. 8||ShowId=1209&EpisodeId=43838||CTV National News||ShowId=1209', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/ctv-national-news/feb-8/', Permalink:'http://watch.ctv.ca/news/ctv-national-news/feb-8/#clip264946', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_7/470_tom_clark_090807.jpg', Rating:'', Description:'If anybody\'s looking for wide open spaces to enjoy winter sports, the place to be is Whistler -- but skiers are in short supply because they\'ve all caught something called \'Olympic aversion.\'', Title:'CTV National News : Feb. 8 : Part three', Format:'FLV', ClipId:'264946', BugUrl: '' ,SiteMap:'Feb. 8||ShowId=1209&EpisodeId=43838||CTV National News||ShowId=1209', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/ctv-national-news/feb-8/', Permalink:'http://watch.ctv.ca/news/ctv-national-news/feb-8/#clip264948', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_8_7/470_tom_clark_090807.jpg', Rating:'', Description:'For many Canadians, one Olympic sport stands out above all others -- hockey. And whether you\'re male or female, it\'s some of the best hockey you\'ll ever see.', Title:'CTV National News : Feb. 8 : Part four', Format:'FLV', ClipId:'264948', BugUrl: '' ,SiteMap:'Feb. 8||ShowId=1209&EpisodeId=43838||CTV National News||ShowId=1209', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/doc-charged/', Permalink:'http://watch.ctv.ca/news/latest/doc-charged/#clip264939', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_8/470_ap_conrad_murray_100208.jpg', Rating:'', Description:'The doctor at the centre of the storm of Michael Jackson\'s death has pleaded not guilty to a charge of involuntary manslaughter. Dr. Conrad Murray stands accused of administering the powerful drugs that ultimately killed Jackson.', Title:'Latest : Doc charged : CTV National News: Genevieve Beauchemin reports', Format:'FLV', ClipId:'264939', BugUrl: '' ,SiteMap:'Doc charged||ShowId=1281&EpisodeId=43817||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/doc-charged/', Permalink:'http://watch.ctv.ca/news/latest/doc-charged/#clip264795', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_8/470_ap_conrad_murray_100208.jpg', Rating:'', Description:'Bird says Dr. Conrad Murray\'s defense will be a \'battle of experts\' who will argue that Murray was not negligent when he administered the drug.', Title:'Latest : Doc charged : CTV News Channel: George Bird, criminal lawyer', Format:'FLV', ClipId:'264795', BugUrl: '' ,SiteMap:'Doc charged||ShowId=1281&EpisodeId=43817||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/e-trade-baby/', Permalink:'http://watch.ctv.ca/news/top-picks/e-trade-baby/#clip264644', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_8/470_baby_100208.jpg', Rating:'', Description:'17-month old McAllister Kerr from Oakville, Ont. South of the border, he\'s already a house-hold name as his face is featured prominently in E-Trade commercials.', Title:'Top Picks : E-Trade baby : CTV Toronto: Oakville baby stars in Super Bowl ad', Format:'FLV', ClipId:'264644', BugUrl: '' ,SiteMap:'E-Trade baby||ShowId=1215&EpisodeId=43809||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/top-picks/rrsp-deadline/', Permalink:'http://watch.ctv.ca/news/top-picks/rrsp-deadline/#clip264537', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2009_9_14/470_cp_canadian_money_090914.jpg', Rating:'', Description:'\'The Skeptical Investor\' author discusses tips for growing and protecting your retirement savings, and says the first step is to get serious about your savings, as it may be the basis of your retirement income.', Title:'Top Picks : RRSP deadline : Canada AM: John Lawrence Reynolds, author', Format:'FLV', ClipId:'264537', BugUrl: '' ,SiteMap:'RRSP deadline||ShowId=1215&EpisodeId=43784||Top Picks||ShowId=1215', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/gainey-gone/', Permalink:'http://watch.ctv.ca/news/latest/gainey-gone/#clip265133', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_8/470_cp_gainey_100208.jpg', Rating:'', Description:'Bob Gainey\'s resignation has been the talk of the town. Rob Lurie finds out what Montrealers think of the Habs GM stepping down.', Title:'Latest : Gainey gone : CTV Montreal: Fans react to Gainey\'s resignation', Format:'FLV', ClipId:'265133', BugUrl: '' ,SiteMap:'Gainey gone||ShowId=1281&EpisodeId=43812||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/gainey-gone/', Permalink:'http://watch.ctv.ca/news/latest/gainey-gone/#clip264681', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_8/470_cp_gainey_100208.jpg', Rating:'', Description:'Bob Gainey is stepping down as the Montreal Canadiens GM. Analysts are surprised by the move because the Habs are doing really well this season and because he had the opportunity to step down in the summer.', Title:'Latest : Gainey gone : CTV Montreal: Brian Wilde on the decision', Format:'FLV', ClipId:'264681', BugUrl: '' ,SiteMap:'Gainey gone||ShowId=1281&EpisodeId=43812||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/ms-cure/', Permalink:'http://watch.ctv.ca/news/latest/ms-cure/#clip264942', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_8/470_brain_100208.jpg', Rating:'', Description:'Scientists from around the world met in Hamilton, Ont., over the weekend to discuss the latest research and to launch new studies in the fight against Multiple Sclerosis.CTV National News: Avis Favaro on the meeting', Title:'Latest : MS cure? : CTV National News: Avis Favaro on the meeting', Format:'FLV', ClipId:'264942', BugUrl: '' ,SiteMap:'MS cure?||ShowId=1281&EpisodeId=43790||Latest||ShowId=1281', IsCanadaOnly:'0'} ) );
    
        Playlist.FeaturedVideos.push( new Video( {EpisodePermalink:'http://watch.ctv.ca/news/latest/ms-cure/', Permalink:'http://watch.ctv.ca/news/latest/ms-cure/#clip264567', IsAd:false, Thumbnail:'', EpisodeThumbnail:'http://images.ctvdigital.com/images/pub2upload/30/2010_2_8/470_brain_100208.jpg', Rating:'', Description:'An Italian medical professor discusses his groundbreaking medical theory and procedure that could potentially cure patients who suffer from Multiple Sclerosis.', Title:'Latest : MS cure? : Canada AM:  Dr. Paolo Zamboni, medical professor', Format:'FLV', ClipId:'264567', BugUrl: '' ,SiteMap:'MS cure?||ShowId=1281&EpisodeId=43790||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 ){}