
var g_cTocTopPadding = 10;
var g_cNotesInputHeight = 94;
var g_cNotesChooseUserHeight = 28;
var g_cEventViewerBorderWidth = 1;

// tab control that hosts multiple event viewers
function EventTabViewer(el, pViewer)
{
    var m_el = el;
    var m_pLastStatus = null;
    var m_pSelectedView = null;
    
    // create our tab control (boolean specifies small tabs)
    var m_pTabControl = new TabControl(document.getElementById( "eventViewerBar" ), OnSelectView, false);
    
    // create our table of contents
    var m_pContents = new TocViewer(document.getElementById("tocDiv"), pViewer);
    m_pContents.Title = "Contents";
    m_pContents.SetVisible( false );

    this.RenderContents = function( arrEvents )
    {
        // initialize our tab control with our array of viewers
        var arrViews = [];
        if( arrEvents.length > 0 ) 
        {
            arrViews.unshift( m_pContents );
        }
        m_pTabControl.SetViews( arrViews );
    
        m_pContents.RenderContents( arrEvents );
    }
    
    this.UpdateStatus = function UpdateStatus( status )
    {
        m_pLastStatus = status;
        m_pSelectedView.UpdateStatus( status );
    }

    // callback for clicking on tabs
    function OnSelectView(pView)
    {
        // if the current player no longer is needed then hide it
        if( m_pSelectedView && m_pSelectedView != pView )
        {
            m_pSelectedView.SetVisible( false );
        }
    
        // show player for this view
        m_pSelectedView = pView;
        if( m_pLastStatus )
        {
            m_pSelectedView.UpdateStatus( m_pLastStatus );
        }
        m_pSelectedView.SetVisible( true );
        m_pSelectedView.SetFocus();
    }
    
    this.SetHeight = function SetHeight(controlHeight)
    {
        // set the height of our viewers taking into account the height of our tabs
        m_el.style.height = controlHeight + "px";
        
        m_pContents.OnResize( controlHeight - g_dTabBarOffsetHeight );
    }
    
    this.SetWidth = function SetWidth(controlWidth)
    {
        m_el.style.width = controlWidth + "px";
    }
}

// visual representation for events - pass in the parent, event object, and options
// options:
//  DeleteCallback - when present a delete button is shown for the visual and when clicked
//                   calls the passed in function with the event
function EventVisual( elParent, pEvent, pOptions )
{
    var m_pEvent = pEvent;
    var m_bSelected = false;
    var m_bHovering = false;
    
    var m_elContainer = CreateChildElement( elParent, "div", "eventVisual" );
    var innerContainer = CreateChildElement( m_elContainer, "div", "" );
    innerContainer.style.position = "relative";
    
    var divTime = CreateChildElement( innerContainer, "div", "eventVisualTime" );
    divTime.innerHTML = (g_bIsLiveNotes ? FormatFileTime(m_pEvent.Time) : FormatSeconds(m_pEvent.Time));

    var divCaption = CreateChildElement( innerContainer, "div", "eventVisualElement" );
    if( !m_pEvent.Caption )
    {
        divCaption.innerHTML = "";
    }
    else
    {
        divCaption.innerHTML = m_pEvent.Caption;
    }
    
    // if we have a delete callback then create a delete button
    var m_elDeleteLink = null;
    if( pOptions && pOptions.DeleteCallback != null )
    {
        var m_elDeleteLink = CreateChildElement( m_elContainer, "a", "deleteLink" );
        m_elDeleteLink.href = "#";
        m_elDeleteLink.innerHTML = "delete";
        m_elDeleteLink.style.visibility = "hidden";
        m_elDeleteLink.onclick = new Clicker( m_elDeleteLink, pOptions.DeleteCallback, pEvent );
        
        // this is to make space for the delete link
        innerContainer.style.marginRight = "50px";
    }
    
    m_elContainer.onmouseover = function(e)
    {
        e = GetEvent( e );
        if( m_elDeleteLink )
        {
            m_elDeleteLink.style.visibility = "visible";
        }
        
        m_bHovering = true;
        SetStyle();
        return false;
    }
    
    m_elContainer.onmouseout = function(e)
    {
        e = GetEvent( e );
        if( m_elDeleteLink )
        {
            m_elDeleteLink.style.visibility = "hidden";
        }
        
        m_bHovering = false;
        SetStyle();
        return false;
    }


    function SetStyle()
    {        
        if( m_bSelected )
        {
            m_elContainer.className = "eventVisualSelected";
        }
        else if( m_bHovering )
        {
            m_elContainer.className = "eventVisualHover";
        }
        else
        {
            m_elContainer.className = "eventVisual";
        }
    }
    
    this.SetSelected = function( bSelected )
    {
        m_bSelected = bSelected;
        SetStyle();
    }
    
    this.GetContainer = function()
    {
        return m_elContainer;
    }
}

// general viewer for events
function EventViewer(el, pViewer, pOptions)
{
    var m_el = el;
    var m_pViewer = pViewer;
    
    var m_divContents = CreateChildElement( m_el, "div" );
    var m_divScrollPane = null;
    var m_divToggleThumbs = null;
    
    var m_pSelectedItem = null;
    var m_arrTimestamps = null;
    var m_arrVisuals = new Array();
    
    var m_bInitialized = false;
    
    this.RenderContents = function( arrTimestamps )
    {
        // this implies that we will only view notes sorted by time                   
        arrTimestamps.sort( function( a, b ) { return a.Time - b.Time } ); 
                
        m_divContents.innerHTML = "";
        m_arrTimestamps = arrTimestamps;
        
        // clear existing visuals
        m_arrVisuals.splice(0, m_arrVisuals.length);

        // if we don't have any elements, hide the list
        if( m_arrTimestamps.length == 0 )
        {
            SetVisible( m_divContents, false );
            return;
        }
        SetVisible( m_divContents, true );
        
        // create event visuals for our timestamps
        for (var i = 0; i < arrTimestamps.length; i++)
        {
					// modified [20081111 by wmc], added check that caption is not blank
					if (arrTimestamps[i].Caption) {
            var pEventVisual = new EventVisual( m_divContents, arrTimestamps[i], pOptions );
            m_arrVisuals.push(pEventVisual);
            
            if(!g_bIsLiveNotes)
            {
                function eventClick( pItem )
                {
                    m_pViewer.SetVideoPosition( pItem.Time );    
                    m_pViewer.ViewStream( pItem.StreamID );           
                }

                var container = pEventVisual.GetContainer();
                container.onclick = Clicker(container, eventClick, arrTimestamps[i]);
            }
					}
        }
    }

    function SelectItem( pItemToSelect )
    {
        if( pItemToSelect == m_pSelectedItem )
        {
            return;
        }
            
        if( m_pSelectedItem )
        {
            m_pSelectedItem.SetSelected( false );
        }

        m_pSelectedItem = pItemToSelect;        
        ScrollIntoView( m_pSelectedItem );       
        m_pSelectedItem.SetSelected( true );
    }
    
    this.UpdateStatus = function(status)
    {
        if( !m_arrTimestamps )
        {
            return;
        }
        
        var iItem = GetCurrentItem( m_arrTimestamps, status.Time );
        if( iItem < m_arrVisuals.length )
        {
            SelectItem( m_arrVisuals[iItem] );
        }
    }
    
    this.SetVisible = function(bVisible)
    {
        SetVisible(m_el, bVisible);
    }
    
    this.OnResize = function OnResize(controlHeight)
    {
        m_el.style.height = (controlHeight - g_cEventViewerBorderWidth - 1) + "px";
    }

    function ScrollIntoView( pVisual )
    {
        var visHeight = pVisual.GetContainer().offsetHeight;
        var visTop = pVisual.GetContainer().offsetTop;


        var scrollHeight = m_el.offsetHeight


        
        var scroll = Math.max(0, (scrollHeight - visHeight) / 2);
        m_el.scrollTop = visTop - scroll;

    }
}

// Table of Contents (slide & thumbnail events)
function TocViewer(el, pViewer)
{
    var m_el = el;
    
    var m_pEventViewer = new EventViewer(document.getElementById("tocContents"), pViewer );
    
    this.RenderContents = function( arrTimestamps )
    {
        m_pEventViewer.RenderContents(arrTimestamps);
    }
    
    this.UpdateStatus = function(status)
    {
        m_pEventViewer.UpdateStatus(status);
    }
    
    this.SetVisible = function(bVisible)
    {
        SetVisible(m_el, bVisible);
    }
    
    this.SetFocus = function() { }
    
    this.OnResize = function OnResize(controlHeight)
    {
        m_el.style.height = controlHeight + "px";
        
        m_pEventViewer.OnResize( controlHeight - g_cTocTopPadding );
    }
}
