#ifndef RcdReaderAsc_HH
#define RcdReaderAsc_HH

#include <string>
#include <fstream>
#include <iostream>

#include "RcdReader.hh"


class RcdReaderAsc : public RcdReader {

public:
  RcdReaderAsc();
  virtual ~RcdReaderAsc();

  bool open(const std::string &file);
  bool read(RcdRecord &r);
  bool close();


private:
  void reset();

  std::ifstream _fin;
};


#ifdef CALICE_DAQ_ICC

RcdReaderAsc::RcdReaderAsc() {
}

RcdReaderAsc::~RcdReaderAsc() {
  close();
}

bool RcdReaderAsc::open(const std::string &file) {
  if(_fin.is_open()) {
    _fin.close();
    reset();
  }

  _fileName=file+".asc";
  _fin.open(_fileName.c_str(),std::ios::in);
  
  if(!_fin) {
    std::cerr << "RcdReaderAsc::open()   Error opening file "
	      << _fileName << std::endl << std::flush;
    reset();
    return false;
  }
  
  if(_printLevel>0) {
    std::cout << "RcdReaderAsc::open()   Opened file " 
	      << _fileName << std::endl;
  }

  _isOpen=true;

  return true;
}

bool RcdReaderAsc::read(RcdRecord &r) {
  if(!_fin) return false;
  
  unsigned *p((unsigned*)&r);
  _fin >> p[0];

  if(!_fin) {
    if(_printLevel>1) {
      std::cout << "RcdReaderAsc::read()   Expected end-of-file" << std::endl;
    }
    return false;
  }

  const unsigned numberOfHeaderWords((sizeof(RcdRecord)+3)/4);

  for(unsigned i(1);i<numberOfHeaderWords;i++) {
    _fin >> p[i];
    if(!_fin) {
      std::cerr << "RcdReaderAsc::read()   Unexpected end-of-file reading"
		<< " header after " << i << " words out of "
		<< numberOfHeaderWords << std::endl << std::flush;
      return false;
    }
  }
  
  if(r.numberOfWords()>100000) {
    std::cerr << "RcdReaderAsc::read()   Too many words in record "
	      << r.numberOfWords() << " > 100000" << std::endl;
    return false;
  }

  _numberOfBytes+=2*sizeof(RcdRecord); // Approx

  for(unsigned i(0);i<r.numberOfWords();i++) {
    _fin >> p[i+numberOfHeaderWords];
    
    if(!_fin) {
      std::cerr << "RcdReaderAsc::read()   Unexpected end-of-file reading"
		<< " data after " << i << " words out of "
		<< r.numberOfWords() << std::endl;
      return false;
    }
  }
  
  _numberOfBytes+=9*r.numberOfWords(); // Approx
  
  return _fin;
}

bool RcdReaderAsc::close() {
  if(!_fin.is_open()) {
    reset();
    return false;
  }

  _fin.close();

  if(_printLevel>0) {
    std::cout << "RcdReaderAsc::close()  Closed file " << _fileName;
    if(_printLevel>1) std::cout << " after reading approx "
				<< _numberOfBytes << " bytes";
    std::cout << std::endl;
  }

  reset();
  return true;
}

void RcdReaderAsc::reset() {
  RcdIoBase::reset();
  _fin.clear(); // Clear all errors
}

#endif
#endif
