// This may look like C code, but it is really -*- C++ -*-
// RTSS --- Railway Total System Simulator
// (c) TAKAGI Ryo (at Kogakuin University)
// diapatrn.hh --- header file that defines diapattern class
// -----
// ChangeLog:
// 2007. 11. 16
//  Changed style.
// -----

#include "globvar.hh"
#include "enumerat.hh"
#include "nextsta.hh"

#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>

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



#ifndef ___DIAPATRN_HH
#define ___DIAPATRN_HH		// こうしておくと2度インクルードしても大丈夫！


// -----
// Nextsta pointer container
// nextsta クラスのポインタのコンテナ
// -----
class _NextstaPtrs
  : private vector < nextsta * >
{
public :
  typedef size_type np_size_type ;
  typedef iterator np_iterator ;

  np_iterator np_begin () { return begin () ; }
  np_iterator np_end () { return end () ; }
  np_size_type np_size () { return size () ; }
  void np_push_back ( nextsta * x ) { push_back ( x ) ; }

  nextsta * & getElement ( np_size_type i )
  { try { return at ( i ) ; } catch ( std :: out_of_range )
    { cerr << "Error: subscript out of range (_NextstaPtrs)" << endl ;
      exit ( 26 ) ; } }

  _NextstaPtrs () : vector < nextsta * > () {}
  _NextstaPtrs ( const _NextstaPtrs & x ) : vector < nextsta * > ( x ) {}
  ~_NextstaPtrs () ;

} ;



// -----
// The class holding a train schedule "pattern"
// ダイヤパターンデータをあらわすクラス
// -----
class diapattern
  : public _NextstaPtrs ,
    public readdata
{

private :
//   void error26_name ()
//   {
//     cerr << "Error: subscript out of range in diapattern object "
//          << "nextsta data call" << endl ;
//   }

  int ndpt ;		// このダイヤパターンの番号
  double twhole ;	// 一周期あたり時間（秒）
  int cars ;    	// 列車数
  double phase ;	// 列車群の位相
  int dptm ;   // パターン倍数, twhole / cars * dptm = const. for all dpt's
  double addphase ;	// 足し算できる位相

  // この5変数、train オブジェクトの初期化用
  double pos ;
  double vel ;
  car_stat stat ;
  double tdept ;
  double taudx ;

  dp_command dcmd ;	// nextsta オブジェクトに渡すコマンド変数
  bool bufss ;		// setbuf を一度実行したら true
  bool bufset ; 	// setbuf を二度実行したら true

  string train_type_key ;

  void membercopy ( diapattern & ) ;	// メンバコピー

  void setnxx () ;		// nextsta object のセット
  void nextnxx () ;		// nextsta object 内の nxx をセット

  void realphase_cal () ;	// phase を時間に足し合わせるよう計算

public :

  diapattern () ;			// empty constructor
  // destructor は定義しない…… reftable のもので十分

  diapattern & operator= ( diapattern & ) ;	// 代入演算子の overload
  diapattern ( diapattern & ) ;        	// X(X&)

  // train obj. の初期化用
  void settrain ( double p , double v , car_stat s , double td )
  { pos = p ; vel = v ; stat = s ; tdept = 0.0 ; taudx = td ; }
  void settdept ( double td ) { tdept = td ; }

  diapattern & operator+= ( nextsta & ) ;	// nextsta obj. を加える

  // ファイルリード
  int readfile ( FILE * , char * ) ;
  bool readfile_xml ( TiXmlNode const * ) ;

  int car_number () { return cars ; }	// 車両数
  double wholetime () { return twhole ; }

  // シミュレーション上パターンの１サイクル時間を返す
  double ptntime () { return twhole / cars * dptm ; }

  // nextsta object 内の dcmd をセット
  void setdc ( dp_command ) ;

  // ndpt のセット
  void set_ndpt ( int x ) { ndpt = x ; }

  void prtinit () ;
  void prtreset () ;
  bool setbuf () ;

  // 列車初期化定数の extraction
  double phasevalue () { return addphase ;}
  double initpos () { return pos ; }
  double initvel () { return vel ; }
  car_stat carstat () { return stat ; }
  double departuretime () { return tdept ; }
  double delaytime () { return taudx ; }
  nextsta * initnxx () { return * np_begin () ; }

  string const * getTrainTypeKey () const { return & train_type_key ; }
  
} ;

#endif /* ! ___DIAPATRN_HH */
