/***************************************************************************
**
**  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-12
**  Copyright: 2007-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#ifndef GURALPCOMPRESSEDBLOCK_H
#define GURALPCOMPRESSEDBLOCK_H

#include <QGpCoreTools.h>

#include "GeopsyCoreDLLExport.h"
#include "TimeRange.h"
#include "GeoSignal.h"

namespace GeopsyCore {

  class GEOPSYCORE_EXPORT GuralpCompressedBlock
  {
    TRANSLATIONS("GuralpCompressedBlock")
  public:
    GuralpCompressedBlock();
    GuralpCompressedBlock(const GuralpCompressedBlock& o);
    ~GuralpCompressedBlock();

    void operator=(const GuralpCompressedBlock& o);
    bool operator==(const GuralpCompressedBlock& o) const;

    enum StreamType {Data, MuxChannel, Status, ChannelData, BytePipe, Information, Unknown};

    inline bool readHeader(QFile& f);
    inline bool readBody(QFile& f);
    inline void skipBody(QFile& f);

    bool parseHeader(const char * gcfHeader);
    bool parseBody(const char * gcfBody);

    StreamType streamType() const;
    const char * streamTypeString() const;
    int nSamples() const {return _nSamples;}
    double samplingFrequency() const {return _samplingFrequency;}
    QString name() const {return _device;}
    DateTime startTime() const {return _startTime;}
    TimeRange timeRange() const;
    Signal::Components component() const;
    bool isData() const {return _component!='0' && _component!='I';}
    int compressionCode() {return _compressionCode;}
    int sample(int index) const {return _samples[index];}
    uint hash() const {return _hash;}

    void debugPrint() const;
  private:
    inline static void base36ToAscii(qint32 b, char * str);
    uint _hash;
    char _systemID[7];
    char _device[5];
    char _component;
    char _channel;
    DateTime _startTime;
    double _samplingFrequency;
    int _compressionCode;
    int _nSamples;
    int * _samples;
  };

  inline uint qHash(const GuralpCompressedBlock& b) {
    return b.hash();
  }

  inline bool GuralpCompressedBlock::readHeader(QFile& f)
  {
    // Read the 16 bytes header
    char header[16];
    qint64 n=f.read(header, 16);
    if(n!=16) return false;
    return parseHeader(header);
  }

  inline bool GuralpCompressedBlock::readBody(QFile& f)
  {
    char body[1008];
    qint64 n=f.read(body,1008);
    if(n!=1008) return false;
    return parseBody(body);
  }

  inline void GuralpCompressedBlock::skipBody(QFile& f)
  {
    f.seek(f.pos()+1008); // 1024-byte blocks less 16-byte header
  }

} // namespace GeopsyCore

#endif // GURALPCOMPRESSEDBLOCK_H
