//  DataAvailability.h
//
//  Qdos - data interfacing
//
//  David Burgess
//  March 2000
//


#ifndef Q_DATAAVAILABILITY_H
#define Q_DATAAVAILABILITY_H

#include <vector>
#include <string>

#include "Viostream.h"
#include "QdTime.h"

namespace QDOS {

class DataAvailability;

Vostream& operator<<(Vostream&, const DataAvailability&);
Vistream& operator>>(Vistream&, DataAvailability&);

class DataAvailability {

  friend Vostream& operator<<(Vostream&, const DataAvailability&);
  friend Vistream& operator>>(Vistream&, DataAvailability&);

  double _resolution;  // time quantum for availability IN SECONDS
  int _num_quanta;      // number of sub intervals
  TimeInterval _time_interval; // interval covered by this object
  string _data_name;   // convenience storage of data name
  vector<bool> _available; // true for available

  void set_num_quanta(void);

public:
  DataAvailability(void)
   : _data_name(""), _num_quanta(0), _resolution(0) {;}
  DataAvailability( const string& data_name, TimeInterval time_interval,
                    double resolution )
    : _data_name(data_name), _time_interval(time_interval),
      _resolution(resolution),
      _num_quanta( static_cast<int>(
                     time_interval.duration_abs().get_time_rep()/resolution)
                     + 1 ),
      _available( _num_quanta, false ) {_time_interval.force_sense();}

  DataAvailability( const string& data_name, TimeInterval time_interval,
                    const string& data_availablity_string );

  DataAvailability( const string& data_name, TimeInterval time_interval, \
                    const double& resolution,
                    const string& data_availablity_string );

//  bool& operator[]( int i ) { return _available[i]; }    // add checks?
  int get_num_subintervals(void) const { return _num_quanta; }
  bool is_data_available( Time t ) const;
  bool is_data_available( TimeInterval tintvl ) const;
  void set_data_available( Time t );

  void set_data_name( const string& data_name )
    { _data_name = data_name; }
  void set_time_interval( TimeInterval time_interval )
    { _time_interval = time_interval; _time_interval.force_sense();
       set_num_quanta(); }
  void set_resolution( double resolution );
  void set_data_availability(const string& data_availability_string);
 
  TimeInterval get_time_interval(void) const { return _time_interval; }
  string get_data_name(void) const { return _data_name; }
  string srep(void) const;
  
  void diag_print(void) const;
  
};

inline Vostream& operator<<(Vostream& v_os, const DataAvailability& da)
{ v_os << da._resolution;
  v_os << da._num_quanta;
  v_os << da._time_interval;
  v_os << da._data_name;
  for(int i=0;i<da._num_quanta;i++)
  {
     int j=(da._available[i])?1:0;
     v_os << j;
  }
  return v_os;
}

inline Vistream& operator>>(Vistream& v_is, DataAvailability& da)
{ v_is >> da._resolution;
  v_is >> da._num_quanta;
  v_is >> da._time_interval;
  v_is >> da._data_name;
  da._available.resize(da._num_quanta);
  for(register int i=0;i<da._num_quanta;i++)
  {
     int j;
     v_is >> j;
     da._available[i]=(j==1)?true:false;
  }
  return v_is;
}

} // end namespace QDOS


#endif //  #ifndef Q_DATAAVAILABILITY_H
