/*
 * Metrics: tracks the user within the player via a metrics package
 */

//Object to hold all available info for a video.
VideoInfo=new Object();

//default to Long Form->Entertainment->General for C5 Value
var comscoreC5="030200";

var VideoPlayerName="One-clip Player";

// 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( "Ctvgmmuchmusic", "MuchMusic 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;	 
}

//build Video info object and track ads with comscore
Metrics.ReportMedia = function (VideoInfoData)
{
	VideoInfo=VideoInfoData;
	try{
    	SendVideoInfo();
    }catch(err){}
	if (VideoInfo.category=="ad"){
		COMSCORE.beacon({
		c1: 1,
		c2: "3005664",
		c3: "",
		c4: "8016412",
		c5: "010000",
		c6: "Ad"
		});
	}
}

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 )
	        {
				COMSCORE.beacon({
                c1: 1,
                c2: "3005664",
                c3: "",
                c4: "8016412",
                c5: comscoreC5,
                c6: CurrentClip.Title
                });
				
				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 =VideoPlayerName;

	if (s_siteName == "MuchMusic_NewMusicLive")
	{
		sInstance.prop18	= sInstance.eVar18 ="NewMusicLivePlayer";
	}
}

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;

/*http://watch.muchmusic.com/js/Video.aspx---------------------------------------------------------------*/

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.muchmusic.com/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+";
