//
//  DataSource.h
//
//  Qdos2 - data interfacing
//
//  David Burgess
//  June 1999
//

#ifndef QDOS_DATASOURCE_H
#define QDOS_DATASOURCE_H

#include <vector>

#include "Exception.h"
#include "Var.h"
#include "Naming.h"
#include "DataBuffer.h"

namespace QDOS {

// TimeInterval declaration (do not include Time.h)
class TimeInterval;

typedef NamingContext<string> DataNamesTable;
typedef Var<DataNamesTable> DataNamesTable_var;

class DataSourceException : public Exception {
public:
  DataSourceException( ExceptionMsg m )
    : Exception( m << "[DataSourceException]" ){;}
};
class NoSuchDataSourceName : public DataSourceException {
public:
  NoSuchDataSourceName( ExceptionMsg m )
    : DataSourceException( m << " [NoSuchDataSourceName]" ){;}
};
class DataSourceBadOpen : public DataSourceException {
public:
  DataSourceBadOpen( ExceptionMsg m )
    : DataSourceException( m << " [DataSourceBadOpen]" ){;}
};

class DataSource:public VarTarget {
public:
  virtual void open( const string& source_name ) = 0;
  virtual void close( ) = 0;
  virtual DataNamesTable_var get_data_names( ) = 0;
  virtual DataBuffer_var get_data(const string& data_name)
  {DataBuffer_var res;return res;}
};

typedef Var<DataSource> DataSource_var;

class RecordStructuredDataSource {
public:
  virtual DataBuffer_var
    get_data( const string& data_name, int rec_start, int num_rec ) = 0;
};

class TimeStructuredDataSource {
public:
  virtual DataBuffer_var
    get_data( const string& data_name, const TimeInterval& time_interval ) = 0;
};


// +++++++++++++++++++++++++++++++++++++++++++ class IgnoreNumericDataFunctor
// --------------------------------------------------------------------------
class IgnoreNumericDataFunctor : public VarTarget {
public:
  virtual ~IgnoreNumericDataFunctor(void) {;}
  virtual bool ignore_data_item(
    NumericVDataBuffer&  nvd_buffer, int item ) = 0 ;
};

typedef Var<IgnoreNumericDataFunctor> IgnoreNumericDataFunctor_var;

// +++++++++++++++++++++++++++++++++++++++++++++++ class IgnoreByApproxNValue
// --------------------------------------------------------------------------
class IgnoreByApproxNValue : public IgnoreNumericDataFunctor {
  vector<double> values;
  double precision;
public:
  IgnoreByApproxNValue( const vector<double>& ignore_values,
                        double precision_percent=5.0 )
    : values( ignore_values ), precision( 0.01 * precision_percent ) {;}
  IgnoreByApproxNValue( double ignore_value, double precision_percent=5.0 )
    : precision( 0.01 * precision_percent ) { values.push_back(ignore_value);}
  IgnoreByApproxNValue(const IgnoreByApproxNValue& a)
    : values(a.values), precision(a.precision) {;}        
  bool ignore_data_item( NumericVDataBuffer& nvd_buffer, int item )
    { return nvd_buffer.item_approx_equal( item, values, precision ); }

};



} // namespace QDOS


#endif //  #ifndef QDOS_DATASOURCE_H

