void ManageViewScreen::Show()
{
    m_ScreenMgr->SetUpdateFlag( true );

    MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
    if( main )
    {
        VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

        m_ViewportSizeXValue.Set( glwin->pixel_w() );
        m_ViewportSizeYValue.Set( glwin->pixel_h() );

        double factor = glwin->pixel_w()/glwin->w();

        //===== Set current COR =====//
        glm::vec3 currentCOR = glwin->getCOR();
        m_CORXValue.Set( currentCOR.x );
        m_CORYValue.Set( currentCOR.y );
        m_CORZValue.Set( currentCOR.z );

        glm::vec2 currentPan = glwin->getPanValues();
        m_PanXPosValue.Set( currentPan.x );
        m_PanYPosValue.Set( currentPan.y );

        m_ZoomValue.Set( glwin->getRelativeZoomValue() );
        m_Zoom.Update( m_ZoomValue.GetID() );

        UpdateRotations();

        m_windowDX = main->GetFlWindow()->w() - m_ViewportSizeXValue.Get()/factor;
        m_windowDY = main->GetFlWindow()->h() - m_ViewportSizeYValue.Get()/factor;
    }

    m_FLTK_Window->show();
}
// Callback for Link Browser
void ManageBackgroundScreen::CallBack( Fl_Widget* w )
{
    assert( m_ScreenMgr );

    MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
    if( !main )
    {
        return;
    }

    VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

    VSPGraphic::Viewport * viewport = glwin->getGraphicEngine()->getDisplay()->getViewport();
    if( !viewport )
    {
        return;
    }

    if ( w == colorChooser )
    {
        viewport->getBackground()->setRed( ( float )( colorChooser->r() ) );
        viewport->getBackground()->setGreen( ( float )( colorChooser->g() ) );
        viewport->getBackground()->setBlue( ( float )( colorChooser->b() ) );
    }

    m_ScreenMgr->SetUpdateFlag( true );
}
bool ManageBackgroundScreen::Update()
{
    MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
    if( !main )
    {
        return false;
    }

    VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

    VSPGraphic::Viewport * viewport = glwin->getGraphicEngine()->getDisplay()->getViewport();
    if( !viewport )
    {
        return false;
    }

    VSPGraphic::Common::VSPenum mode = viewport->getBackground()->getBackgroundMode();
    if ( mode == VSPGraphic::Common::VSP_BACKGROUND_COLOR )
    {
        m_ColorLayout.GetGroup()->activate();
        m_ImageLayout.GetGroup()->deactivate();
    }
    else
    {
        m_ColorLayout.GetGroup()->deactivate();
        m_ImageLayout.GetGroup()->activate();
    }

    if ( m_PreserveAspect.GetFlButton()->value() )
    {
        m_PreserveAspectLayout.GetGroup()->deactivate();
    }
    else
    {
        m_PreserveAspectLayout.GetGroup()->activate();
    }

    //Update Scale and Offset in Background
    m_WScale.Update( m_WidthScaleValue.GetID() );
    m_HScale.Update( m_HeightScaleValue.GetID() );

    viewport->getBackground()->scaleW( (float) m_WidthScaleValue.Get() );
    if (m_PreserveAspect.GetFlButton()->value())
    {
        m_HeightScaleValue.Set( viewport->getBackground()->getScaleH() );
    }
    else
    {
        viewport->getBackground()->scaleH( (float) m_HeightScaleValue.Get() );
    }

    m_XOffset.Update( m_XOffsetValue.GetID() );
    m_YOffset.Update( m_YOffsetValue.GetID() );

    viewport->getBackground()->offsetX( (float) m_XOffsetValue.Get() );
    viewport->getBackground()->offsetY( (float) m_YOffsetValue.Get() );

    m_FLTK_Window->redraw();
    return false;
}
void ManageViewScreen::UpdateZoom()
{
    MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
    if( main )
    {
        VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

        m_ZoomValue.Set( glwin->getRelativeZoomValue() );
        m_Zoom.Update( m_ZoomValue.GetID() );
    }
}
void ManageViewScreen::UpdateViewport()
{
    MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
    if( main )
    {
        m_ViewportSizeXValue.Set( main->GetGLWindow()->pixel_w() );
        m_ViewportSizeYValue.Set( main->GetGLWindow()->pixel_h() );

        m_ViewportSizeX.Update( m_ViewportSizeXValue.GetID() );
        m_ViewportSizeY.Update( m_ViewportSizeYValue.GetID() );
    }
}
void ManageViewScreen::UpdatePan()
{
    MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
    if( main )
    {
        VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

        glm::vec2 currentPan = glwin->getPanValues();
        m_PanXPosValue.Set( currentPan.x );
        m_PanYPosValue.Set( currentPan.y );

        m_PanXPos.Update( m_PanXPosValue.GetID() );
        m_PanYPos.Update( m_PanYPosValue.GetID() );
    }
}
//===== Attempt at Euler Angle Rotation =====//
void ManageViewScreen::UpdateRotations()
{
    MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
    if( main )
    {
        VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

        glm::vec3 eulerValues = glwin->getRotationEulerAngles();

        m_XRotationValue.Set( eulerValues[0] * ( 180.0 / M_PI ) );
        m_YRotationValue.Set( eulerValues[1] * ( 180.0 / M_PI ) );
        m_ZRotationValue.Set( eulerValues[2] * ( 180.0 / M_PI ) );

        m_XRotation.Update( m_XRotationValue.GetID() );
        m_YRotation.Update( m_YRotationValue.GetID() );
        m_ZRotation.Update( m_ZRotationValue.GetID() );
    }
}
void ManageViewScreen::UpdateCOR()
{
    MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
    if( main )
    {
        VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

        glm::vec3 center = glwin->getCOR();

        m_CORXValue.Set( center.x );
        m_CORYValue.Set( center.y );
        m_CORZValue.Set( center.z );

        m_CORX.Update( m_CORXValue.GetID() );
        m_CORY.Update( m_CORYValue.GetID() );
        m_CORZ.Update( m_CORZValue.GetID() );
    }
}
// Callback for all other GUI Devices
void ManageViewScreen::GuiDeviceCallBack( GuiDevice* device )
{
    assert( m_ScreenMgr );

    //===== Trigger Buttons =====//
    if ( device == &m_SetDefaultViewportSize )
    {
        MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
        if( main )
        {
            VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

            m_ViewportSizeXValue.Set( glwin->getGraphicEngine()->getDisplay()->getDefaultGlWindowWidth( ) );
            m_ViewportSizeYValue.Set( glwin->getGraphicEngine()->getDisplay()->getDefaultGlWindowHeight( ) );
        }
    }
    else if ( device == &m_PickLookAtBtn )
    {
        ManageCORScreen* corScreen = dynamic_cast<ManageCORScreen *>
        ( m_ScreenMgr->GetScreen( ScreenMgr::VSP_COR_SCREEN ) );
        if( corScreen )
        {
            corScreen->EnableSelection();
        }
    }
    else if ( device == &m_ResetOriginLookAtBtn )
    {
        m_CORXValue.Set( 0.0 );
        m_CORYValue.Set( 0.0 );
        m_CORZValue.Set( 0.0 );

        m_CORX.Update( m_CORXValue.GetID() );
        m_CORY.Update( m_CORYValue.GetID() );
        m_CORZ.Update( m_CORZValue.GetID() );

        MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
        if( main )
        {
            VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

            glwin->setCOR( glm::vec3( m_CORXValue.Get(), m_CORYValue.Get(), m_CORZValue.Get() ) );
        }
    }
    else if ( device == &m_ResetCamera )
    {
        //===== Reset the values to default =====//
        m_PanXPosValue.Set( 0.0 );
        m_PanYPosValue.Set( 0.0 );

        m_ZoomValue.Set( 0.018 );

        m_XRotationValue.Set( 0.0 );
        m_YRotationValue.Set( 0.0 );
        m_ZRotationValue.Set( 0.0 );

        //===== Update The Values =====//
        m_PanXPos.Update( m_PanXPosValue.GetID() );
        m_PanYPos.Update( m_PanYPosValue.GetID() );

        m_Zoom.Update( m_ZoomValue.GetID() );

        m_XRotation.Update( m_XRotationValue.GetID() );
        m_YRotation.Update( m_YRotationValue.GetID() );
        m_ZRotation.Update( m_ZRotationValue.GetID() );
    }

    m_ScreenMgr->SetUpdateFlag( true );
}
bool ManageViewScreen::Update()
{
    MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
    if( !main )
    {
        return false;
    }

    VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

    double factor = glwin->pixel_w()/glwin->w();

    // Added padding to screen
    if (m_ViewportSizeXValue.Get()/factor > Fl::w() - 10)
    {
        m_ViewportSizeXValue.Set( (Fl::w() - 10) * factor );
    }
    if (m_ViewportSizeYValue.Get()/factor > Fl::h() - 10)
    {
        m_ViewportSizeYValue.Set( (Fl::h() - 10) * factor );
    }

    Vehicle *veh = VehicleMgr.GetVehicle();
    if ( veh )
    {
        m_AxisLenSlider.Update( veh->m_AxisLength.GetID() );
        m_TextSizeSlider.Update( veh->m_TextSize.GetID() );
    }

    m_ViewportSizeX.Update( m_ViewportSizeXValue.GetID() );
    m_ViewportSizeY.Update( m_ViewportSizeYValue.GetID() );

    m_CORX.Update( m_CORXValue.GetID() );
    m_CORY.Update( m_CORYValue.GetID() );
    m_CORZ.Update( m_CORZValue.GetID() );

    m_PanXPos.Update( m_PanXPosValue.GetID() );
    m_PanYPos.Update( m_PanYPosValue.GetID() );

    m_Zoom.Update( m_ZoomValue.GetID() );

    //===== Euler Attempt =====//
    m_XRotation.Update( m_XRotationValue.GetID() );
    m_YRotation.Update( m_YRotationValue.GetID() );
    m_ZRotation.Update( m_ZRotationValue.GetID() );

    //===== Do glwin functions here after the updates of the sliders =====//

    // Resize Viewport and window to your maximum screen size. Achieves any ratio.
    main->ResizeWindow( m_ViewportSizeXValue.Get()/factor + m_windowDX, m_ViewportSizeYValue.Get()/factor + m_windowDY );

    //===== Update Center of Rotation =====//
    glwin->setCOR( glm::vec3( m_CORXValue.Get(), m_CORYValue.Get(), m_CORZValue.Get() ) );

    glwin->relativePan( m_PanXPosValue.Get(), m_PanYPosValue.Get() );

    glwin->relativeZoom( m_ZoomValue.Get() );

    //===== LookAt Point Method =====//
    glwin->rotateSphere( m_XRotationValue.Get() * ( M_PI / 180.0 ),
                         m_YRotationValue.Get() * ( M_PI / 180.0 ),
                         m_ZRotationValue.Get() * ( M_PI / 180.0 ) );

    m_FLTK_Window->redraw();
    return false;
}
// Callback for all other GUI Devices
void ManageBackgroundScreen::GuiDeviceCallBack( GuiDevice* device )
{
    assert( m_ScreenMgr );

    MainVSPScreen* main = dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );
    if( !main )
    {
        return;
    }

    VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

    VSPGraphic::Viewport * viewport = glwin->getGraphicEngine()->getDisplay()->getViewport();
    if( !viewport )
    {
        return;
    }

    if ( device == &m_Color )
    {
        m_Color.GetFlButton()->value( 1 );
        m_Image.GetFlButton()->value( 0 );
        viewport->getBackground()->removeImage();
        viewport->getBackground()->setBackgroundMode( VSPGraphic::Common::VSP_BACKGROUND_COLOR );
    }
    else if ( device == &m_Image )
    {
        m_Color.GetFlButton()->value( 0 );
        m_Image.GetFlButton()->value( 1 );
        viewport->getBackground()->setBackgroundMode( VSPGraphic::Common::VSP_BACKGROUND_IMAGE );

        if ( m_ImageFile.compare( "" ) != 0 )
        {
            viewport->getBackground()->attachImage( VSPGraphic::GlobalTextureRepo()->get2DTexture( m_ImageFile.c_str() ) );
        }
    }
    else if ( device == &m_FileSelect )
    {
        std::string fileName = m_ScreenMgr->GetSelectFileScreen()->FileChooser(
                "Select Image File", "*.{jpg,png,tga,bmp,gif}", false );

        if( !fileName.empty() )
        {
            viewport->getBackground()->removeImage();
            viewport->getBackground()->attachImage( VSPGraphic::GlobalTextureRepo()->get2DTexture( fileName.c_str() ) );
            m_ImageFile = fileName;
            m_FileOutput.Update( truncateFileName( fileName, 40 ).c_str() );
        }
    }
    else if ( device == &m_PreserveAspect )
    {
        if ( m_PreserveAspect.GetFlButton()->value() == 1 )
        {
            viewport->getBackground()->preserveAR( true );
        }
        else
        {
            viewport->getBackground()->preserveAR( false );
        }
    }
    else if ( device == &m_ResetDefaults )
    {
        viewport->getBackground()->reset();
        colorChooser->rgb( viewport->getBackground()->getRed(), viewport->getBackground()->getGreen(),
                           viewport->getBackground()->getBlue() );
        m_FileOutput.Update("");
        m_ImageFile = "";

        //Reset Scale & Offset
        m_WidthScaleValue.Set( viewport->getBackground()->getScaleW() );
        m_HeightScaleValue.Set( viewport->getBackground()->getScaleH() );

        m_XOffsetValue.Set( viewport->getBackground()->getOffsetX() );
        m_YOffsetValue.Set( viewport->getBackground()->getOffsetY() );
    }

    m_ScreenMgr->SetUpdateFlag( true );
}
void ManageViewScreen::CallBack( Fl_Widget * w )
{
    MainVSPScreen * main =
        dynamic_cast<MainVSPScreen*>( m_ScreenMgr->GetScreen( m_ScreenMgr->VSP_MAIN_SCREEN ) );

    if( !main )
    {
        return;
    }

    VSPGUI::VspGlWindow * glwin = main->GetGLWindow();

    if( w == m_ViewUI->xPosMinus1 )
    {
        glwin->pan( -1, 0, true );
    }
    else if( w == m_ViewUI->xPosMinus2 )
    {
        glwin->pan( -1, 0, false );
    }
    else if( w == m_ViewUI->xPosPlus1 )
    {
        glwin->pan( 1, 0, true );
    }
    else if( w == m_ViewUI->xPosPlus2 )
    {
        glwin->pan( 1, 0, false );
    }
    else if( w == m_ViewUI->yPosMinus1 )
    {
        glwin->pan( 0, -1, true );
    }
    else if( w == m_ViewUI->yPosMinus2 )
    {
        glwin->pan( 0, -1, false );
    }
    else if( w == m_ViewUI->yPosPlus1 )
    {
        glwin->pan( 0, 1, true );
    }
    else if( w == m_ViewUI->yPosPlus2 )
    {
        glwin->pan( 0, 1, false );
    }
    else if( w == m_ViewUI->zoomMinus1 )
    {
        glwin->zoom( 1, true );
    }
    else if( w == m_ViewUI->zoomMinus2 )
    {
        glwin->zoom( 1, false );
    }
    else if( w == m_ViewUI->zoomPlus1 )
    {
        glwin->zoom( -1, true );
    }
    else if( w == m_ViewUI->zoomPlus2 )
    {
        glwin->zoom( -1, false );
    }
    m_ScreenMgr->SetUpdateFlag( true );
}