// This may look like C code, but it is really -*- C++ -*-
// RTSS --- Railway Total System Simulator
// (c) TAKAGI Ryo (at Kogakuin University)
// OBESS_CurrentCapper.cc --- implementation of class OBESS_CurrentCapper
// -----
// ChangeLog:
// 2010. 1. 26
//  File created.
// -----


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <string>
#include <stdexcept>
#include "OBESS_CurrentCapper.hh"
#include "train.hh"

using std :: cerr ;
using std :: endl ;
using std :: setprecision ;

#define DEBUG



// -----
// Constructor of class OBESS_CurrentCapper using a DOM node.
// ESS_Initialiser is typedef'ed to TiXmlNode * .
// OBESS_CurrentCapper クラスを DOM ノードで初期化する. ESS_Initialiser は
// TiXmlNode * に typedef されている。
// -----
OBESS_CurrentCapper :: OBESS_CurrentCapper
( ESS_Initialiser const & d_in )
  : ESS_OnBoard () ,
    OBESS_Expander ()
{
  // -----
  // Checking if d_in is of tag "current_capper".
  // d_in が "current_capper" タグであることを確認する。
  // -----
  string d_val = d_in -> ValueStr () ;
  if ( d_val != "current_capper" )
  {
    cerr << "Error: \"" << d_val << "\" tag not allowed for construction of "
         << "OBESS_CurrentCapper." << endl ;
    exit ( 1 ) ;
  }

  // -----
  // Accessing attribute.
  // 属性データにアクセスする。
  // -----
  bool sw_p = false ;
  bool sw_b = false ;
  for ( TiXmlAttribute const *
          _atr = d_in -> ToElement () -> FirstAttribute () ;
        _atr ; _atr = _atr -> Next () )
  {
    string _a_n = string ( _atr -> Name () ) ;
    if ( _a_n == "max_current_power" )
    {
      // Attribute "max_current_power"
      if ( sw_p )
      {
        cerr << "Error initialising OBESS_CurrentCapper:" << endl
             << " Duplicate attribute max_current_power" << endl ;
        exit ( 1 ) ;
      }
      sscanf ( _atr -> Value () , "%lf" , & max_current_power ) ;
      sw_p = true ;
    }
    else if ( _a_n == "max_current_brake" )
    {
      // Attribute "max_current_brake"
      if ( sw_b )
      {
        cerr << "Error initialising OBESS_CurrentCapper:" << endl
             << " Duplicate attribute max_current_brake" << endl ;
        exit ( 1 ) ;
      }
      sscanf ( _atr -> Value () , "%lf" , & max_current_brake ) ;
      sw_b = true ;
    }
    else
    {
      cerr << "Error initialising OBESS_CurrentCapper:" << endl
           << " Attribute " << _a_n << " not allowed" << endl ;
      exit ( 1 ) ;
    }
  }
  if ( ! sw_p )
  {
    cerr << "Error initialising OBESS_CurrentCapper:" << endl
         << " Attribute max_current_power not found" << endl ;
    exit ( 1 ) ;
  }
  if ( ! sw_b )
  {
    cerr << "Error initialising OBESS_CurrentCapper:" << endl
         << " Attribute max_current_brake not found" << endl ;
    exit ( 1 ) ;
  }
}




// -----
// Copy constructor.
// コピーコンストラクタ.
// -----
OBESS_CurrentCapper :: OBESS_CurrentCapper
( const OBESS_CurrentCapper & e_in )
  : ESS_OnBoard  ( e_in ) ,
    OBESS_Expander ()
{
  max_current_power = e_in . max_current_power ;
  max_current_brake = e_in . max_current_brake ;
}




// -----
// Destructor.
// デストラクタ.
// -----
OBESS_CurrentCapper :: ~OBESS_CurrentCapper
()
{
}




// -----
// Calculate the state (voltage and current) of the system.
// システムの状態（電圧・電流）の計算
// -----
void
OBESS_CurrentCapper :: calculateVoltagesAndCurrents
( train_ParamFunc * _pf )
{
  double _trn_a = _pf -> getCurrent () ;
  if ( _trn_a < - INVLIM && _trn_a < - max_current_power )
  {
    _trn_a = - max_current_power ;
    _pf -> setCurrentWithoutLimiter ( _trn_a ) ;
    _pf -> setCurrent ( _trn_a ) ;
    _pf -> setMainCircuitCurrent ( _trn_a ) ;
    _pf -> set_Di_Dtheta ( 0 ) ;
  }
  if ( _trn_a > INVLIM && _trn_a > max_current_brake )
  {
    _trn_a = max_current_brake ;
    _pf -> setCurrentWithoutLimiter ( _trn_a ) ;
    _pf -> setCurrent ( _trn_a ) ;
    _pf -> setMainCircuitCurrent ( _trn_a ) ;
    _pf -> set_Di_Dtheta ( 0 ) ;
  }

  // ----
  // Full-notch ratio must be changed.
  // フルノッチ比も変更する必要あり。
  // ----
  double _a_wo_c = _pf -> getCurrentWithoutCapper () ;
  if ( fabs ( _a_wo_c ) > INVLIM )
  {
    double __nr = _trn_a / _a_wo_c ;
    _pf -> setNotchRateForCapper ( __nr ) ;
  }
}




// -----
// Calculate ESD voltage and current.
// -----
void
OBESS_CurrentCapper :: calculateESDVoltageAndCurrent
( train_ParamFunc * x )
{
}




// -----
// Renew the state of the ESS.
// システムの内部状態（SOCなど）の更新
// -----
void
OBESS_CurrentCapper :: renewElectricalStates
( train_ParamFunc * x )
{
}



// -----
// Regeneration limiter processing.
// 回生絞込システムへの対応。
// -----
void
OBESS_CurrentCapper :: processRegenerationLimiter
( train_ParamFunc * _pf )
{
  // Main circuit current = pantograph current
  _pf -> setMainCircuitCurrent () ;
}



// -----
// Write data to a CSV file.
// CSV ファイルにデータを書き出す.
// -----
void
OBESS_CurrentCapper :: writeToCSV
( ostream & f_in ,
  bool sw_csv )
  const
{
}



// -----
// Write a header line to a CSV file.
// CSV ファイルにヘッダ行を書き出す.
// -----
void
OBESS_CurrentCapper :: writeHeaderToCSV
( ostream & f_in ,
  bool sw_csv ,
  const string & h_in )
  const
{
}
