// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I

#ifndef DATAH
#define DATAH

// ABCs for the data classes. The derived classes are in edr, bdr,
// pdsdr.

#include <iostream.h>
#include <stdio.h>

#include <defines.h>
#include <DREstring.h>
#include <timeclass.h>

enum edr_record_type { engineering, decom, science, unknown };

enum { engr = 0, cr2, cr3, cr4, cr5, cr6, unk1, cr1, bcr1, im7, gs3,
       im9, pb3, pb2, pb1, gs4, unk2, gs2, im14, unk3, im12, im11,
       im10, oc1, cr5a, gs10, gs8, im5, im4, uv5a, im2, im13, browse };

enum { pollo = 0, harad, pollo1, harad1, level, level1, level2,
       level3, fixlol, fixloh, vlobrl, vlobrh, xxxxxl, xxxxxh,
       polhil, polhih } ;		// pra submodes

enum { prapollo = 0, praharad, pralevel, prafixlo, pravlobr, praxxxxx,
       prapolhi };                    // pra modes

enum { upper, lower };		// channels

enum { left, right };			// polarisation

extern const char* _pra_mode_name[7];
extern const char* _pra_submode_name[16];

const int N_SC_MODES = 33;  // includes browse

extern const char* _sc_mode_name[N_SC_MODES];

class GMDR;

// data_record is the class from which the data handling classes are
// derived. data_file is the class from which the file handling classes
// are derived

// *****************************  data_record  ********************
class data_record
{
protected:
  byte _sc;

// what I really wanted to do was to have a single place to put the
// data and two ways to access it. But GNU refuses to initialise the
// reference member correctly.

  byte* _record;
  int16* _int16_record;
  int _record_length;
  timeclass _time;
  
public:
  data_record(void) : _record(0), _int16_record(0),
                      _record_length(0), _sc(0), _time(0)
    { };
  data_record(const data_record&);
  virtual ~data_record(void)
    { destroy_array(_record);
      destroy_array(_int16_record);
    }

  virtual reveal(byte, sc, _sc);
  virtual reveal(int, year, _time.year());
  virtual reveal(int, day, _time.day());
  virtual reveal(int, hour, _time.hour());
  virtual reveal(int, minute, _time.minute());
  virtual reveal(int, second, (int)_time.second());
  virtual reveal(timeclass, time, timeclass(year(), day(),
                 hour(), minute(), second()));
  virtual reveal(int, record_length, _record_length);
  
};

// ******************************  data_file  *************************
class data_file
{
protected:
  boolean recent_write;
  FILE* fp;
  uint32 file_size;
  
public:
  data_file(void) : recent_write(false), fp(0), file_size(0) { }
  virtual ~data_file(void)
    { if (fp) then fclose(fp); }

  virtual uint32 size(void) = 0;
  
  virtual inline operator FILE*()
    { return fp; }
  virtual inline boolean magic_number_OK(void)
    { return true; }


  inline operator FILE*() const
    { return fp; }

// place holders for the various kinds of data that can be read
  virtual void read(GMDR&, const int = -1)
    { fatal_error(""); }
};

#endif




