//**************************************************************************************************
//                                        PnlNgSpiceDC.cpp                                         *
//                                       ------------------                                        *
// Started     : 2004-05-08                                                                        *
// Last Update : 2015-04-16                                                                        *
// 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 "PnlNgSpiceDC.hpp"

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

wxBEGIN_EVENT_TABLE( PnlNgSpiceDC, PnlAnaBase )

  EVT_CHOICE( PnlAnaBase::ID_CHO_SRCNAME, PnlNgSpiceDC::OnSrcName )

wxEND_EVENT_TABLE( )

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

PnlNgSpiceDC::PnlNgSpiceDC( wxWindow * poWin ) : PnlAnaBase( poWin )
{
  bSetAnalysType( eCMD_DC );

  Create( );        // Create the analysis panel
  InitSwpUnits( );  // Initialize the sweep units
  bClear( );        // Clear all object attributes
}

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

PnlNgSpiceDC::~PnlNgSpiceDC( )
{
}

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

void  PnlNgSpiceDC::Create( void )
{
  PnlAnaBase::CreateBase( );    // Create the base controls
  PnlAnaBase::CreateScale( );   // Create the scale controls
  PnlAnaBase::CreateTemp( );    // Create the analysis temperature controls
              CreateSigSrc( );  // Create the source component display objects

  PnlAnaBase::DoLayout( );      // Layout the panel's GUI objects

  // Set the DC sweep parameter labels
  m_oSbxSwpPars.SetLabel( wxT(" DC Sweep ")  );
  m_oPnlStart  .bSetName( wxT("Start Value") );
  m_oPnlStop   .bSetName( wxT("Stop Value")  );
  m_oPnlStep   .bSetName( wxT("Step Size")   );

  // Disable the scale options NG-Spice doesn't support
  m_oRbxSweep.Enable( eSCALE_LOG, false );
  m_oRbxSweep.Enable( eSCALE_DEC, false );
  m_oRbxSweep.Enable( eSCALE_OCT, false );

  // 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  PnlNgSpiceDC::CreateSigSrc( void )
{
  // Create and add signal source controls
  m_oSbxSigSrc .Create( this, ID_UNUSED, wxT(" Signal Source "), wxPoint(  6, 178 ),
                        wxSize( 145, 60 ) );
  m_oChoSrcName.Create( this, ID_CHO_SRCNAME,                    wxPoint( 18, 200 ),
                        wxSize( 121, GUI_CTRL_HT ) );

  // Set static box font
  m_oSbxSigSrc.SetOwnFont( FONT_SLANT );
}

//**************************************************************************************************
// Initialize the sweep parameter units.

void  PnlNgSpiceDC::InitSwpUnits( void )
{
  wxString    os1;
  eTypeUnits  eUnits;

  // Determine the sweep parameter units
  os1 = m_oChoSrcName.GetStringSelection( );
  eUnits = Component::eGetUnitsType( os1 );

  switch( eUnits )
  {
    case eUNITS_VOLT :  // Units of voltage
      os1 = wxT("Voltage");
      break;

    case eUNITS_CURR :  // Units of current
      os1 = wxT("Current");
      break;

    case eUNITS_RES  :  // Units of resistance
      os1 = wxT("Resistance");
      break;

    default          :  // No units
      os1 = wxT("Value");
  }

  // Set the sweep parameter units
  m_oPnlStart.bSetName( wxString( wxT("Start ") ) + os1 );
  m_oPnlStop .bSetName( wxString( wxT("Stop ")  ) + os1 );
  m_oPnlStart.bSetUnitsType( eUnits );
  m_oPnlStop .bSetUnitsType( eUnits );
  m_oPnlStep .bSetUnitsType( eUnits );
}

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

bool  PnlNgSpiceDC::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 );

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

  // 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 :
//   roSim - A simulation object
//
// Return Values :
//   true  - Success
//   false - Failure

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

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

  // Go no further if the DC command isn't valid
  if( ! roSimn.m_oCmdDC.bIsValid( ) )                        return( false );
  if( roSimn.m_oCmdDC.m_osSource.Upper( ) == wxT("TEMP") )   return( false );

  // Set the source component label
  if( ! PnlAnaBase::bSetSrcCpnt( roSimn.m_oCpntSwpSrc ) )    bRtn = false;
  InitSwpUnits( );

  // Set the sweep values
  if( ! m_oPnlStart.bSetValue( roSimn.m_oCmdDC.m_osStart ) ) bRtn = false;
  if( ! m_oPnlStop .bSetValue( roSimn.m_oCmdDC.m_osStop  ) ) bRtn = false;
  if( ! m_oPnlStep .bSetValue( roSimn.m_oCmdDC.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 :
//   roSim - A simulation object
//
// Return Values :
//   true  - Success
//   false - Failure

bool  PnlNgSpiceDC::bSave( SimnNgSpice & roSimn )
{
  m_osErrMsg.Empty( );

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

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

  // Set the sweep source (this is compulsory for a DC analysis)
  if( m_oChoSrcName.GetStringSelection( ) != wxT("None") )
  {
    roSimn.m_oCmdDC.m_osSource = m_oChoSrcName.GetStringSelection( );
    roSimn.m_oCpntSwpSrc = roSimn.roGetCpnt( roSimn.m_oCmdDC.m_osSource );
  }
  else SetErrMsg( wxT("No sweep source component has been selected.") );

  // 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_oCmdDC.bFormat( );
  roSimn.m_oCmdPR.bFormat( );

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

  return( bIsOk( ) );
}

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

void  PnlNgSpiceDC::OnSrcName( wxCommandEvent & roEvtCmd )
{
  // Execute the base class event handler first
  PnlAnaBase::OnSrcName( roEvtCmd );

  // Initialize the sweep parameter units
  InitSwpUnits( );
}

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