/*@@@**************************************************************************
* \file  mainWindow
* \author Hernan Badino
* \date  Mon Mar  2 17:04:12 Local time zone must be set--see zic manual page 2009
* \notes 
*******************************************************************************
******************************************************************************/

/* INCLUDES */
#include "seqControlDlg.h"

#include <QMessageBox>

using namespace VIC;

CSeqControlDlg::CSeqControlDlg(QWidget *f_parent_p /* = 0 */ )
        : QDialog (                       f_parent_p ),
          m_numFrames_i (                         -1 ),
          m_currentFrame_i (                       1 ),
          m_sliderPressed_b (                   true ),
          m_positionMode_e (         IPM_FIRST_FRAME ),
          m_actionMode_e (               AM_DISABLED ),
          m_deviceType_e (          DT_BIDIRECTIONAL )
{
    setupUi(this); // this sets up GUI

    setWindowTitle( tr("Sequence Control") );
    setObjectName ( windowTitle() );

    m_qlStatus_p -> setText("");

    m_numFrames_i = 100;
    
    m_qsPosition_p -> setValue ( 1 );
    m_qsPosition_p -> setMinimum ( 1 );
    m_qsPosition_p -> setMaximum ( 100 );

    /// So that valueChange events are not emited while the user drags the
    /// slider to different positions. Only when the user releases the slider
    /// the event valueChanged is emitted.
    m_qsPosition_p -> setTracking ( true );
    
    /// Allowing signals to be emited in on_m_qsPosition_p_valueChanged ().
    m_sliderPressed_b = false;

    updateMode ();
}

CSeqControlDlg::~CSeqControlDlg( )
{

}

void CSeqControlDlg::setCurrentFrame( const int f_currentFrame_i )
{
    m_currentFrame_i = f_currentFrame_i;
    
    if ( m_numFrames_i > 0 )
        m_qsPosition_p -> setValue ( f_currentFrame_i );

    updateModeFromSlider();
    updateLabel();
}

void CSeqControlDlg::setNumberOfFrames ( const int f_numFrames_i )
{
    if ( f_numFrames_i > 0 )
        m_qsPosition_p -> setMaximum ( f_numFrames_i );
    else
        m_qsPosition_p -> setMaximum ( 1 );

    m_numFrames_i = f_numFrames_i;

    updateLabel();
}

void CSeqControlDlg::on_m_qsPosition_p_valueChanged ( int /*f_value_i */)
{
    /*
    m_currentFrame_i = f_value_i;    

    if (!m_sliderPressed_b)
    {
        emit goTo(f_value_i);
        updateModeFromSlider();
    }

    updateLabel();
    */
}

/// In this slot we only handle when the user press on the bar changing the 
/// slide to a new position (page change).
void CSeqControlDlg::on_m_qsPosition_p_actionTriggered ( int f_action_i )
{
    if (f_action_i == QAbstractSlider::SliderMove)
        return;

    m_currentFrame_i = m_qsPosition_p -> sliderPosition();
    
    if (!m_sliderPressed_b)
    {
        emit goTo(m_currentFrame_i);
        updateModeFromSlider();
    }

    updateLabel();
}


void CSeqControlDlg::updateModeFromSlider()
{
    if ( m_currentFrame_i < m_numFrames_i && 
         m_currentFrame_i > 1 )
        setPositionMode ( IPM_MIDDLE_FRAME );
    else if ( m_currentFrame_i == 1 )
         setPositionMode ( IPM_FIRST_FRAME );
    else 
        setPositionMode ( IPM_LAST_FRAME );
}

void CSeqControlDlg::updateLabel()
{
    QString qsText;    

    if ( m_numFrames_i > 0 )
    {
        qsText =  ( QString::number(m_currentFrame_i) + "/" + 
                    QString::number(m_numFrames_i) );
    }
    else
    {
        qsText = QString::number(m_currentFrame_i);
    }

    m_qlStatus_p -> setText( qsText );
}

void CSeqControlDlg::on_m_qsPosition_p_sliderReleased ( ) 
{
    m_sliderPressed_b = false;
    m_currentFrame_i = m_qsPosition_p -> sliderPosition();

    emit( goTo( m_currentFrame_i ) ) ;
    updateModeFromSlider();
}

void CSeqControlDlg::updateMode ()
{
    /*
    printf("updating model\n\tactionMode = %s\n"
           "\tdeviceType = %s\n"
           "\tpositionMode = %s\n",
           ( m_actionMode_e == AM_DISABLED?"AM_DISABLED":
             m_actionMode_e == AM_PLAY?"AM_PLAY":
             m_actionMode_e == AM_PLAY_BACKWARD?"AM_PLAY_BACKWARD":
             m_actionMode_e == AM_PAUSE?"AM_PAUSE":"OTHER" ),
           ( m_deviceType_e == DT_BIDIRECTIONAL?"DT_BIDIRECTIONAL":
             m_deviceType_e == DT_FORWARD_ONLY?"DT_FORWARD_ONLY":"OTHER" ),
           ( m_positionMode_e == IPM_FIRST_FRAME?"IPM_FIRST_FRAME":
             m_positionMode_e == IPM_LAST_FRAME?"IPM_LAST_FRAME":
             m_positionMode_e == IPM_LAST_FRAME?"IPM_MIDDLE_FRAME":"OTHER" ) );
    */
    // If disabled, then disable all.
    if ( m_actionMode_e == AM_DISABLED )
    {
        m_qpbStop_p     -> setEnabled ( false );
        m_qpbPause_p    -> setEnabled ( false );
        m_qpbPlay_p     -> setEnabled ( false );
        m_qpbPlayBack_p -> setEnabled ( false );
        m_qpbNext_p     -> setEnabled ( false );
        m_qpbPrev_p     -> setEnabled ( false );
        m_qpbBegin_p    -> setEnabled ( false );
        m_qpbEnd_p      -> setEnabled ( false );

        m_qsPosition_p  -> setValue ( 1 );
        m_qsPosition_p  -> setEnabled ( false );
    }
    else if ( m_positionMode_e == IPM_FIRST_FRAME )
    {
        m_qpbStop_p     -> setEnabled ( true );
        m_qpbPause_p    -> setEnabled ( m_actionMode_e == AM_PLAY ||
                                        m_actionMode_e == AM_PLAY_BACKWARD );

        m_qpbBegin_p    -> setEnabled ( false );
        m_qpbPrev_p     -> setEnabled ( false );
        m_qpbPlayBack_p -> setEnabled ( false ); 

        m_qpbPlay_p     -> setEnabled ( m_numFrames_i != 1 && 
                                        m_actionMode_e != AM_PLAY );
        
        m_qpbNext_p     -> setEnabled ( m_numFrames_i != 1 && 
                                        !( m_actionMode_e == AM_PLAY ||
                                           m_actionMode_e == AM_PLAY_BACKWARD ) );
        m_qpbEnd_p      -> setEnabled ( m_numFrames_i != 1 );

        if ( m_deviceType_e == DT_BIDIRECTIONAL && m_numFrames_i != 1 )
        {
            m_qsPosition_p -> setValue ( 1 );
            m_currentFrame_i = 1;
            updateLabel();
        }
        m_qsPosition_p  -> setEnabled ( true );
    }
    else if ( m_positionMode_e == IPM_LAST_FRAME )
    {
        m_qpbStop_p     -> setEnabled ( true );
        m_qpbPause_p    -> setEnabled ( m_actionMode_e == AM_PLAY ||
                                        m_actionMode_e == AM_PLAY_BACKWARD );

        m_qpbPlay_p     -> setEnabled ( m_actionMode_e != AM_PLAY );
        m_qpbNext_p     -> setEnabled ( false );
        m_qpbEnd_p      -> setEnabled ( false );

        const bool enableBack_b = ( m_deviceType_e == DT_BIDIRECTIONAL && 
                                    m_numFrames_i != 1 );

        m_qpbBegin_p    -> setEnabled ( enableBack_b );
        m_qpbPrev_p     -> setEnabled ( enableBack_b && 
                                        !( m_actionMode_e == AM_PLAY ||
                                           m_actionMode_e == AM_PLAY_BACKWARD ) );
        m_qpbPlayBack_p -> setEnabled ( enableBack_b && 
                                        m_actionMode_e != AM_PLAY_BACKWARD ); 
 
        if ( enableBack_b )
        {
            m_qsPosition_p -> setValue ( m_numFrames_i );
            m_currentFrame_i = m_numFrames_i;
            updateLabel();
        }
        m_qsPosition_p  -> setEnabled ( true );
    }
    else if ( m_positionMode_e == IPM_MIDDLE_FRAME )
    {
        m_qpbStop_p     -> setEnabled ( true );
        m_qpbPause_p    -> setEnabled ( m_actionMode_e == AM_PLAY ||
                                        m_actionMode_e == AM_PLAY_BACKWARD );
        
        m_qpbPlay_p     -> setEnabled ( m_numFrames_i  != 1 &&
                                        m_actionMode_e != AM_PLAY );

        m_qpbNext_p     -> setEnabled ( m_numFrames_i != 1 && 
                                        !( m_actionMode_e == AM_PLAY ||
                                           m_actionMode_e == AM_PLAY_BACKWARD ));

        m_qpbEnd_p      -> setEnabled ( m_numFrames_i != 1 );

        const bool enableBack_b = ( m_deviceType_e == DT_BIDIRECTIONAL && 
                                    m_numFrames_i != 1 );

        m_qpbPrev_p     -> setEnabled ( enableBack_b  && 
                                        !( m_actionMode_e == AM_PLAY ||
                                           m_actionMode_e == AM_PLAY_BACKWARD ));
        m_qpbPlayBack_p -> setEnabled ( enableBack_b && 
                                        m_actionMode_e != AM_PLAY_BACKWARD );
        m_qpbBegin_p    -> setEnabled ( enableBack_b );

        m_qsPosition_p  -> setEnabled ( true );
    }
}

void CSeqControlDlg::setPositionMode ( const EFramePositionMode_t f_newMode_e )
{
    //if (f_newMode_e == m_positionMode_e)
    //    return;

    m_positionMode_e = f_newMode_e;
    
    updateMode();
}

void CSeqControlDlg::setActionMode ( const EActionMode_t f_newMode_e )
{
    if ( f_newMode_e == m_actionMode_e )
        return;

    m_actionMode_e  = f_newMode_e;
    
    updateMode();
}


void CSeqControlDlg::setDeviceType ( const EDeviceType_t f_newType_e )
{
    if ( f_newType_e == m_deviceType_e )
        return;

    m_deviceType_e = f_newType_e;

    updateMode();
}

/* ////////////  Version History ///////////////
 *  $Log: seqControlDlg.cpp,v $
 *  Revision 1.3  2010/01/18 17:12:29  badino
 *  General updates and added new classes.
 *
 *  Revision 1.2  2009/11/18 15:50:15  badino
 *  badino: global changes.
 *
 *//////////////////////////////////////////////
