//**************************************************************************************************
//                                        DlgGcpCfgGEN.cpp                                         *
//                                       ------------------                                        *
// Started     : 2004-02-27                                                                        *
// Last Update : 2016-03-21                                                                        *
// Copyright   : (C) 2004-2016 MSWaters                                                            *
//**************************************************************************************************

//**************************************************************************************************
//                                                                                                 *
//      This program is free software; you can redistribute it and/or modify it under the          *
//      terms of the GNU General Public License as published by the Free Software Foundation;      *
//      either version 3 of the License, or (at your option) any later version.                    *
//                                                                                                 *
//**************************************************************************************************

#include "DlgGcpCfgGEN.hpp"

//**************************************************************************************************
// Implement an event table.

wxBEGIN_EVENT_TABLE( DlgGcpCfgGEN, wxDialog )

  EVT_BUTTON( ID_BTN_OK,     DlgGcpCfgGEN::OnBtnOk     )
  EVT_BUTTON( ID_BTN_CLEAR,  DlgGcpCfgGEN::OnBtnClear  )
  EVT_BUTTON( ID_BTN_CANCEL, DlgGcpCfgGEN::OnBtnCancel )

wxEND_EVENT_TABLE( )

//**************************************************************************************************
// Constructor.
//
// Argument List :
//   poWin - A pointer to the dialog parent window

DlgGcpCfgGEN::DlgGcpCfgGEN( wxWindow * poWin ) :
                wxDialog( poWin, -1, wxT(""), wxDefaultPosition, wxDefaultSize,
                          wxDEFAULT_DIALOG_STYLE, wxDialogNameStr )
{
  SetTitle( wxT("Generator Setup") );
  Initialize( );
  bClear( );
}

//**************************************************************************************************
// Destructor.

DlgGcpCfgGEN::~DlgGcpCfgGEN( )
{
}

//**************************************************************************************************
// Initialize object attributes.

void  DlgGcpCfgGEN::Initialize( void )
{
  // Call all the initialization functions
  Create( );
  ToolTips( );

  // Layout the of the display objects
  DoLayout( );
}

//**************************************************************************************************
// Create the display objects.

void  DlgGcpCfgGEN::Create( void )
{
  wxPanel * poPnlOvrAll, * poPnlSine, * poPnlPulse, * poPnlBtns;
  int       iWdName=115, iWdValue=95, iWdUnits=75;

  // Create the various underlying panel objects
  poPnlOvrAll = new wxPanel( this );
  poPnlSine   = new wxPanel( this );
  poPnlPulse  = new wxPanel( this );
  poPnlBtns   = new wxPanel( this );

  // Create the overall panel and controls
  m_oPnlAmplitude.bCreate( poPnlOvrAll, ID_PNL_AMPLITUDE, iWdName, iWdValue, iWdUnits );
  m_oPnlOffset   .bCreate( poPnlOvrAll, ID_PNL_OFFSET,    iWdName, iWdValue, iWdUnits );

  m_oPnlAmplitude.bSetName( wxT("Amplitude") );
  m_oPnlOffset   .bSetName( wxT("DC Offset") );

  m_oPnlAmplitude.bSetUnitsType( eUNITS_VOLT );
  m_oPnlOffset   .bSetUnitsType( eUNITS_VOLT );

  // Create the sine wave panel and controls
  m_oPnlSinFreq .bCreate( poPnlSine, ID_PNL_SIN_FREQ,  iWdName, iWdValue, iWdUnits );
  m_oPnlSinPhase.bCreate( poPnlSine, ID_PNL_SIN_PHASE, iWdName, iWdValue, iWdUnits );

  m_oPnlSinFreq .bSetName( wxT("Frequency")     );
  m_oPnlSinPhase.bSetName( wxT("Initial Phase") );

  m_oPnlSinFreq .bSetUnitsType( eUNITS_FREQ  );
  m_oPnlSinPhase.bSetUnitsType( eUNITS_PHAD );

  m_oPnlSinFreq .bSetSpnRange( 0.0, 1000.0 );
  m_oPnlSinFreq .bSetUnits( wxT("Hz") );

  m_oPnlSinPhase.bShowUnits( PnlValue::eSHOW_LBL );
  m_oPnlSinPhase.bSetUnits( wxT("Degree") );

  // Create the pulse panel and controls
  m_oPnlPulInitial.bCreate( poPnlPulse, ID_PNL_PUL_INITIAL, iWdName, iWdValue, iWdUnits );
  m_oPnlPulMin    .bCreate( poPnlPulse, ID_PNL_PUL_MIN,     iWdName, iWdValue, iWdUnits );
  m_oPnlPulMax    .bCreate( poPnlPulse, ID_PNL_PUL_MAX,     iWdName, iWdValue, iWdUnits );
  m_oPnlPulDelay  .bCreate( poPnlPulse, ID_PNL_PUL_DELAY,   iWdName, iWdValue, iWdUnits );
  m_oPnlPulRise   .bCreate( poPnlPulse, ID_PNL_PUL_RISE,    iWdName, iWdValue, iWdUnits );
  m_oPnlPulWidth  .bCreate( poPnlPulse, ID_PNL_PUL_WIDTH,   iWdName, iWdValue, iWdUnits );
  m_oPnlPulFall   .bCreate( poPnlPulse, ID_PNL_PUL_FALL,    iWdName, iWdValue, iWdUnits );
  m_oPnlPulPeriod .bCreate( poPnlPulse, ID_PNL_PUL_PERIOD,  iWdName, iWdValue, iWdUnits );

  m_oPnlPulInitial.bSetName( wxT("Initial Value") );
  m_oPnlPulMin    .bSetName( wxT("Min Level")     );
  m_oPnlPulMax    .bSetName( wxT("Max Level")     );
  m_oPnlPulDelay  .bSetName( wxT("Initial Delay") );
  m_oPnlPulRise   .bSetName( wxT("Rise Time")     );
  m_oPnlPulWidth  .bSetName( wxT("Pulse Width")   );
  m_oPnlPulFall   .bSetName( wxT("Fall Time")     );
  m_oPnlPulPeriod .bSetName( wxT("Period")        );

  m_oPnlPulInitial.bSetUnitsType( eUNITS_VOLT );
  m_oPnlPulMin    .bSetUnitsType( eUNITS_VOLT );
  m_oPnlPulMax    .bSetUnitsType( eUNITS_VOLT );
  m_oPnlPulDelay  .bSetUnitsType( eUNITS_TIME );
  m_oPnlPulRise   .bSetUnitsType( eUNITS_TIME );
  m_oPnlPulWidth  .bSetUnitsType( eUNITS_TIME );
  m_oPnlPulFall   .bSetUnitsType( eUNITS_TIME );
  m_oPnlPulPeriod .bSetUnitsType( eUNITS_TIME );

  // Create the buttons panel and the button controls
  m_oBtnOk    .Create( poPnlBtns, ID_BTN_OK    , wxT("OK")     );
  m_oBtnClear .Create( poPnlBtns, ID_BTN_CLEAR , wxT("Clear")  );
  m_oBtnCancel.Create( poPnlBtns, ID_BTN_CANCEL, wxT("Cancel") );
}

//**************************************************************************************************
// Initialize the tool tips.

void  DlgGcpCfgGEN::ToolTips( void )
{
  m_oPnlAmplitude .SetToolTip( wxT("The overall amplitude of the sine wave and the pulse train") );
  m_oPnlOffset    .SetToolTip( wxT("The DC offset applied to the entire signal") );

  m_oPnlSinFreq   .SetToolTip( wxT("The frequency of the sine wave generator for a Transient analysis") );
  m_oPnlSinPhase  .SetToolTip( wxT("The phase of the sine wave at startup") );

  m_oPnlPulInitial.SetToolTip( wxT("The initial value of the source") );
  m_oPnlPulMin    .SetToolTip( wxT("The 'OFF' value for the pulse train") );
  m_oPnlPulMax    .SetToolTip( wxT("The 'ON' value for the pulse train") );
  m_oPnlPulDelay  .SetToolTip( wxT("The time until the first pulse") );
  m_oPnlPulRise   .SetToolTip( wxT("The time taken to go from 0 to the pulsed value") );
  m_oPnlPulWidth  .SetToolTip( wxT("The width of each pulse") );
  m_oPnlPulFall   .SetToolTip( wxT("The time taken to go from the pulsed value to 0") );
  m_oPnlPulPeriod .SetToolTip( wxT("The period of the pulse train") );
}

//**************************************************************************************************
// Layout the dialog display objects.

void  DlgGcpCfgGEN::DoLayout( void )
{
  wxBoxSizer  * poSzrDlg;
  wxPanel     * poPnlOvrAll, * poPnlSine, * poPnlPulse, * poPnlBtns;
  wxBoxSizer  * poSzrOvrAll, * poSzrSine, * poSzrPulse, * poSzrBtns;
  wxSizerFlags  oFlags;

  // Get pointers to the various panels
  poPnlOvrAll = (wxPanel *) m_oPnlAmplitude .GetParent( );
  poPnlSine   = (wxPanel *) m_oPnlSinFreq   .GetParent( );
  poPnlPulse  = (wxPanel *) m_oPnlPulInitial.GetParent( );
  poPnlBtns   = (wxPanel *) m_oBtnOk        .GetParent( );

  // Create sizers to associate with the panels
  poSzrDlg    = new wxBoxSizer      ( wxVERTICAL   );
  poSzrOvrAll = new wxStaticBoxSizer( wxVERTICAL, poPnlOvrAll, wxT(" Overall ")  );
  poSzrSine   = new wxStaticBoxSizer( wxVERTICAL, poPnlSine  , wxT(" Sinusoid ") );
  poSzrPulse  = new wxStaticBoxSizer( wxVERTICAL, poPnlPulse , wxT(" Pulse ")    );
  poSzrBtns   = new wxBoxSizer      ( wxHORIZONTAL );

  // Set the sizers to the panels
               SetSizer( poSzrDlg    );
  poPnlOvrAll->SetSizer( poSzrOvrAll );
  poPnlSine  ->SetSizer( poSzrSine   );
  poPnlPulse ->SetSizer( poSzrPulse  );
  poPnlBtns  ->SetSizer( poSzrBtns   );

  // Layout the Overall panel
  oFlags.Align( wxALIGN_LEFT );
  oFlags.Border( wxTOP | wxLEFT | wxRIGHT, 10 );
  poSzrOvrAll->Add( &m_oPnlAmplitude, oFlags );
  oFlags.Border( wxLEFT | wxBOTTOM       , 10 );
  poSzrOvrAll->Add( &m_oPnlOffset   , oFlags );

  // Layout the Sinusoid panel
  oFlags.Border( wxTOP | wxLEFT | wxRIGHT, 10 );
  poSzrSine->Add( &m_oPnlSinFreq , oFlags );
  oFlags.Border( wxLEFT | wxBOTTOM       , 10 );
  poSzrSine->Add( &m_oPnlSinPhase, oFlags );

  // Layout the Pulse panel
  oFlags.Border( wxTOP | wxLEFT | wxRIGHT, 10 );
  poSzrPulse->Add( &m_oPnlPulInitial, oFlags );
  oFlags.Border( wxLEFT | wxRIGHT        , 10 );
  poSzrPulse->Add( &m_oPnlPulMin    , oFlags );
  poSzrPulse->Add( &m_oPnlPulMax    , oFlags );
  poSzrPulse->Add( &m_oPnlPulDelay  , oFlags );
  poSzrPulse->Add( &m_oPnlPulRise   , oFlags );
  poSzrPulse->Add( &m_oPnlPulWidth  , oFlags );
  poSzrPulse->Add( &m_oPnlPulFall   , oFlags );
  oFlags.Border( wxLEFT | wxBOTTOM       , 10 );
  poSzrPulse->Add( &m_oPnlPulPeriod , oFlags );

  // Layout the button panel
  oFlags.Align( wxALIGN_RIGHT  );
  oFlags.Border( wxTOP | wxBOTTOM, 10 );
  poSzrBtns->Add( &m_oBtnOk    , oFlags );
  poSzrBtns->AddSpacer( 10 );
  oFlags.Align( wxALIGN_CENTER );
  poSzrBtns->Add( &m_oBtnClear , oFlags );
  poSzrBtns->AddSpacer( 10 );
  oFlags.Align( wxALIGN_LEFT   );
  poSzrBtns->Add( &m_oBtnCancel, oFlags );

  // Layout the underlying dialog
  oFlags.Align( wxALIGN_CENTER );
  oFlags.Border( wxTOP | wxLEFT | wxRIGHT, 15 );
  poSzrDlg->Add( poPnlOvrAll, oFlags );
  poSzrDlg->Add( poPnlSine  , oFlags );
  oFlags.Border( wxALL                   , 15 );
  poSzrDlg->Add( poPnlPulse , oFlags );
  oFlags.Border( wxBOTTOM                , 15 );
  poSzrDlg->Add( poPnlBtns  , oFlags );

  // Set dialogues minimum size and initial size as calculated by the sizer
  poSzrOvrAll->SetSizeHints( poPnlOvrAll );
  poSzrSine  ->SetSizeHints( poPnlSine   );
  poSzrPulse ->SetSizeHints( poPnlPulse  );
  poSzrBtns  ->SetSizeHints( poPnlBtns   );
  poSzrDlg   ->SetSizeHints( this        );
}

//**************************************************************************************************
// Set the values in the value panel controls.
//
// Argument List :
//   roCmdGEN - A reference to a GENERATOR command object

void  DlgGcpCfgGEN::SetValues( CmdGnuCapGEN & roCmdGEN )
{
  SetEvtHandlerEnabled( false );

  m_oPnlAmplitude .bSetValue( roCmdGEN.m_osAmplitude  );
  m_oPnlOffset    .bSetValue( roCmdGEN.m_osOffset     );

  m_oPnlSinFreq   .bSetValue( roCmdGEN.m_osSinFreq    );
  m_oPnlSinPhase  .bSetValue( roCmdGEN.m_osSinPhase   );

  m_oPnlPulInitial.bSetValue( roCmdGEN.m_osPulInitial );
  m_oPnlPulMin    .bSetValue( roCmdGEN.m_osPulMin     );
  m_oPnlPulMax    .bSetValue( roCmdGEN.m_osPulMax     );
  m_oPnlPulDelay  .bSetValue( roCmdGEN.m_osPulDelay   );
  m_oPnlPulRise   .bSetValue( roCmdGEN.m_osPulRise    );
  m_oPnlPulWidth  .bSetValue( roCmdGEN.m_osPulWidth   );
  m_oPnlPulFall   .bSetValue( roCmdGEN.m_osPulFall    );
  m_oPnlPulPeriod .bSetValue( roCmdGEN.m_osPulPeriod  );

  SetEvtHandlerEnabled( true );
}

//**************************************************************************************************
// Get the values from the value panel controls.
//
// Argument List :
//   roCmdGEN - A reference to a GENERATOR command object

void  DlgGcpCfgGEN::GetValues( CmdGnuCapGEN & roCmdGEN )
{
  SetEvtHandlerEnabled( false );

  roCmdGEN.m_osAmplitude  = m_oPnlAmplitude .rosGetValue( );
  roCmdGEN.m_osOffset     = m_oPnlOffset    .rosGetValue( );

  roCmdGEN.m_osSinFreq    = m_oPnlSinFreq   .rosGetValue( );
  roCmdGEN.m_osSinPhase   = m_oPnlSinPhase  .rosGetValue( );

  roCmdGEN.m_osPulInitial = m_oPnlPulInitial.rosGetValue( );
  roCmdGEN.m_osPulMin     = m_oPnlPulMin    .rosGetValue( );
  roCmdGEN.m_osPulMax     = m_oPnlPulMax    .rosGetValue( );
  roCmdGEN.m_osPulDelay   = m_oPnlPulDelay  .rosGetValue( );
  roCmdGEN.m_osPulRise    = m_oPnlPulRise   .rosGetValue( );
  roCmdGEN.m_osPulWidth   = m_oPnlPulWidth  .rosGetValue( );
  roCmdGEN.m_osPulFall    = m_oPnlPulFall   .rosGetValue( );
  roCmdGEN.m_osPulPeriod  = m_oPnlPulPeriod .rosGetValue( );

  roCmdGEN.bFormat( );

  SetEvtHandlerEnabled( true );
}

//**************************************************************************************************
// Reset all dialog settings to defaults.
//
// Return Values :
//   true  - Success
//   false - Failure

bool  DlgGcpCfgGEN::bClear( void )
{
  m_oCmdGEN.bSetDefaults( );

  SetValues( m_oCmdGEN );

  return( true );
}

//**************************************************************************************************
// Set the values in the value panel controls.
//
// Argument List :
//   roCmdGEN - A reference to a GENERATOR command object
//
// Return Values :
//   true  - Success
//   false - Failure

bool  DlgGcpCfgGEN::bSetValues( CmdGnuCapGEN & roCmdGEN )
{
  SetValues( roCmdGEN );
  m_oCmdGEN = roCmdGEN;

  return( true );
}

//**************************************************************************************************
// Get the values from the value panel controls.
//
// Argument List :
//   roCmdGEN - A reference to a GENERATOR command object
//
// Return Values :
//   true  - Success
//   false - Failure

bool  DlgGcpCfgGEN::bGetValues( CmdGnuCapGEN & roCmdGEN )
{
  GetValues( roCmdGEN );

  return( true );
}

//**************************************************************************************************
//                                         Event Handlers                                          *
//**************************************************************************************************
// OK button event handler.
//
// Argument List :
//   roEvtCmd - An object holding information about the event (not used)

void  DlgGcpCfgGEN::OnBtnOk( wxCommandEvent & roEvtCmd )
{
  GetValues( m_oCmdGEN );
  EndModal( wxID_OK );
}

//**************************************************************************************************
// Clear button event handler.
//
// Argument List :
//   roEvtCmd - An object holding information about the event (not used)

void  DlgGcpCfgGEN::OnBtnClear( wxCommandEvent & roEvtCmd )
{
  CmdGnuCapGEN  oCmdGEN;

  oCmdGEN.bSetDefaults( );
  SetValues( oCmdGEN );
}

//**************************************************************************************************
// Cancel button event handler.
//
// Argument List :
//   roEvtCmd - An object holding information about the event (not used)

void  DlgGcpCfgGEN::OnBtnCancel( wxCommandEvent & roEvtCmd )
{
  SetValues( m_oCmdGEN );
  EndModal( wxID_CANCEL );
}

//**************************************************************************************************
