// This may look like C code, but it is really -*- C++ -*-
// RTSS --- Railway Total System Simulator
// (c) TAKAGI Ryo (at Kogakuin University)
// Ref_SOC_Curve.hh --- declaration of class Ref_SOC_Curve and related classes
// -----
// ChangeLog:
// 2009. 11. 25
//  File created.
// -----


#ifndef Ref_SOC_Curve_HH
#define Ref_SOC_Curve_HH

#include <cstdlib>
#include <string>
#include <vector>
#include <iostream>
#include "tinyxml.h"
#include "DataInSection.hh"
#include "RS_Object.hh"
#include "Expandable.hh"

using std :: vector ;
using std :: string ;
using std :: cerr ;
using std :: endl ;



class SOC_FeedForward_Data
  : public virtual RS_Object
{
public :

  // Virtual destructor
  virtual ~SOC_FeedForward_Data () {}

  // Constructor
  explicit SOC_FeedForward_Data ( TiXmlNode const * const & ) ;
  explicit SOC_FeedForward_Data ( SOC_FeedForward_Data const & x )
    : RS_Object ( x ) {}

  // Overriding a virtual function defined in base class RS_Object
  bool acceptInitObject ( string const & a , RS_Object * b )
  { cerr << "Error: SOC_FeedForward_Data::acceptInitObject(...) "
         << "must not be called" << endl ; return false ; }

  struct _Data
  {
    double _soc ;
    double _dsoc_dx ;
  } ;

  // Virtual function for obtaining necessary data.
  virtual _Data getData ( double ) const = 0 ;

} ;



// ----
// Definition of SOC_FeedForward_Data class "expander".
// SOC_FeedForward_Data クラスの "expander" の定義。
// ----
typedef Expandable < SOC_FeedForward_Data , TiXmlNode const * >
FFSOC_Expander ;



/******************************************************************
 * struct Ref_SOC_Data_Cell
 ******************************************************************/
struct Ref_SOC_Data_Cell
{

  // -----
  // Declaration of initialiser class
  // 初期化用クラスの宣言
  // -----
  struct Init
  {
    TiXmlAttribute const * _pos ;
    TiXmlAttribute const * _value ;

    Init () { _pos = _value = 0 ; }
    Init ( TiXmlAttribute const * _pos_ , TiXmlAttribute const * _value_ )
      : _pos ( _pos_ ) , _value ( _value_ ) {}
  } ;

  double _pos ;
  double _value ;

  Ref_SOC_Data_Cell () { _pos = _value = 0 ; }
  Ref_SOC_Data_Cell ( Init const & ) ;
  Ref_SOC_Data_Cell ( double _pos_ , double _val_ )
  { _pos = _pos_ ; _value = _val_ ; }

  Ref_SOC_Data_Cell ( Ref_SOC_Data_Cell const & x )
  { _pos = x . _pos ; _value = x . _value ; }

  Ref_SOC_Data_Cell & operator= ( Ref_SOC_Data_Cell const & x )
  { if ( & x  == this ) return * this ;
    _pos = x . _pos ; _value = x . _value ; return * this ; }

} ;



/******************************************************************
 * class Ref_SOC_Curve (Amano version).
 * Ref_SOC_Curve (天野バージョン).
 ******************************************************************/
class Ref_SOC_Curve
  : public SOC_FeedForward_Data ,
    public vector < Ref_SOC_Data_Cell >
{

public :

  // -----
  // Functions ... Getting data
  // 関数 ... データを得る
  // -----
  _Data getData ( double ) const ;

  // Constructor
  Ref_SOC_Curve ( TiXmlNode const * const & ) ;

  // X(X&)
  Ref_SOC_Curve ( Ref_SOC_Curve const & x )
    : vector < Ref_SOC_Data_Cell > ( x ) , SOC_FeedForward_Data ( x ) {}

  // Operator =
  Ref_SOC_Curve & operator= ( Ref_SOC_Curve const & x )
  { vector < Ref_SOC_Data_Cell > :: operator= ( x ) ; return * this ; }

private :

  // Default constructor prohibited
  explicit Ref_SOC_Curve () ;

} ;



// -----
// Creator of class Ref_SOC_Curve.
// Ref_SOC_Curve クラスの Creator.
// -----
class Ref_SOC_Curve_Creator
  : public FFSOC_Expander :: ObjectCreator
{
public :
  Ref_SOC_Curve_Creator ()
  { add_to_creators_list ( "amano" ) ; }
  Ref_SOC_Curve_Creator ( char const * x )
    : FFSOC_Expander :: ObjectCreator () { add_to_creators_list ( x ) ; }
  SOC_FeedForward_Data * create () const
  {
    cerr << "Error: Ref_SOC_Curve... default constructor prohibited"
         << endl ;
    exit ( 1 ) ;
  }
  SOC_FeedForward_Data * create ( TiXmlNode const * const & x ) const
  { return new Ref_SOC_Curve ( x ) ; }
} ;



#endif	// Ref_SOC_Curve_HH
