//-----------------------------------------------------------------------------
#ifndef WizardQuickSetupH
#define WizardQuickSetupH WizardQuickSetupH
//-----------------------------------------------------------------------------
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire_GenICam.h>
#include "ValuesFromUserDlg.h"
#include "spinctld.h"
#include "PropViewFrame.h"

class wxCheckBox;
class wxSlider;
class wxTextCtrl;
class wxToggleButton;

//-----------------------------------------------------------------------------
class WizardQuickSetup : public OkAndCancelDlg
//-----------------------------------------------------------------------------
{
    DECLARE_EVENT_TABLE()

private:
    ////////////////////////////MEMBER VARIABLES///////////////////////////////////

    //-----------------------------------------------------------------------------
    enum TWidgetIDs_QuickSetup
    //-----------------------------------------------------------------------------
    {
        widMainFrame = wxID_HIGHEST,
        widBtnPresetColor,
        widBtnPresetGrey,
        widBtnPresetCustom,
        widBtnPresetFactory,
        widSLExposure,
        widSCExposure,
        widBtnExposureAuto,
        widSLGain,
        widSCGain,
        widBtnGainAuto,
        widSLBlackLevel,
        widSCBlackLevel,
        widBtnGamma,
        widSLSaturation,
        widSCSaturation,
        widBtnCCM,
        widSLWhiteBalanceR,
        widSCWhiteBalanceR,
        widSLWhiteBalanceB,
        widSCWhiteBalanceB,
        widBtnWhiteBalanceAuto,
        widSLFrameRate,
        widSCFrameRate,
        widBtnFrameRateAuto,
        widCBShowDialogAtStartup
    };

    //-----------------------------------------------------------------------------
    enum TWhiteBalanceChannel
    //-----------------------------------------------------------------------------
    {
        wbcRed,
        wbcBlue
    };

    //-----------------------------------------------------------------------------
    struct DeviceSettings
            //-----------------------------------------------------------------------------
    {
        double                          exposureTime;
        bool                            boAutoExposureEnabled;
        double                          unifiedGain;
        bool                            boAutoGainEnabled;
        double                          unifiedBlackLevel;
        bool                            boGammaEnabled;
        double                          whiteBalanceRed;
        double                          whiteBalanceBlue;
        bool                            boAutoWhiteBalanceEnabled;
        double                          saturation;
        bool                            boCCMEnabled;
        double                          frameRate;
        bool                            boAutoFrameRateEnabled;

        double                          analogGainMin;
        double                          analogGainMax;
        double                          digitalGainMin;
        double                          digitalGainMax;
        double                          analogBlackLevelMin;
        double                          analogBlackLevelMax;
        double                          digitalBlackLevelMin;
        double                          digitalBlackLevelMax;

        bool                            boColorEnabled;
        std::string                     imageFormatControlPixelFormat;
        std::string                     imageDestinationPixelFormat;
    };

    //-----------------------------------------------------------------------------
    struct SupportedWizardFeatures
            //-----------------------------------------------------------------------------
    {
        bool                            boAutoExposureSupport;
        bool                            boAutoGainSupport;
        bool                            boAutoWhiteBalanceSupport;
        bool                            boAutoFrameRateSupport;
        bool                            boColorOptionsSupport;
    };

    //----------------------------------STATICS------------------------------------
    static const double                 GAMMA_;
    static const double                 SLIDER_GRANULARITY_;
    static const double                 GAMMA_CORRECTION_VALUE_;

    //----------------------------------GUI ELEMENTS-------------------------------
    wxBoxSizer*                         pTopDownSizer_;
    wxButton*                           pBtnPresetColor_;
    wxButton*                           pBtnPresetCustom_;
    wxButton*                           pBtnPresetFactory_;
    wxButton*                           pBtnPresetGrey_;
    wxSlider*                           pSLExposure_;
    wxSpinCtrlDbl*                      pSCExposure_;
    wxToggleButton*                     pBtnExposureAuto_;
    wxSlider*                           pSLGain_;
    wxSpinCtrlDbl*                      pSCGain_;
    wxToggleButton*                     pBtnGainAuto_;
    wxSlider*                           pSLBlackLevel_;
    wxSpinCtrlDbl*                      pSCBlackLevel_;
    wxToggleButton*                     pBtnGamma_;
    wxSlider*                           pSLWhiteBalanceR_;
    wxSpinCtrlDbl*                      pSCWhiteBalanceR_;
    wxSlider*                           pSLWhiteBalanceB_;
    wxSpinCtrlDbl*                      pSCWhiteBalanceB_;
    wxToggleButton*                     pBtnWhiteBalanceAuto_;
    wxSlider*                           pSLSaturation_;
    wxSpinCtrlDbl*                      pSCSaturation_;
    wxToggleButton*                     pBtnCCM_;
    wxSlider*                           pSLFrameRate_;
    wxSpinCtrlDbl*                      pSCFrameRate_;
    wxToggleButton*                     pBtnFrameRateAuto_;
    wxCheckBox*                         pCBShowDialogAtStartup_;

    //----------------------------------HELPER VARIABLES-----------------------------
    bool                                boGUILocked_;

    double                              analogGainMin_;
    double                              analogGainMax_;
    double                              digitalGainMin_;
    double                              digitalGainMax_;
    double                              analogBlackLevelMin_;
    double                              analogBlackLevelMax_;
    double                              digitalBlackLevelMin_;
    double                              digitalBlackLevelMax_;

    std::string                         currentDeviceSerial_;
    std::map<std::string, DeviceSettings> currentSettings_;
    std::map<std::string, DeviceSettings> propGridSettings_;
    std::map<std::string, SupportedWizardFeatures> featuresSupported_;
    PropViewFrame*                      pParentPropViewFrame_;

    Device*                             pDev_;
    GenICam::AcquisitionControl*        pAcC_;
    GenICam::AnalogControl*             pAnC_;
    GenICam::ImageFormatControl*        pIFC_;
    GenICam::TransportLayerControl*     pTCL_;
    GenICam::UserSetControl*            pUSC_;
    ImageDestination*                   pID_;
    ImageProcessing*                    pIP_;


    ////////////////////////////////////METHODS////////////////////////////////////
    //----------------------------------GENERAL------------------------------------
    void                                AnalyzeDeviceAndGatherInformation( SupportedWizardFeatures& wizardSupportedFeatures );
    void                                CleanUp( void );
    void                                CloseDlg( void );
    virtual void                        OnClose( wxCloseEvent& );
    void                                QueryInitialDeviceSettings( DeviceSettings& settings );
    void                                PresetColorHQ( void );
    void                                PresetGreyHQ( void );
    void                                RefreshControls( void );
    void                                SelectColorPixelFormat( void );
    void                                SelectGreyscalePixelFormat( void );
    void                                SelectLUTDependingOnPixelFormat( void );
    void                                SetAcquisitionFrameRateLimitMode( void );
    void                                SetupControls( void );
    void                                SetupDevice( void );
    void                                SetupDriverSettings( void );
    void                                SetupFrameRateControls( void );
    void                                SetupUnifiedAnalogControlData( bool newDevice );
    bool                                ShowFactoryResetPopup( void );
    void                                UpdateExposureControlsFromCamera( void );
    void                                UpdateGainControlsFromCamera( void );
    void                                UpdateWhiteBalanceControlsFromCamera( void );
    inline void                         WritePropOnOff( Property& p, bool boOn );

public:
    explicit                            WizardQuickSetup( PropViewFrame* pParent, const wxString& title, bool boShowAtStartup );
    void                                ReferToNewDevice( Device* pDev );
    void                                RestoreWizardConfiguration( void );
    void                                SaveWizardConfiguration( void );
    void                                ShowImageTimeoutPopup( void );
    void                                UpdateControlsData( void );
    bool                                MustShowAtStartup( void ) const
    {
        return pCBShowDialogAtStartup_->IsChecked();
    }

private:
    //----------------------------------EXPOSURE-----------------------------------
    void                                ApplyExposure( void );
    void                                ConfigureExposureAuto( bool boActive );
    double                              ExposureFromSliderValue( void ) const;
    int                                 ExposureToSliderValue( const double exposure ) const;
    void                                HandleExposureSpinControlChanges( void );

    //----------------------------------GAIN---------------------------------------
    void                                ApplyGain( void );
    void                                ConfigureGainAuto( bool boActive );
    void                                HandleGainSpinControlChanges( void );
    double                              ReadUnifiedGainData( void );
    void                                WriteUnifiedGainData( double unifiedGain );

    //----------------------------------BLACKLEVEL---------------------------------
    void                                ApplyBlackLevel( void );
    void                                ConfigureGamma( bool boActive );
    void                                HandleBlackLevelSpinControlChanges( void );
    double                              ReadUnifiedBlackLevelData( void );
    void                                WriteUnifiedBlackLevelData( double unifiedBlackLevel );

    //----------------------------------WHITEBALANCE-------------------------------
    void                                ApplyWhiteBalance( TWhiteBalanceChannel channel );
    void                                ConfigureWhiteBalanceAuto( bool boActive );
    void                                HandleWhiteBalanceRSpinControlChanges( void );
    void                                HandleWhiteBalanceBSpinControlChanges( void );

    //----------------------------------SATURATION--------------------------------
    void                                ApplySaturation( void );
    void                                ConfigureCCM( bool boActive );
    void                                HandleSaturationSpinControlChanges( void );
    double                              ReadSaturationData( void );
    void                                WriteSaturationData( double saturation );

    //----------------------------------FRAMERATE---------------------------------
    void                                ApplyFrameRate( void );
    void                                ConfigureFrameRateAuto( bool boActive );
    void                                HandleFrameRateSpinControlChanges( void );

    //----------------------------------BUTTONS------------------------------------
    void                                OnBtnPresetColor( wxCommandEvent& e );
    void                                OnBtnPresetCustom( wxCommandEvent& e );
    void                                OnBtnPresetFactory( wxCommandEvent& e );
    void                                OnBtnPresetGrey( wxCommandEvent& e );

    void                                OnBtnExposureAuto( wxCommandEvent& e )
    {
        ConfigureExposureAuto( e.IsChecked() );
        RefreshControls();
    }
    void                                OnBtnGainAuto( wxCommandEvent& e )
    {
        ConfigureGainAuto( e.IsChecked() );
        RefreshControls();
    }
    void                                OnBtnGamma( wxCommandEvent& e )
    {
        ConfigureGamma( e.IsChecked() );
        RefreshControls();
    }
    void                                OnBtnCCM( wxCommandEvent& e )
    {
        ConfigureCCM( e.IsChecked() );
        RefreshControls();
    }
    void                                OnBtnWhiteBalanceAuto( wxCommandEvent& e )
    {
        ConfigureWhiteBalanceAuto( e.IsChecked() );
        RefreshControls();
    }
    void                                OnBtnFrameRateAuto( wxCommandEvent& e )
    {
        ConfigureFrameRateAuto( e.IsChecked() );
        RefreshControls();
    }

    virtual void                        OnBtnCancel( wxCommandEvent& );
    virtual void                        OnBtnOk( wxCommandEvent& );

    //----------------------------------SPINCONTROLS--------------------------------
    void                                OnSCExposureChanged( wxSpinEvent& )
    {
        HandleExposureSpinControlChanges();
    }
    void                                OnSCGainChanged( wxSpinEvent& )
    {
        HandleGainSpinControlChanges();
    }
    void                                OnSCBlackLevelChanged( wxSpinEvent& )
    {
        HandleBlackLevelSpinControlChanges();
    }
    void                                OnSCWhiteBalanceRChanged( wxSpinEvent& )
    {
        HandleWhiteBalanceRSpinControlChanges();
    }
    void                                OnSCWhiteBalanceBChanged( wxSpinEvent& )
    {
        HandleWhiteBalanceBSpinControlChanges();
    }
    void                                OnSCSaturationChanged( wxSpinEvent& )
    {
        HandleSaturationSpinControlChanges();
    }
    void                                OnSCFrameRateChanged( wxSpinEvent& )
    {
        HandleFrameRateSpinControlChanges();
    }

    //----------------------------------TEXTCONTROLS--------------------------------
    void                                OnSCExposureTextChanged( wxCommandEvent& )
    {
        HandleExposureSpinControlChanges();
    }
    void                                OnSCGainTextChanged( wxCommandEvent& )
    {
        HandleGainSpinControlChanges();
    }
    void                                OnSCBlackLevelTextChanged( wxCommandEvent& )
    {
        HandleBlackLevelSpinControlChanges();
    }
    void                                OnSCWhiteBalanceRTextChanged( wxCommandEvent& )
    {
        HandleWhiteBalanceRSpinControlChanges();
    }
    void                                OnSCWhiteBalanceBTextChanged( wxCommandEvent& )
    {
        HandleWhiteBalanceBSpinControlChanges();
    }
    void                                OnSCSaturationTextChanged( wxCommandEvent& )
    {
        HandleSaturationSpinControlChanges();
    }
    void                                OnSCFrameRateTextChanged( wxCommandEvent& )
    {
        HandleFrameRateSpinControlChanges();
    }

    //----------------------------------SLIDERS-------------------------------------
    void                                OnSLExposure( wxScrollEvent& e );
    void                                OnSLGain( wxScrollEvent& e );
    void                                OnSLBlackLevel( wxScrollEvent& e );
    void                                OnSLWhiteBalanceR( wxScrollEvent& e );
    void                                OnSLWhiteBalanceB( wxScrollEvent& e );
    void                                OnSLSaturation( wxScrollEvent& e );
    void                                OnSLFrameRate( wxScrollEvent& e );
};

#endif // WizardQuickSetupH
