//**************************************************************************************************
//                                        DlgNgsCfgSrc.hpp                                         *
//                                       ------------------                                        *
// Started     : 2005-05-13                                                                        *
// Last Update : 2015-08-10                                                                        *
// Copyright   : (C) 2005-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 "DlgNgsCfgSrc.hpp"

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

wxBEGIN_EVENT_TABLE( DlgNgsCfgSrc, wxDialog )

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

wxEND_EVENT_TABLE( )

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

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

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

DlgNgsCfgSrc::~DlgNgsCfgSrc( )
{
}

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

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

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

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

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

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

  // Create the Sinusoid panel controls
  m_oPnlSinAmp   .bCreate( poPnlSine, ID_PNL_SIN_AMP   , iWdName, iWdValue, iWdUnits );
  m_oPnlSinFreq  .bCreate( poPnlSine, ID_PNL_SIN_FREQ  , iWdName, iWdValue, iWdUnits );
  m_oPnlSinOffset.bCreate( poPnlSine, ID_PNL_SIN_OFFSET, iWdName, iWdValue, iWdUnits );
  m_oPnlSinDelay .bCreate( poPnlSine, ID_PNL_SIN_DELAY , iWdName, iWdValue, iWdUnits );
  m_oPnlSinDamp  .bCreate( poPnlSine, ID_PNL_SIN_DAMP  , iWdName, iWdValue, iWdUnits );

  m_oPnlSinAmp   .bSetName( wxT("Amplitude")      );
  m_oPnlSinFreq  .bSetName( wxT("Frequency")      );
  m_oPnlSinOffset.bSetName( wxT("DC Offset")      );
  m_oPnlSinDelay .bSetName( wxT("Initial Delay")  );
  m_oPnlSinDamp  .bSetName( wxT("Damping Factor") );

  m_oPnlSinAmp   .bSetUnitsType( eUNITS_VOLT );
  m_oPnlSinFreq  .bSetUnitsType( eUNITS_FREQ );
  m_oPnlSinOffset.bSetUnitsType( eUNITS_VOLT );
  m_oPnlSinDelay .bSetUnitsType( eUNITS_TIME );
  m_oPnlSinDamp  .bShowUnits( PnlValue::eSHOW_LBL );

  // Create the Pulse panel controls
  m_oPnlPulInitial.bCreate( poPnlPulse, ID_PNL_PUL_INITV , iWdName, iWdValue, iWdUnits );
  m_oPnlPulMax    .bCreate( poPnlPulse, ID_PNL_PUL_MAXV  , 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_oPnlPulMax    .bSetName( wxT("Pulsed Value")  );
  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_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 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  DlgNgsCfgSrc::ToolTips( void )
{
  m_oPnlSinAmp    .SetToolTip( wxT("The amplitude of the sinusoidal signal") );
  m_oPnlSinFreq   .SetToolTip( wxT("The frequency of the sinusoidal signal") );
  m_oPnlSinOffset .SetToolTip( wxT("The DC offset of the sinusoidal signal") );
  m_oPnlSinDelay  .SetToolTip( wxT("The initial delay of the sinusoidal signal") );
  m_oPnlSinDamp   .SetToolTip( wxT("The damping factor of the sinusoidal signal") );

  m_oPnlPulInitial.SetToolTip( wxT("The initial value of the pulse source") );
  m_oPnlPulMax    .SetToolTip( wxT("The maximum value of each pulse") );
  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  DlgNgsCfgSrc::DoLayout( void )
{
  wxBoxSizer  * poSzrDlg;
  wxPanel     * poPnlSine, * poPnlPulse, * poPnlBtns;
  wxBoxSizer  * poSzrSine, * poSzrPulse, * poSzrBtns;
  wxSizerFlags  oFlags;

  // Get pointers to the various panels
  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   );
  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   );
  poPnlSine ->SetSizer( poSzrSine  );
  poPnlPulse->SetSizer( poSzrPulse );
  poPnlBtns ->SetSizer( poSzrBtns  );

  // Layout the Sinusoid  panel
  oFlags.Align( wxALIGN_LEFT );
  oFlags.Border( wxTOP | wxLEFT | wxRIGHT, 10 );
  poSzrSine->Add( &m_oPnlSinAmp   , oFlags );
  oFlags.Border( wxLEFT | wxRIGHT        , 10 );
  poSzrSine->Add( &m_oPnlSinFreq  , oFlags );
  poSzrSine->Add( &m_oPnlSinOffset, oFlags );
  poSzrSine->Add( &m_oPnlSinDelay , oFlags );
  oFlags.Border( wxLEFT | wxBOTTOM       , 10 );
  poSzrSine->Add( &m_oPnlSinDamp  , oFlags );

  // Layout the Pulse panel
  oFlags.Border( wxTOP | wxLEFT | wxRIGHT, 10 );
  poSzrPulse->Add( &m_oPnlPulInitial, oFlags );
  oFlags.Border( wxLEFT | wxRIGHT        , 10 );
  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( poPnlSine , oFlags );
  oFlags.Border( wxALL                   , 15 );
  poSzrDlg->Add( poPnlPulse, oFlags );
  oFlags.Align( wxALIGN_CENTER );
  oFlags.Border( wxBOTTOM                , 15 );
  poSzrDlg->Add( poPnlBtns , oFlags );

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

//**************************************************************************************************
// Set the values in the value panel controls.
//
// Argument List :
//   roCpntSrc - A reference to an independent source component object

void  DlgNgsCfgSrc::SetValues( CpntNgsIndSrc & roCpntSrc )
{
  SetEvtHandlerEnabled( false );

  m_oPnlSinAmp    .bSetValue( roCpntSrc.m_osSinAmp     );
  m_oPnlSinFreq   .bSetValue( roCpntSrc.m_osSinFreq    );
  m_oPnlSinOffset .bSetValue( roCpntSrc.m_osSinOffset  );
  m_oPnlSinDelay  .bSetValue( roCpntSrc.m_osSinDelay   );
  m_oPnlSinDamp   .bSetValue( roCpntSrc.m_osSinDamp    );

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

  SetEvtHandlerEnabled( true );
}

//**************************************************************************************************
// Get the values from the value panel controls.
//
// Argument List :
//   roCpntSrc - A reference to an independent source component object

void  DlgNgsCfgSrc::GetValues( CpntNgsIndSrc & roCpntSrc )
{
  SetEvtHandlerEnabled( false );

  roCpntSrc.m_osSinAmp     = m_oPnlSinAmp    .rosGetValue( );
  roCpntSrc.m_osSinFreq    = m_oPnlSinFreq   .rosGetValue( );
  roCpntSrc.m_osSinOffset  = m_oPnlSinOffset .rosGetValue( );
  roCpntSrc.m_osSinDelay   = m_oPnlSinDelay  .rosGetValue( );
  roCpntSrc.m_osSinDamp    = m_oPnlSinDamp   .rosGetValue( );

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

  SetEvtHandlerEnabled( true );
}

//**************************************************************************************************
// Set the source component name.
//
// Argument List :
//   rosName - The name of the source component
//
// Return Values :
//   true  - Success
//   false - Failure

bool  DlgNgsCfgSrc::bSetName( wxString & rosName )
{
  eTypeCpnt  eCpnt;

  eCpnt = Component::eGetType( rosName );
  if( eCpnt!=eCPNT_IVS && eCpnt!=eCPNT_ICS ) return( false );

  m_oCpntIndSrc.bSetName( rosName );

  return( true );
}

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

bool  DlgNgsCfgSrc::bClear( void )
{
  m_oCpntIndSrc.bClear( );

  SetValues( m_oCpntIndSrc );

  return( true );
}

//**************************************************************************************************
// Set the values in the value panel controls.
//
// Argument List :
//   roCpntSrc - A reference to an independent source component object
//
// Return Values :
//   true  - Success
//   false - Failure

bool  DlgNgsCfgSrc::bSetValues( CpntNgsIndSrc & roCpntSrc )
{
  SetValues( roCpntSrc );
  m_oCpntIndSrc = roCpntSrc;

  return( true );
}

//**************************************************************************************************
// Get the values from the value panel controls.
//
// Argument List :
//   roCpntSrc - A reference to an independent source component object
//
// Return Values :
//   true  - Success
//   false - Failure

bool  DlgNgsCfgSrc::bGetValues( CpntNgsIndSrc & roCpntSrc )
{
  GetValues( roCpntSrc );

  return( true );
}

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

void  DlgNgsCfgSrc::OnBtnOk( wxCommandEvent & roEvtCmd )
{
  GetValues( m_oCpntIndSrc );
  EndModal( wxID_OK );
}

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

void  DlgNgsCfgSrc::OnBtnClear( wxCommandEvent & roEvtCmd )
{
  CpntNgsIndSrc  oCpntIndSrc;

  oCpntIndSrc.bClear( );
  SetValues( oCpntIndSrc );
}

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

void  DlgNgsCfgSrc::OnBtnCancel( wxCommandEvent & roEvtCmd )
{
  SetValues( m_oCpntIndSrc );
  EndModal( wxID_CANCEL );
}

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