
/*
 * 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.UseMetricsOverridePlayName = false;

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.Pause = function(pSeconds) {
    var _Playlist = Playlist.GetInstance();

    if (_Playlist.Current) {
       // console.log("pause:" + pSeconds);
        Metrics.StopClip(_Playlist.Current, pSeconds);
    }
}


Player.Play = function (pSeconds) {

    var _Playlist = Playlist.GetInstance();

    if (_Playlist.Current) {
        // console.log("play:" + pSeconds);
        Metrics.StartClip(_Playlist.Current, pSeconds);
    }
}

Player.prototype.Play = function (pVideo) {

    Metrics.UseMetricsOverridePlayName = Framework.UseMetricsOverridePlayName;

    Utility.Log("Play");

    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)) {

        Utility.Log("User agent:" + navigator.userAgent);
        //        if (navigator.userAgent.match(/iPad/i) != null) {
        //            if (this.Controller && this.Controller.Destroy) { this.Controller.Destroy(); }
        //            var NewController = new IDeviceController(this.Theme);
        //            this.Controller = NewController;
        //        }
        //        else 
        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 (pVideo.Format == Format.MP3) {
            if (this.Controller && this.Controller.Destroy) { this.Controller.Destroy(); }
            var silverlight2Controller = new Silverlight2Controller();
            this.Controller = silverlight2Controller;
        }
        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;
        }
    } else {

        //        Utility.Log("ELSE");
        //        if (navigator.userAgent.match(/iPad/i) != null) {
        //            if (this.Controller && this.Controller.Destroy) { this.Controller.Destroy(); }
        //            var NewController = new IDeviceController(this.Theme);
        //            this.Controller = NewController;
        //        }
    }

    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) {

        var timeLinePosition = Player.GetInstance().Controller.getTimelinePosition();
        
        if (Player.GetInstance().Controller && Player.GetInstance().Controller.Loading) {
            Player.GetInstance().Controller.Loading();
        }



        Metrics.EndedClip(_Playlist.Current, timeLinePosition);

        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().CallMads(Playlist.GetInstance().FindNext());

    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.GetShowName = function () {
    var _Playlist = Playlist.GetInstance();

    var nextVideo;

    //If there is a Video in the list of Upcoming videos...
    if (_Playlist.Upcoming.length > 0) {
        nextVideo = _Playlist.Upcoming.shift();
    }
    //If there is a Video in the list of Sibling videos...
    else if (_Playlist.SiblingVideos.length > 0) {
        nextVideo = _Playlist.SiblingVideos.shift();
    }
    // If we haven't played all the FeaturedVideos yet...
    else if (Playlist.FeaturedVideos.length > 0 && Playlist.FeaturedVideos.length > _Playlist.FeaturedVideosIndex) {
        // Get the next FeaturedVideo
        nextVideo = Playlist.FeaturedVideos[_Playlist.FeaturedVideosIndex];
    }
    else if (Playlist.FeaturedVideos.length > 0) {
        // Get the next FeaturedVideo
        nextVideo = Playlist.FeaturedVideos[0];
    }
    else {
        return "";
    }

    return Player.GetShowNameFromSiteMap(nextVideo);
}


Player.GetShowNameFromSiteMap = function (nextVideo) {
    if (nextVideo.SiteMap) {
        var showName;
        showName = nextVideo.SiteMap[nextVideo.SiteMap.length - 1][0]

        return escape(showName);
    }
}

Player.GetCurrentShowMetadata = function () {

    var _Playlist = Playlist.GetInstance();

    var nextVideo;

    //If there is a Video in the list of Upcoming videos...
    if (_Playlist.Upcoming.length > 0) {
        nextVideo = _Playlist.Upcoming[0];
    }
    //If there is a Video in the list of Sibling videos...
    else if (_Playlist.SiblingVideos.length > 0) {
        nextVideo = _Playlist.SiblingVideos[0];
    }
    // If we haven't played all the FeaturedVideos yet...
    else if (Playlist.FeaturedVideos.length > 0 && Playlist.FeaturedVideos.length > _Playlist.FeaturedVideosIndex) {
        // Get the next FeaturedVideo
        nextVideo = Playlist.FeaturedVideos[_Playlist.FeaturedVideosIndex];
    }
    else if (Playlist.FeaturedVideos.length > 0) {
        // Get the next FeaturedVideo
        nextVideo = Playlist.FeaturedVideos[0];
    }

    var currentVideoTitle;
    var currentVideoDescription;
    var currentClipID;
    var currentPermalink;
    var currentIsAd;

    if (_Playlist.Current == null) {
        //nothing played yet, likely due to lack of autoplay, use NEXT
        currentVideoTitle = nextVideo.Title;
        currentVideoDescription = nextVideo.Description;
        currentClipID = nextVideo.ClipId;
        currentPermalink = nextVideo.Permalink;
        currentIsAd = nextVideo.IsAd;
    } else {
        currentVideoTitle = _Playlist.Current.Title;
        currentVideoDescription = _Playlist.Current.Description;
        currentClipID = _Playlist.Current.ClipId;
        currentPermalink = _Playlist.Current.Permalink;
        currentIsAd = _Playlist.Current.IsAd;
    }

    var nextVideoTitle = nextVideo.Title;

    var metadata = { currentTitle: currentVideoTitle, currentDescription: currentVideoDescription, nextTitle: nextVideoTitle, clipID: currentClipID, permalink: currentPermalink, isAd: currentIsAd };

    return metadata;
}




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";
Format.IDevice = "MP4";



















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));
}
