
#include <Qt>
#include <QtGui>
#include <QGLWidget>

#include "displayWidget.h"
#include "display.h"
#include "drawingListHandler.h"
#include "displayTreeDlg.h"
#include "displayTreeNode.h"

using namespace VIC;

CDisplayWidget::CDisplayWidget( QWidget *              f_parent_p,
                                CDrawingListHandler *  f_handler_p )
        : QWidget (                      f_parent_p ),
          m_drawingListHandler_p (      f_handler_p ),
          m_treeDlg_p (                        NULL ),
          m_glDisplay_p (                      NULL ),
          m_grabbing_b (                      false ),

          m_qfTopControls_p (                  NULL ),
          m_qpbAction1_p (                     NULL ),
          m_qpbAction2_p (                     NULL ),
          m_qpbAction3_p (                     NULL ),
          m_qfNumScreens_p (                   NULL ),
          m_qlabel1_p (                        NULL ),
          m_qsbNumHorScreens_p (               NULL ),
          m_qsbNumVertScreens_p (              NULL ),
          m_qfStatusBar_p (                    NULL ),
          m_qStatusBarSplitter_p (             NULL ),
          m_qlUserMessage_p (                  NULL ),
          m_qlSystemMessage_p (                NULL )
{
    setWindowTitle(tr("Main Display"));
    setObjectName(windowTitle());

    if (m_drawingListHandler_p)
    {
        createForm();        
        
        m_treeDlg_p = new CDisplayTreeDlg ( this,
                                            m_glDisplay_p,
                                            m_drawingListHandler_p -> getRootNode() );
        
        connect( m_glDisplay_p, SIGNAL(fullScreenSwitched ( )), 
                 this,          SLOT(  switchFullScreen ( )));

        connect( m_glDisplay_p, SIGNAL(exitFullScreen ( )), 
                 this,          SLOT(  exitFullScreen ( )));

        connect( m_glDisplay_p, SIGNAL(keyPressed ( CKeyEvent *)), 
                 this,          SLOT(  keyPressed ( CKeyEvent *)));

        connect( m_glDisplay_p, SIGNAL(mouseMoved ( CMouseEvent *)),
                 this,          SLOT(  mouseMoved ( CMouseEvent *)));

    }
}

void CDisplayWidget::createForm()
{
    /// Main layout
    QGridLayout *gridLayout_p = new QGridLayout(this);
    m_qfTopControls_p = new QFrame(this);

    QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);

    /// Size policy top control.
    sizePolicy.setHorizontalStretch(0);
    sizePolicy.setVerticalStretch(0);
    sizePolicy.setHeightForWidth(m_qfTopControls_p->sizePolicy().hasHeightForWidth());
 
    m_qfTopControls_p->setSizePolicy(sizePolicy);
    m_qfTopControls_p->setFrameShape(QFrame::StyledPanel);
    m_qfTopControls_p->setFrameShadow(QFrame::Raised);

    /// Grid layout for top controls.
    QGridLayout *layoutTopCtrls_p = new QGridLayout(m_qfTopControls_p);
    m_qpbAction1_p = new QPushButton(m_qfTopControls_p);

    /// Size policy for top control buttons.
    QSizePolicy sizePolicy1(QSizePolicy::Maximum, QSizePolicy::Maximum);

    sizePolicy1.setHorizontalStretch(0);
    sizePolicy1.setVerticalStretch(0);
    sizePolicy1.setHeightForWidth(m_qpbAction1_p->sizePolicy().hasHeightForWidth());
 
    /// Button action1.
    m_qpbAction1_p->setSizePolicy(sizePolicy1);
    m_qpbAction1_p->setMinimumSize(QSize(41, 41));
    m_qpbAction1_p->setMaximumSize(QSize(41, 41));

    layoutTopCtrls_p->addWidget(m_qpbAction1_p, 0, 0, 1, 1);

    m_qpbAction2_p = new QPushButton(m_qfTopControls_p);

    sizePolicy1.setHeightForWidth(m_qpbAction2_p->sizePolicy().hasHeightForWidth());

    /// Button action2.
    m_qpbAction2_p->setSizePolicy(sizePolicy1);
    m_qpbAction2_p->setMinimumSize(QSize(41, 41));
    m_qpbAction2_p->setMaximumSize(QSize(41, 41));

    layoutTopCtrls_p->addWidget(m_qpbAction2_p, 0, 1, 1, 1);

    m_qpbAction3_p = new QPushButton(m_qfTopControls_p);

    sizePolicy1.setHeightForWidth(m_qpbAction3_p->sizePolicy().hasHeightForWidth());

    /// Button action3.
    m_qpbAction3_p->setSizePolicy(sizePolicy1);
    m_qpbAction3_p->setMinimumSize(QSize(41, 41));
    m_qpbAction3_p->setMaximumSize(QSize(41, 41));

    layoutTopCtrls_p->addWidget(m_qpbAction3_p, 0, 2, 1, 1);

    /// Horizontal spacer.
    QSpacerItem * horizontalSpacer_p = new QSpacerItem(407, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

    layoutTopCtrls_p->addItem(horizontalSpacer_p, 0, 3, 1, 1);

    /// Line Edits for selecting number of screens.
    m_qfNumScreens_p = new QFrame(m_qfTopControls_p);
    QSizePolicy sizePolicy2(QSizePolicy::Fixed, QSizePolicy::Fixed);

    /// Size policy for frame containing spin boxes.
    sizePolicy2.setHorizontalStretch(0);
    sizePolicy2.setVerticalStretch(0);
    sizePolicy2.setHeightForWidth(m_qfNumScreens_p->sizePolicy().hasHeightForWidth());

    m_qfNumScreens_p->setSizePolicy(sizePolicy2);
    m_qfNumScreens_p->setMinimumSize(QSize(100, 40));
    m_qfNumScreens_p->setMaximumSize(QSize(100, 40));
    m_qfNumScreens_p->setFrameShape(QFrame::NoFrame);
    m_qfNumScreens_p->setFrameShadow(QFrame::Raised);

    /// "X" label
    m_qlabel1_p = new QLabel(m_qfNumScreens_p);
    m_qlabel1_p->setGeometry(QRect(45, 10, 16, 19));
    sizePolicy1.setHeightForWidth(m_qlabel1_p->sizePolicy().hasHeightForWidth());
    m_qlabel1_p->setSizePolicy(sizePolicy1);

    /// Spin boxes.
    m_qsbNumHorScreens_p = new QSpinBox(m_qfNumScreens_p);
    m_qsbNumHorScreens_p->setGeometry(QRect(0, 0, 41, 31));
    m_qsbNumHorScreens_p->setMinimum(1);
    m_qsbNumHorScreens_p->setMaximum(6);

    m_qsbNumVertScreens_p = new QSpinBox(m_qfNumScreens_p);
    m_qsbNumVertScreens_p->setGeometry(QRect(60, 0, 41, 31));
    m_qsbNumVertScreens_p->setMinimum(1);
    m_qsbNumVertScreens_p->setMaximum(6);
    
    /// Add to the layout of the top controls.
    layoutTopCtrls_p->addWidget(m_qfNumScreens_p, 0, 4, 1, 1);
    
    
    gridLayout_p->addWidget(m_qfTopControls_p, 0, 0, 1, 1);

    /// Main Display
    m_glDisplay_p = new CDisplay ( m_drawingListHandler_p -> getRootNode(), this );

    QSizePolicy sizePolicy3(QSizePolicy::Expanding, QSizePolicy::Expanding);
    sizePolicy3.setHorizontalStretch(0);
    sizePolicy3.setVerticalStretch(0);
    sizePolicy3.setHeightForWidth(m_glDisplay_p->sizePolicy().hasHeightForWidth());
    m_glDisplay_p->setSizePolicy(sizePolicy3);

    gridLayout_p->addWidget(m_glDisplay_p, 1, 0, 1, 1);

    /// Status bar
    m_qfStatusBar_p = new QFrame(this);

    QSizePolicy sizePolicy4(QSizePolicy::Expanding, QSizePolicy::Fixed);
    sizePolicy4.setHorizontalStretch(0);
    sizePolicy4.setVerticalStretch(0);
    sizePolicy4.setHeightForWidth(m_qfStatusBar_p->sizePolicy().hasHeightForWidth());

    m_qfStatusBar_p->setSizePolicy(sizePolicy4);
    m_qfStatusBar_p->setFrameShape(QFrame::StyledPanel);
    m_qfStatusBar_p->setFrameShadow(QFrame::Raised);

    m_qfStatusBar_p->setMaximumSize(QSize(16777215, 33));

    QHBoxLayout * horLayout_p = new QHBoxLayout(m_qfStatusBar_p);

    m_qStatusBarSplitter_p = new QSplitter(m_qfStatusBar_p);
    m_qStatusBarSplitter_p->setOrientation(Qt::Horizontal);

    m_qlUserMessage_p = new QLabel(m_qStatusBarSplitter_p);

    //sizePolicy4.setHeightForWidth(m_qlUserMessage_p->sizePolicy().hasHeightForWidth());

    m_qlUserMessage_p->setSizePolicy(sizePolicy4);
    m_qlUserMessage_p->setMaximumSize(QSize(16777215, 16777215));

    m_qStatusBarSplitter_p->addWidget(m_qlUserMessage_p);

    m_qlSystemMessage_p = new QLabel(m_qStatusBarSplitter_p);

    //sizePolicy4.setHeightForWidth(m_qlSystemMessage_p->sizePolicy().hasHeightForWidth());
    m_qlSystemMessage_p->setSizePolicy(sizePolicy4);
    m_qlSystemMessage_p->setMaximumSize(QSize(16777215, 16777215));

    m_qStatusBarSplitter_p->addWidget(m_qlSystemMessage_p);

    horLayout_p->addWidget(m_qStatusBarSplitter_p);

    gridLayout_p->addWidget(m_qfStatusBar_p, 2, 0, 1, 1);

    m_qpbAction1_p->setText(QString());
    m_qpbAction2_p->setText(QString());
    m_qpbAction3_p->setText(QString());
    m_qlabel1_p->setText("X");
}


QWidget * CDisplayWidget::getDialog() const
{
    return m_treeDlg_p;
}

CDisplay * CDisplayWidget::getDisplay() const
{
    return m_glDisplay_p;
}

void CDisplayWidget::update ( int f_forceUpdate_b )
{
    if ( f_forceUpdate_b ||
         m_drawingListHandler_p -> mustUpdateDisplay ( ) )
    {
        update();
    }
}

void CDisplayWidget::update()
{
    //printf("Setting visible\n");
    
    //m_glDisplay_p -> setVisible(true);
    //printf("Updating GL\n");
    m_glDisplay_p -> updateGL();
    
    QWidget::update();

    m_drawingListHandler_p -> setDisplayUpdateFlag ( false );

    if (m_grabbing_b)
    {
        static int imgNr_i = 0;
        QImage saveImage = m_glDisplay_p -> renderGL();
        
        char fileName[256];
        
        sprintf(fileName, "grabbedDisplayWidgetImg_%05i.png", imgNr_i );
    
        saveImage.save( fileName );        

        printf("imgNr_i = %i\n", imgNr_i);
        ++imgNr_i;
    }
}

void CDisplayWidget::switchFullScreen ()
{
    static Qt::WindowStates prevState;
    if ( not isInFSMode() )
    {
        prevState = m_glDisplay_p -> windowState ();

        m_glDisplay_p -> setParent ( 0 );
        m_glDisplay_p -> setWindowState ( Qt::WindowStates(Qt::WindowFullScreen | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint) );
        m_glDisplay_p -> show();
    }
    else
    {
        m_glDisplay_p -> setParent ( this );
        m_glDisplay_p -> setWindowState (prevState);
        layout()->addWidget(m_glDisplay_p);
    }
}

void CDisplayWidget::exitFullScreen ()
{
    if ( isInFSMode() )
        switchFullScreen();
}

void
CDisplayWidget::keyPressed ( CKeyEvent * f_keyEvent_p )
{
    if (f_keyEvent_p -> qtKeyEvent_p -> key() == Qt::Key_S)
    {
        m_grabbing_b = !m_grabbing_b;
    }
    
}

void
CDisplayWidget::mouseMoved ( CMouseEvent *  f_event_p )
{
    char str[4096];

    snprintf(str, 4096, "Screen [%i,%i] - Abs Pos [%7.2f,%7.2f] - Scr Pos [%7.2f,%7.2f]\n",
             f_event_p->displayScreen.x,
             f_event_p->displayScreen.y,
             f_event_p->posInDisplay.x,
             f_event_p->posInDisplay.y,
             f_event_p->posInScreen.x,
             f_event_p->posInScreen.y );

    m_qlSystemMessage_p -> setText( str );    
}



/* ////////////  Version History ///////////////
 *  $Log: displayWidget.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.
 *
 *//////////////////////////////////////////////
