

/*
 * 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 )
	{
	    
		
		pUrlToPassClipId = "http://cls.ctvdigital.net/cliplookup.aspx?id={0}".replace("{0}",this.ClipId);
	}
	
	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 + "&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+";
