//**************************************************************************************************
//                                           CmdBase.cpp                                           *
//                                          -------------                                          *
// Started     : 2006-08-31                                                                        *
// Last Update : 2018-09-25                                                                        *
// Copyright   : (C) 2006-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 "CmdBase.hpp"

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

CmdBase::CmdBase( void ) : wxString( )
{
  m_osErrMsg = wxT("Invalid");

  m_eSimEng  = eSIMR_NONE;
  m_eCmdType = eCMD_NONE;
}

//**************************************************************************************************
// Copy constructor.
//
// Argument List :
//   roCmd - A reference to the object to be copied

CmdBase::CmdBase( const CmdBase & roCmd ) : wxString( )
{
  *this = roCmd;
}

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

CmdBase::~CmdBase( )
{
}

//**************************************************************************************************
// Set the object attributes to their default values.
//
// Return Values :
//   true  - Success
//   false - Failure

bool  CmdBase::bSetDefaults( void )
{
  wxString::Empty( );

  m_osErrMsg = wxT("Invalid");

  m_eSimEng  = eSIMR_NONE;
  m_eCmdType = eCMD_NONE;

  return( true );
}

//**************************************************************************************************
// Check that the object attributes are valid.
//
// Return Values :
//   true  - Success
//   false - Failure

bool  CmdBase::bValidate( void )
{
  m_osErrMsg.Empty( );

  if( IsEmpty( ) )
    SetErrMsg( wxT("The command is empty") );
  if( m_eSimEng == eSIMR_NONE )
    SetErrMsg( wxT("The command has no simulator engine") );
  if( m_eCmdType == eCMD_NONE )
    SetErrMsg( wxT("The command has no type") );

  return( bIsValid( ) );
}

//**************************************************************************************************
// Set the command based on a complete command string.
//
// Argument List :
//   rosCmd - A reference to a wxString object
//
// Return Values :
//   true  - Success
//   false - Failure

bool  CmdBase::bSetString( wxString & ros )
{
  bSetDefaults( );
  assign( ros );
  bParse( );

  return( true );
}

//**************************************************************************************************
// Copy the contents of another CmdBase object.
//
// Argument List :
//   roCmd - A reference to a CmdBase object
//
// Return Values :
//   A reference to this object

CmdBase & CmdBase::operator = ( const CmdBase & roCmd )
{
  // Copy the command string
  (wxString &) *this = (wxString &) roCmd;

  // Once these attributes are set they won't change
  if( m_eSimEng == eSIMR_NONE ) m_eSimEng  = roCmd.m_eSimEng;
  if( m_eCmdType == eCMD_NONE ) m_eCmdType = roCmd.m_eCmdType;

  // Copy the any error message
  m_osErrMsg = roCmd.m_osErrMsg;

  return( *this );
}

//**************************************************************************************************
// Print the object attributes.
//
// Argument List :
//   rosPrefix - A prefix to every line displayed (usually just spaces)

void  CmdBase::Print( const wxString & rosPrefix )
{
  std::cout << rosPrefix .mb_str( ) << "wxString   : \"" << this     ->mb_str( ) << "\"\n";

  std::cout << rosPrefix .mb_str( ) << "m_osErrMsg : \"" << m_osErrMsg.mb_str( ) << "\"\n";

  std::cout << rosPrefix .mb_str( ) << "m_eSimEng  : ";
  switch( m_eSimEng )
  {
    case eSIMR_GNUCAP  : std::cout << "eSIMR_GNUCAP";  break;
    case eSIMR_NGSPICE : std::cout << "eSIMR_NGSPICE"; break;
    case eSIMR_NONE    : std::cout << "eSIMR_NONE";    break;
    default            : std::cout << "Invalid";       break;
  }
  std::cout << '\n';

  std::cout << rosPrefix .mb_str( ) << "m_eCmdType : ";
  switch( m_eCmdType )
  {
    case eCMD_OP   : std::cout << "eANA_OP";   break;  // Operating point analysis
    case eCMD_DC   : std::cout << "eANA_DC";   break;  // DC analysis
    case eCMD_AC   : std::cout << "eANA_AC";   break;  // AC analysis
    case eCMD_TR   : std::cout << "eANA_TR";   break;  // Transient analysis
    case eCMD_FO   : std::cout << "eANA_FO";   break;  // Fourier analysis
    case eCMD_DI   : std::cout << "eANA_DI";   break;  // Distortion analysis
    case eCMD_NO   : std::cout << "eANA_NO";   break;  // Noise analysis
    case eCMD_PZ   : std::cout << "eANA_PZ";   break;  // Pole-zero analysis
    case eCMD_SE   : std::cout << "eANA_SE";   break;  // Sensitivity analysis
    case eCMD_TF   : std::cout << "eANA_TF";   break;  // Transfer function analysis

    case eCMD_OPT  : std::cout << "eCMD_OPT";  break;  // Options command
    case eCMD_IC   : std::cout << "eCMD_IC";   break;  // Initial conditions command
    case eCMD_PR   : std::cout << "eCMD_PR";   break;  // Print command
    case eCMD_GEN  : std::cout << "eCMD_GEN";  break;  // Generator command

    case eCMD_NONE : std::cout << "eANA_NONE"; break;  // Command type not set
    default        : std::cout << "Invalid";   break;  // Command type is invalid
  }
  std::cout << '\n';
}

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