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

#ifndef CITYSIGNAL_H
#define CITYSIGNAL_H

#include <QGpCoreTools.h>

#include "SignalDatabase.h"
#include "GeopsyCoreDLLExport.h"

namespace GeopsyCore {

#define BLOCK_SIZE 9

class GEOPSYCORE_EXPORT CitySignal
{
  TRANSLATIONS("CitySignal")
public:
  CitySignal();
  ~CitySignal();

  bool readHeader(QFile * stream, int version);
  bool loadSignals(SignalDatabase *db, QFile * stream) const;
  bool erase(QFile * stream);

  enum RecorderType {Unknown, CityShark1, CityShark2};

  const DateTime& startTime() const {return _startTime;}
  const DateTime& endTime() const {return _endTime;}
  const char * fileIndex() const {return _fileIndex;}
  int channelNum() const {return _channelNum;}
  int duration() const {return _duration;}
  int gain() const {return _gain;}
  int maxAllowedAmpl() const {return _maxAllowedAmpl;}
  int maxReachedAmpl() const {return _maxReachedAmpl;}
  int frequency() const {return _frequency;}
  int nSamples() const {return _nSamples;}
  double saturation() const {return _saturation;}
  bool erased() const {return _erased;}
  QString fileName() const {return _startTime.toString("yyMMdd_hhmm")+"."+_fileIndex;}

  static double conversionFactor(int frequency, int gain);
private:
  void readBlock(QFile * f) {f->read (_currentBlock, BLOCK_SIZE);}
  inline void setRecorder(char *ptr);
  inline int getSample(char * ptr) const;
  inline char * getCouple(char * startPtr);
  void setCurrentYear(DateTime& dt);
private:
  char _currentBlock [BLOCK_SIZE+1];

  RecorderType _recorder;
  bool _erased;
  qint64 _dataOffset;
  // CityShark 1 and 2
  int _channelNum;
  int _softwareVersion;
  int _serialNum;
  DateTime _startTime;
  DateTime _endTime;
  char _fileIndex[4];
  int _frequency;
  int _duration;
  int _nSamples;
  int _gain;
  double _saturation;
  int _maxAllowedAmpl;
  int _maxReachedAmpl;
  // CityShark 2 only
  int _latitudeDeg;
  int _longitudeDeg;
  double _latitudeMin;
  double _longitudeMin;
  int _satNum;
  double _altitude;
};

inline void CitySignal::setRecorder(char * ptr)
{
  TRACE;
    if(*ptr=='\0') _recorder=CityShark1;
    else if(*ptr=='2' && *(ptr+1)=='\0') _recorder=CityShark2;
    else _recorder=Unknown;
}

inline char * CitySignal::getCouple(char * startPtr)
{
  TRACE;
    char * ptr=startPtr;
    while(*ptr!='\0' && *ptr!=',') ptr++;
    *ptr='\0';
    return ptr+1;
}

inline int CitySignal::getSample(char * ptr) const
{
  TRACE;
  union {
    struct {unsigned char b1, b2, b3, b4;} b;
    int dw;
  } val;
#if Q_BYTE_ORDER==Q_BIG_ENDIAN
    val.b.b2=ptr[0];
    val.b.b3=ptr[1];
    val.b.b4=ptr[2];
    if(val.b.b2>=0x80) val.b.b1=0xFF; else val.b.b1=0x00;
#else // LITTLE ENDIAN
    val.b.b3=ptr[0];
    val.b.b2=ptr[1];
    val.b.b1=ptr[2];
    if(val.b.b3>=0x80) val.b.b4=0xFF; else val.b.b4=0x00;
#endif
    return val.dw;
}

} // namespace GeopsyCore

#endif // CITYSIGNAL_H
