//**************************************************************************************************
//                                         PnlGnuCapOP.cpp                                         *
//                                        -----------------                                        *
// Started     : 2003-11-06                                                                        *
// Last Update : 2015-08-10                                                                        *
// Copyright   : (C) 2003-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 "PnlGnuCapOP.hpp"

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

wxBEGIN_EVENT_TABLE( PnlGnuCapOP, PnlAnaBase )

  EVT_RADIOBOX( PnlAnaBase::ID_RBX_SCALE  , PnlGnuCapOP::OnScale   )
  EVT_CHOICE  ( PnlAnaBase::ID_CHO_SRCNAME, PnlGnuCapOP::OnSrcName )

wxEND_EVENT_TABLE( )

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

PnlGnuCapOP::PnlGnuCapOP( wxWindow * poWin ) : PnlAnaBase( poWin )
{
  bSetAnalysType( eCMD_OP );

  Create( );

  bClear( );
}

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

PnlGnuCapOP::~PnlGnuCapOP( )
{
}

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

void  PnlGnuCapOP::Create( void )
{
  PnlAnaBase::CreateBase( );   // Create the base controls
  PnlAnaBase::CreateScale( );  // Create the scale controls
  PnlAnaBase::CreateSigSrc( ); // Create input signal source controls

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

  // Set the sweep parameter labels
  m_oSbxSwpPars.SetLabel( wxT(" Operating Point Sweep ") );
  m_oPnlStart  .bSetName( wxT("Start Temperature") );
  m_oPnlStop   .bSetName( wxT("Stop Temperature") );

  // Display the PnlValue units as a label
  m_oPnlStart.bShowUnits( PnlValue::eSHOW_LBL );
  m_oPnlStop .bShowUnits( PnlValue::eSHOW_LBL );
  m_oPnlStep .bShowUnits( PnlValue::eSHOW_LBL );

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

  // Layout the PnlValue controls
  m_oPnlStart.Layout( );
  m_oPnlStop .Layout( );
  m_oPnlStep .Layout( );

  // Create scale controls but disable the scale option GNU-Cap doesn't support
  m_oRbxSweep.Enable( eSCALE_OCT, false );
}

//**************************************************************************************************
// Initialize the step scale.

void  PnlGnuCapOP::InitScale( void )
{
  switch( m_oRbxSweep.GetSelection( ) )
  {
    case eSCALE_LIN :
      m_oPnlStep.bSetName( wxT("Step Increment") );
      m_oPnlStep.bSetValueType( eVALUE_FLT );
      m_oPnlStep.bShowUnits( PnlValue::eSHOW_LBL );
      m_oPnlStep.bSetSpnRange( 0.0, 10000.0 );
      m_oPnlStep.bSetSpnIncSz( 1.0,  1000.0 );
      m_oPnlStep.bSetDefValue( 1.0 );
      break;

    case eSCALE_LOG :
      m_oPnlStep.bSetName( wxT("Step Multiplier") );
      m_oPnlStep.bSetValueType( eVALUE_FLT );
      m_oPnlStep.bShowUnits( PnlValue::eSHOW_NONE );
      m_oPnlStep.bSetSpnRange( 0.0 , 10000.0 );
      m_oPnlStep.bSetSpnIncSz( 0.01,  1000.0 );
      m_oPnlStep.bSetDefValue( 1.01 );
      break;

    case eSCALE_DEC :
      m_oPnlStep.bSetName( wxT("Steps / Decade") );
      m_oPnlStep.bSetValueType( eVALUE_INT );
      m_oPnlStep.bShowUnits( PnlValue::eSHOW_NONE );
      m_oPnlStep.bSetSpnRange( 1, 10000 );
      m_oPnlStep.bSetSpnIncSz( 1,  1000 );
      m_oPnlStep.bSetDefValue( 10 );
      break;

    default :
      break;
  }
}

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

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

  // Set the step scale type and default sweep values
  m_oPnlStart.bSetValue( (float)   0.0 );
  m_oPnlStop .bSetValue( (float) 100.0 );
  m_oPnlStep .bSetValue( (float)  10.0 );

  // Set default scale value
  bSetScale( eSCALE_LIN );

  // Set input source default values
  m_oChoSrcName.Clear( );
  m_oChoSrcName.Append( wxT("None") );
  m_oChoSrcName.SetSelection( 0 );
  m_oPnlSrcLvl.bSetValue( (float) 0.0 );
  m_oPnlSrcLvl.bSetUnitsType( eUNITS_NONE );

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

  return( true );
}

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

bool  PnlGnuCapOP::bLoad( SimnGnuCap & roSimn )
{
  bool  bRtn=true;

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

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

  // Set the source component (a sweep source is not mandatory for an OP analysis)
  PnlAnaBase::bSetSrcCpnt( roSimn.m_oCpntSwpSrc );

  // Set the step scale (do this before setting the sweep step)
  if( roSimn.m_oCmdOP.m_eScale != eSCALE_NONE )
    m_oRbxSweep.SetSelection( roSimn.m_oCmdOP.m_eScale );

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

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

  return( bRtn );
}

//**************************************************************************************************
// Save information to a simulation object.
//
// Argument List :
//   roSimn - A SimnGnuCap object
//
// Return Values :
//   true  - Success
//   false - Failure

bool  PnlGnuCapOP::bSave( SimnGnuCap & roSimn )
{
  wxString  os1;

  m_osErrMsg.Empty( );

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

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

  // Set the step scale
  roSimn.m_oCmdOP.m_eScale = (eTypeScale) m_oRbxSweep.GetSelection( );

  // Set the sweep source (a sweep source is not compulsory for a OP analysis)
  if( m_oChoSrcName.GetStringSelection( ) != wxT("None") )
  {
    os1 = m_oChoSrcName.GetStringSelection( );
    (Component &) roSimn.m_oCpntSwpSrc = roSimn.roGetCpnt( os1 );
    roSimn.m_oCpntSwpSrc.bSetValue( m_oPnlSrcLvl.rosGetValue( ) );
  }
  else roSimn.m_oCpntSwpSrc.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_oCmdOP.bFormat( );
  roSimn.m_oCmdPR.bFormat( );

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

  return( bIsOk( ) );
}

//**************************************************************************************************
//                                         Event Handlers                                          *
//**************************************************************************************************
// Step scale radio box event handler.
//
// Argument List :
//   roEvtCmd - An object holding information about the event

void  PnlGnuCapOP::OnScale( wxCommandEvent & roEvtCmd )
{
  InitScale( );
}

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

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

  // Execute the base class event handler first
  PnlAnaBase::OnSrcName( roEvtCmd );

  if( m_oChoSrcName.GetStringSelection( ) != wxT("None") )
  {
    // Set the units type
    os1 = m_oChoSrcName.GetStringSelection( );
    m_oPnlSrcLvl.bSetUnitsType( Component::eGetUnitsType( os1 ) );

    // Set the source value
    if( m_oPnlSrcLvl.dfGetValue( ) == 0.0 )
      m_oPnlSrcLvl.bSetValue( (double) 1.0 );
  }
  else
  {
    m_oPnlSrcLvl.bSetUnitsType( eUNITS_NONE );
    m_oPnlSrcLvl.bSetValue( (double) 0.0 );
  }
}

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