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

#ifndef ASCIISIGNALFORMAT_H
#define ASCIISIGNALFORMAT_H

#include "AbstractFileFormat.h"
#include "AsciiSignalFormatRule.h"
#include "AsciiSignalFormatComponent.h"
#include "GeopsyCoreDLLExport.h"

namespace GeopsyCore {

class GEOPSYCORE_EXPORT AsciiSignalFormat : public AbstractFileFormat
{
  TRANSLATIONS("AsciiSignalFormat")
public:
  AsciiSignalFormat();
  AsciiSignalFormat(const AsciiSignalFormat& o);

  void operator=(const AsciiSignalFormat& o);

  bool xml_inherits(const QString& tagName) const;
  virtual const QString& xml_tagName() const {return xmlAsciiSignalFormatTag;}
  static const QString xmlAsciiSignalFormatTag;

  enum HeaderType {NoHeader, FixedHeader, HeaderPattern, EndHeaderPattern};

  void setHeaderType(HeaderType t) {_headerType=t;}
  void setHeaderType(const QString& t);
  HeaderType headerType() const {return _headerType;}
  QString headerTypeString() const;

  const QString& headerPattern() const {return _headerPattern;}
  void setHeaderPattern(const QString& h) {_headerPattern=h;}

  int headerLineCount() const {return _headerLineCount;}
  void setHeaderLineCount(int h) {_headerLineCount=h;}

  const QString& timeFormat() const {return _timeFormat;}
  void setTimeFormat(const QString& t) {_timeFormat=t;}

  void setSeparators(AsciiLineParser::Separators s) {_separators=s;}
  AsciiLineParser::Separators separators() const {return _separators;}

  void setEmptyValues(bool e) {_emptyValues=e;}
  bool emptyValues() const {return _emptyValues;}

  void setQuotes(bool q) {_quotes=q;}
  bool quotes() const {return _quotes;}

  void setHexadecimal(bool h) {_hexadecimal=h;}
  bool hexadecimal() const {return _hexadecimal;}

  void insertComponent(int index, const AsciiSignalFormatComponent& c) {_components.insert(index, c);}
  void removeComponent(int index) {_components.removeAt(index);}
  int componentCount() const {return _components.count();}
  const AsciiSignalFormatComponent& component(int index) const {return _components.at(index);}
  AsciiSignalFormatComponent& component(int index) {return _components[index];}

  void insertRule(int index, const AsciiSignalFormatRule& r) {_rules.insert(index, r);}
  void removeRule(int index) {_rules.removeAt(index);}
  int ruleCount() const {return _rules.count();}
  void moveRuleUp(int index);
  void moveRuleDown(int index);
  const AsciiSignalFormatRule& rule(int index) const {return _rules.at(index);}
  AsciiSignalFormatRule& rule(int index) {return _rules[index];}

  QString header(QTextStream& s, int& lineNumber, QAtomicInt * terminate=nullptr) const;
  bool parseHeader(const QString& headerText, QAtomicInt * terminate=nullptr);
  bool readTimeColumn(QByteArray &buffer, int columnCount, int lineNumber);
  DateTime startTime() const;
  void assign(Signal * sig);
  bool isIgnored(int columnIndex) const;

  virtual SignalFileFormat::Format format() const {return SignalFileFormat::Ascii;}
  virtual int complexity() const;
  virtual bool isValid(const QString& fileName) const;
  virtual bool hasUserProperties() const {return true;}

  static void setVerbose(bool v) {_verbose=v;}
protected:
  virtual void xml_writeProperties(XML_WRITEPROPERTIES_ARGS) const;
  virtual void xml_writeChildren(XML_WRITECHILDREN_ARGS) const;
  virtual XMLMember xml_member(XML_MEMBER_ARGS);
  virtual bool xml_setProperty(XML_SETPROPERTY_ARGS);
private:
  HeaderType _headerType;
  QString _headerPattern;
  int _headerLineCount;

  QString _timeFormat;
  QList<AsciiSignalFormatComponent> _components;
  QList<AsciiSignalFormatRule> _rules;

  AsciiLineParser::Separators _separators;
  bool _quotes, _emptyValues, _hexadecimal;

  static bool _verbose;
};

} // namespace GeopsyCore

#endif // ASCIISIGNALFORMAT_H
