
/*
 * 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));
}