//**************************************************************************************************
//                                        PnlNgSpiceTR.cpp                                         *
//                                       ------------------                                        *
// Started     : 2004-08-05                                                                        *
// Last Update : 2018-10-20                                                                        *
// Copyright   : (C) 2004-2018 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 "PnlNgSpiceTR.hpp"

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

wxBEGIN_EVENT_TABLE( PnlNgSpiceTR, PnlAnaBase )

  EVT_CHOICE( PnlAnaBase  ::ID_CHO_SRCNAME, PnlNgSpiceTR::OnSrcName  )
  EVT_BUTTON( PnlNgSpiceTR::ID_BTN_SETUP  , PnlNgSpiceTR::OnBtnSetup )

wxEND_EVENT_TABLE( )

//**************************************************************************************************
// Constructor.

PnlNgSpiceTR::PnlNgSpiceTR( wxWindow * poWin ) : PnlAnaBase( poWin ), m_oDlgCfgSrc( poWin )
{
  bSetAnalysType( eCMD_TR );  // Set the analysis panel type
  Create( );                  // Create the analysis panel
  bClear( );                  // Clear all object attributes
}

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

PnlNgSpiceTR::~PnlNgSpiceTR( )
{
}

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

void  PnlNgSpiceTR::Create( void )
{
  PnlAnaBase::CreateBase( );    // Create the base controls
  PnlAnaBase::CreateInitC( );   // Create the initial condtns controls
  PnlAnaBase::CreateTemp( );    // Create the analysis temperature controls
  PnlAnaBase::CreateSigSrc( );  // Create the input signal source controls
              CreateSigSrc( );  // Create the additional input signal source controls

#ifdef LAYOUT_MNGR
  PnlAnaBase::DoLayout( );      // Layout the panel's GUI objects
#endif // LAYOUT_MNGR

  // The following block of code is required to circumvent a bug in wxWidgets. All declared wxChoice
  // controls attempt a clear( ) operation in their destructor whether or not thay have actually
  // been created. Causes a null pointer warning. ??? 2018-10-20
  m_oPnlSrcLvl.bCreate( m_oChoSrcName.GetParent( ), ID_PNL_SRCLVL, -1, 95, 82 );
  m_oPnlSrcLvl.Hide( );

  // Set the time sweep parameter labels
#ifdef LAYOUT_MNGR
  bSetSwpParsLbl( wxT("Time Sweep") );
#else
  m_oSbxSwpPars.SetLabel( wxT(" Time Sweep ") );
#endif // LAYOUT_MNGR
  m_oPnlStart  .bSetName( wxT("Start Time") );
  m_oPnlStop   .bSetName( wxT("Stop Time") );
  m_oPnlStep   .bSetName( wxT("Step Increment") );

  // Set sweep parameter units
  m_oPnlStart.bSetUnitsType( eUNITS_TIME );
  m_oPnlStop .bSetUnitsType( eUNITS_TIME );
  m_oPnlStep .bSetUnitsType( eUNITS_TIME );

  // Disable the checkboxes for the parameters NG-Spice cannot calculate
  m_oCbxCurrent.Disable( );
  m_oCbxPower  .Disable( );
  m_oCbxResist .Disable( );
}

//**************************************************************************************************
// Create the source component display objects.

void  PnlNgSpiceTR::CreateSigSrc( void )
{
  wxPanel * poPnl;

  poPnl = static_cast< wxPanel * >( m_oChoSrcName.GetParent( ) );

  // Create and add signal source controls
#ifdef LAYOUT_MNGR
  m_oBtnSetup.Create( poPnl, ID_BTN_SETUP, wxT("Setup ...") );
  m_oBtnSetup.SetMinSize( wxSize( 105, GUI_CTRL_HT ) );
#else
  m_oSbxSigSrc.SetSize( wxSize( 255, 60 ) );
  m_oBtnSetup .Create( poPnl, ID_BTN_SETUP, wxT("Setup ..."),
                       wxPoint( 143, 200 ), wxSize( 105, GUI_CTRL_HT ) );
#endif // LAYOUT_MNGR
}

//**************************************************************************************************
// Clear the object attributes.
//
// Return Values:
//   true  - Success
//   false - Failure

bool  PnlNgSpiceTR::bClear( void )
{
  // Clear the base class
  PnlAnaBase::bClear( );

  // Set the sweep parameters to their defaults
  m_oPnlStart.bSetValue( (float)   0.0 );
  m_oPnlStop .bSetValue( (float) 100.0 );
  m_oPnlStep .bSetValue( (float)  10.0 );
  m_oPnlStart.bSetUnits( wxT("msec") );
  m_oPnlStop .bSetUnits( wxT("msec") );
  m_oPnlStep .bSetUnits( wxT("msec") );

  // Set default initial condition values
  bSetInitC( eINITC_WARM );

  // Set input source default values
  m_oChoSrcName.Clear( );
  m_oChoSrcName.Append( wxT("None") );
  m_oChoSrcName.SetSelection( 0 );

  // Clear the generator dialog
  m_oDlgCfgSrc.bClear( );

  // Set parameters check box default values
  m_oCbxVoltage.SetValue( true );
  m_oCbxCurrent.SetValue( false );
  m_oCbxPower  .SetValue( false );
  m_oCbxResist .SetValue( false );

  // Set default temperature value
  m_oPnlTemp.bSetValue( 27.0 );

  return( true );
}

//**************************************************************************************************
// Load information from a simulation object.
//
// Argument List :
//   roSimn - A simulation object
//
// Return Values :
//   true  - Success
//   false - Failure

bool  PnlNgSpiceTR::bLoad( SimnNgSpice & roSimn )
{
  bool  bRtn=true;

  // Load the components into the signal source choice box
  PnlAnaBase::LoadSrcNames( roSimn.m_oaCpnts, wxT("VI") );

  // Go no further if the TR command isn't valid
  if( ! roSimn.m_oCmdTR.bIsValid( ) )                        return( false );

  // Set the source component name (a sweep source is not mandatory for a TR analysis)
  PnlAnaBase::bSetSrcCpnt( roSimn.m_oCpntSigSrc );

  // Set the initial state of the source setup dialog
  m_oDlgCfgSrc.bSetValues( roSimn.m_oCpntIndSrc );

  // Set the initial conditions
  if( ! bSetInitC( (eTypeInitC) roSimn.m_oCmdTR.m_eInitC ) ) bRtn = false;

  // Set the sweep values
  if( ! m_oPnlStart.bSetValue( roSimn.m_oCmdTR.m_osStart ) ) bRtn = false;
  if( ! m_oPnlStop .bSetValue( roSimn.m_oCmdTR.m_osStop  ) ) bRtn = false;
  if( ! m_oPnlStep .bSetValue( roSimn.m_oCmdTR.m_osStep  ) ) bRtn = false;

  // Set the analysis temperature
  if( ! m_oPnlTemp.bSetValue( roSimn.m_oCmdOPT.m_osTEMP ) )  bRtn = false;

  return( bRtn );
}

//**************************************************************************************************
// Save information to a simulation object.
// (Prior to it being passed to a simulator object.)
//
// Argument List :
//   roSimn - A simulation object
//
// Return Values :
//   true  - Success
//   false - Failure

bool  PnlNgSpiceTR::bSave( SimnNgSpice & roSimn )
{
  wxString  os1;

  m_osErrMsg.Empty( );

  // Set the analysis type
  roSimn.m_oCmdPR.bSetAnaType( eCMD_TR );

  // Set the sweep values
  roSimn.m_oCmdTR.m_osStart = m_oPnlStart.rosGetValue( );
  roSimn.m_oCmdTR.m_osStop  = m_oPnlStop .rosGetValue( );
  roSimn.m_oCmdTR.m_osStep  = m_oPnlStep .rosGetValue( );

  // Set the initial conditions
  roSimn.m_oCmdTR.m_eInitC = (eTypeInitC) m_oRbxSweep.GetSelection( );

  // Set the component to be used as a signal source
  if( m_oChoSrcName.GetStringSelection( ) != wxT("None") )
  {
    // Get the unmodified signal source component
    os1 = m_oChoSrcName.GetStringSelection( );
    (Component &) roSimn.m_oCpntIndSrc = roSimn.roGetCpnt( os1 );
    // Add the modifications from the independent source configuration dialog
    m_oDlgCfgSrc.bGetValues( roSimn.m_oCpntIndSrc );
    if( roSimn.m_oCpntIndSrc.bFormat( ) )
      roSimn.m_oCpntSigSrc = roSimn.m_oCpntIndSrc;
    else
    {
      os1 = wxT("The signal source ")
          + roSimn.m_oCpntIndSrc.rosGetErrMsg( ) + wxT(".   ");
      SetErrMsg( os1 );
    }
  }
  else
  {
    roSimn.m_oCpntSigSrc.bClear( );
    roSimn.m_oCpntIndSrc.bClear( );
  }

  // Store the parameters to derive
  roSimn.m_oCmdPR.m_bParams[ ePARAM_VLT ] = m_oCbxVoltage.GetValue( );
  roSimn.m_oCmdPR.m_bParams[ ePARAM_CUR ] = m_oCbxCurrent.GetValue( );
  roSimn.m_oCmdPR.m_bParams[ ePARAM_PWR ] = m_oCbxPower  .GetValue( );
  roSimn.m_oCmdPR.m_bParams[ ePARAM_RES ] = m_oCbxResist .GetValue( );

  // Create the command strings
  roSimn.m_oCmdTR.bFormat( );
  roSimn.m_oCmdPR.bFormat( );

  // Check for errors
  if( ! roSimn.m_oCmdTR.bIsValid( ) )
    SetErrMsg( roSimn.m_oCmdTR.rosGetErrMsg( ) );
  if( ! roSimn.m_oCmdPR.bIsValid( ) )
    SetErrMsg( roSimn.m_oCmdPR.rosGetErrMsg( ) );

  return( bIsOk( ) );
}

//**************************************************************************************************
//                                         Event Handlers                                          *
//**************************************************************************************************
// Generator component choice control event handler.
//
// Argument List:
//   roEvtCmd - An object holding information about the event

void  PnlNgSpiceTR::OnSrcName( wxCommandEvent & roEvtCmd )
{
  wxString  os1;

  // Set the signal source name in the configuration dialogue
  os1 = m_oChoSrcName.GetStringSelection( );
  if( os1 != wxT("None") ) m_oDlgCfgSrc.bSetName( os1 );
  else                     m_oDlgCfgSrc.bClear( );
}

//**************************************************************************************************
// Generator component setup button control event handler.
//
// Argument List:
//   roEvtCmd - An object holding information about the event

void  PnlNgSpiceTR::OnBtnSetup( wxCommandEvent & roEvtCmd )
{
  // Display the signal source setup dialogue
  m_oDlgCfgSrc.CenterOnParent( );
  if( m_oDlgCfgSrc.ShowModal( ) != wxID_OK ) return;
}

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