
var g_dVideoAspect = (640/480);


// mechanism so that silverlight players can call back into its corresponding object
var arrPlayers = new Array();
function mediaElementLoaded(sender)
{
    // Set the TextBlock to display the current date and time.
    var id = sender.GetHost().id;
    arrPlayers[id].OnPlayerLoaded(sender);
}

// silverlight video player
function SilverlightVideoPlayer(el, strId)
{
    var m_pEl = el;
    
    var m_pVideo = null;
    var m_pInfo = null;
    var m_dVideoWidth = null;
    var m_dVideoHeight = null;

    arrPlayers[strId] = this;
    
    this.Initialize = function(info)
    {
        m_pInfo = info;
            
        // initialize our silverlight instance with the load callback
        Silverlight.createObjectEx({
	        source: 'VideoPlayer.xaml',
	        parentElement: m_pEl,
	        id: strId,
	        properties:{
		        width:'100%',
		        height:'240px',
		        background:'black',
		        isWindowless:'false',
		        version:'1.0'
	        },
	        events:{
		        onError:null,
		        onLoad:this.OnResize
	        },
	        context:null
        });
    }
        
    // this is needed by TabViewer for layout
    this.AspectRatio = g_dVideoAspect;
    
    // called when our mediaelement xaml element is loaded
    this.OnPlayerLoaded = function(sender)
    {
        // get a pointer to the mediaelement and set our source
        var slPlugin = sender.getHost();
	    m_pVideo = slPlugin.content.findName("mediaElement");
        m_pVideo.Source = m_pInfo.Url;
        m_pVideo.BufferingTime = CreateTimeSpan(0);
        
        if( m_dVideoWidth && m_dVideoHeight )
        {
            this.SetSize( m_dVideoWidth, m_dVideoHeight );
        }
    }

    this.SetVisible = function( bVisible )
    {
        SetVisible( m_pEl, bVisible );
    }
    
    this.SetVideoPosition = function( fTime )
    {
        if( fTime < m_pVideo.NaturalDuration.Seconds )
        {
            m_pVideo.Position = CreateTimeSpan(fTime);
        }
    }
    
    this.GetVideoPosition = function()
    {
        if( !m_pVideo )
            return 0;
        else
            return m_pVideo.Position.Seconds;
    }
    
    this.GetPlayState = function()
    {
        var state = null;
        
        if(m_pVideo)
        {
            try
            {
                state = m_pVideo.CurrentState;
            }
            catch(error)
            {
            }
        }
        
        return state;
    }
    
    this.SetPlayState = function( playState )
    {
        if( this.GetPlayState() != playState && m_pVideo )
        {
            if( playState == "Playing" )
            {
                m_pVideo.Play();
            }
            else if( playState == "Paused" )
            {
                m_pVideo.Pause();
            }
        }
    }
    
    this.UpdateStatus = function(pEvent, bUserInitiated)
    {
        if( !m_pVideo )
            return;
        
        // synchronize positions - if we are more than the threshold away from the
        // archival video then synchronize
        var fTargetObjPos;
        if( m_pInfo.Segments )
        {
            var iTargetSeg = 0;
            while( iTargetSeg < m_pInfo.Segments.length && m_pInfo.Segments[iTargetSeg].RelativeStart <= pEvent.Time )
            {
                iTargetSeg++;
            }
            iTargetSeg--;
            var pTargetSeg = m_pInfo.Segments[iTargetSeg];
            fTargetObjPos = Math.max( pTargetSeg.Offset + pEvent.Time - pTargetSeg.RelativeStart, 0 ); 
        }
        else
        {
            // our target with respect to the archival video
            fTargetObjPos = Math.max( pEvent.Time - m_pInfo.RelativeStart, 0 );    
        }
        
        try
        {
            var fCurPos = m_pVideo.Position.Seconds;
            if( bUserInitiated || (Math.abs(fCurPos - fTargetObjPos) > g_fOffsetThreshold) )
            {
                this.SetVideoPosition( fTargetObjPos );
            }
            var curPlayState = this.GetPlayState();
            if(pEvent.PlayState != curPlayState)
            {
                this.SetPlayState(pEvent.PlayState);
            }
        }
        catch(error)
        {
        }
    }
    
    this.SetSize = function(width, height)
    {
        m_dVideoWidth = width;
        m_dVideoHeight = height;
        
        m_pEl.style.width = width + "px";
        m_pEl.style.height = height + "px";
        
        var slPlugin = document.getElementById(strId);
        if( slPlugin )
        {
            slPlugin.style.height = height + "px";
            slPlugin.style.width = width + "px";
        }
        
        if( m_pVideo )
        {
            try
            {
                m_pVideo.Width = m_dVideoWidth;
                m_pVideo.Height = m_dVideoHeight;
            }
            catch(error)
            {
            }   
        }
    }
    
    this.GetHeight = function()
    {
        return m_dVideoHeight;
    }
}


// helper functions
function CreateTimeSpan(fSeconds)
{
    // hooray, javascript
    function pad(int)
    {
        return int = (int < 10) ? '0' + int : int;
    }

    // surely there is some built-in way to do this
    var iHours = Math.floor(fSeconds / 3600);
    var iMinutes = Math.floor((fSeconds % 3600) / 60);
    var seconds = fSeconds % 60;
    seconds = seconds.toFixed(2);
    return pad(iHours) + ":" + pad(iMinutes) + ":" + pad(seconds);
}
