/***************************************************************************
**
**  This file is part of QGpCoreTools.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This file 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 Lesser General Public
**  License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2011-09-20
**  Copyright: 2011-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#ifndef ASCIILINEPARSER_H
#define ASCIILINEPARSER_H

#include <QtCore>

#include "QGpCoreToolsDLLExport.h"

namespace QGpCoreTools {

  class QGPCORETOOLS_EXPORT AsciiLineParser
  {
  public:
    AsciiLineParser(char * buffer, int size, int nColumns=1);
    AsciiLineParser(QByteArray * buffer, int nColumns=1);
    ~AsciiLineParser();

    enum Separator {None=0x00, Tab=0x01, Space=0x02, Coma=0x04, Semicolon=0x08};
    Q_DECLARE_FLAGS(Separators, Separator)

    void setSeparators(Separators s) {_separators=s;}
    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 setColumnCount(int n);
    void readLine();
    bool readColumn(int index);
    bool readColumns(int count, int *columns);
    void countColumns();
    void reset() {_index=0;}
    void reset(QByteArray * buffer);
    void reset(char * buffer, int size);
    bool atEnd() const {return _index>=_bufferSize;}

    int count() const {return _valueCount;}

    inline int toInt(int index=0);
    inline qint64 hexaToInt(int index=0);
    inline double toDouble(int index=0);
    inline QString toString(int index=0);

    int toInt(int begin, int count);
    double toDouble(int begin, int count);
    inline QString toString(int begin, int count);

    static Separators stringToSeparators(const QString& s);
    static QString separatorsToString(Separators s);
    static Separators userStringToSeparators(const QString& s);
    static QString separatorsToUserString(Separators s);
  private:
    void defaultOptions();
    inline bool readValue(int index, bool nextLine, bool& endOfLine);
    inline void skipValue(bool& endOfLine);
    inline int skipSingleQuoted(int iBeginBuffer);
    inline int skipDoubleQuoted(int iBeginBuffer);

    bool _emptyValues, _quotes;
    Separators _separators;
    char * _buffer;
    int _bufferSize;
    int _index;
    int _maximumValueCount;
    int _valueCount;
    char ** _values;
  };

  inline int AsciiLineParser::toInt(int index)
  {
    return atoi(_values[index]);
  }

  inline double AsciiLineParser::toDouble(int index)
  {
    return atof(_values[index]);
  }

  inline qint64 AsciiLineParser::hexaToInt(int index)
  {
    return strtol(_values[index], 0, 16);
  }

  inline QString AsciiLineParser::toString(int index)
  {
    return QString::fromLatin1(_values[index]);
  }

  inline QString AsciiLineParser::toString(int begin, int count)
  {
    return QString::fromLatin1(_buffer+begin, count);
  }

} // namespace QGpCoreTools

Q_DECLARE_OPERATORS_FOR_FLAGS(QGpCoreTools::AsciiLineParser::Separators)

#endif // ASCIILINEPARSER_H
