/***************************************************************************
**
**  This file is part of GeopsyCore.
**
**  GeopsyCore is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  GeopsyCore is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with Foobar.  If not, see <http://www.gnu.org/licenses/>
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2007-10-20
**  Copyright: 2007-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QGpCoreTools.h>
#include <mseed.h>

#include "MiniSeedReader.h"
#include "MiniSeedVolume.h"

namespace GeopsyCore {

/*!
  \class MiniSeedReader MiniSeedReader.h
  \brief Brief description of class still missing

  Used by Signal to load samples with the help of a record list stored in MiniSeedRecords.
*/

/*!
  Description of constructor still missing
*/
MiniSeedReader::MiniSeedReader(QString fileName, const MiniSeedRecords * records)
{
  TRACE;
  _records=records;
  _sequenceIndex=0;
  _recordIndex=-1;

  _f=new QFile(fileName);
  if(!_f->open(QIODevice::ReadOnly)) {
    App::log(tr("Loading MiniSeed values: cannot open file '%1'\n").arg(fileName) );
    delete _f;
    _f=nullptr;
  }
  _msr=nullptr;
}

/*!
  Description of destructor still missing
*/
MiniSeedReader::~MiniSeedReader()
{
  TRACE;
  delete _f;
}

/*!
  Returns the samples contained in next record with type \a t.
  \a nSamples is set to the number of samples.
*/
void * MiniSeedReader::nextRecord(Type& t, int& nSamples)
{
  TRACE;
  ASSERT(_f);
  off_t pos;
  quint32 recLen;
  SAFE_UNINITIALIZED(pos, 0);
  SAFE_UNINITIALIZED(recLen, 0);
  if(!_records->record(_sequenceIndex, ++_recordIndex, pos, recLen)) {
    _sequenceIndex++;
    _recordIndex=0;
    if(_sequenceIndex>=_records->sequenceCount()) {
      return nullptr;
    }
    if(!_records->record(_sequenceIndex, _recordIndex, pos, recLen)) {
      App::log(tr("Corrupted record, count=0\n") );
      return nullptr;
    }
  }
  _f->seek(pos);
  char buf[recLen];
  if(_f->read(buf, recLen)<recLen) {
    App::log(tr("Record not completely read\n") );
    return nullptr;
  }
  if(!MS_ISVALIDHEADER(buf)) {
    App::log(tr("Not a valid seed record\n") );
    return nullptr;
  }
  int msErr=msr_unpack (buf, recLen, &_msr, 1, 0);
  if(msErr!= MS_NOERROR) {
    MiniSeedVolume::errorLog(_f->fileName(), tr("Loading Miniseed values"), msErr);
    return nullptr;
  }
  nSamples=_msr->samplecnt;
  switch(_msr->sampletype) {
  case 'i':
    t=Integer;
    break;
  case 'f':
    t=Float;
    break;
  case 'd':
    t=Double;
    break;
  default:
    t=Text;
    break;
  }
  return _msr->datasamples;
}

bool MiniSeedReader::atEnd() const
{
  if(_sequenceIndex>=_records->sequenceCount()) {
    return true;
  }
  return _recordIndex>=_records->recordCount(_sequenceIndex);
}

off_t MiniSeedReader::lastPos() const
{
  off_t pos;
  quint32 recLen;
  SAFE_UNINITIALIZED(pos, 0);
  SAFE_UNINITIALIZED(recLen, 0);
  _records->record(_sequenceIndex, _recordIndex, pos, recLen);
  return pos;
}

} // namespace GeopsyCore
