/***************************************************************************
**
**  This file is part of GeopsyGui.
**
**  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: 2009-10-20
**  Copyright: 2009-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QtGui>
#include <GeopsyCore.h>

#include "AsciiSignalFormatEditor.h"
#include "AsciiSignalRulesWidget.h"
#include "AsciiSignalComponentsWidget.h"
#include "GeopsyGuiEngine.h"

namespace GeopsyGui {

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

  Full description of class still missing
*/



/*!
  Description of constructor still missing
*/
AsciiSignalFormatEditor::AsciiSignalFormatEditor(QWidget * parent, Qt::WindowFlags f)
    : Dialog(parent, f)
{
  TRACE;
  setupUi(this);
  exampleErrors->setMinimumLineCount(5);
  _reader=new AsciiSignalFormatReader(this);
  Application::instance()->setStream(exampleErrors , _reader);
  connect(_reader, SIGNAL(dataChanged()), this, SLOT(readerReady()));
  on_headerType_currentIndexChanged(0);
  _rules=new AsciiSignalRulesWidget(this, Qt::Window);
  _rules->setFormat(&_format);
  _rules->setExampleErrors(exampleErrors);
  _rules->hide();
  _components=new AsciiSignalComponentsWidget(this, Qt::Window);
  _components->setFormat(&_format);
  _components->setReader(_reader);
  _components->hide();

  QStringList sep;
  sep << tr("TAB") << tr("Space") << tr("Coma") << tr("Semicolon");
  separators->addItems(sep);
}

/*!
  Description of destructor still missing
*/
AsciiSignalFormatEditor::~AsciiSignalFormatEditor()
{
  TRACE;
  exampleErrors->remove();
  delete _rules;
  delete _components;
  _reader->stop();
}

void AsciiSignalFormatEditor::readerReady()
{
  TRACE;
  exampleHeader->setPlainText(_reader->header());
  _rules->setHeader(_reader->header());
}

void AsciiSignalFormatEditor::setFormat(const AsciiSignalFormat& f)
{
  TRACE;
  _format=f;
  nameEdit->setText(_format.caption());
  suffixEdit->setText(_format.suffixList().join(","));
  switch(_format.headerType()) {
  case AsciiSignalFormat::NoHeader:
    headerType->setCurrentIndex(0);
    break;
  case AsciiSignalFormat::FixedHeader:
    headerType->setCurrentIndex(1);
    break;
  case AsciiSignalFormat::HeaderPattern:
    headerType->setCurrentIndex(2);
    break;
  case AsciiSignalFormat::EndHeaderPattern:
    headerType->setCurrentIndex(3);
    break;
  }
  headerCount->setValue(_format.headerLineCount());
  headerPattern->setText(_format.headerPattern());
  timeFormat->setText(_format.timeFormat());
  _rules->setFormat(&_format);
  _components->setFormat(&_format);
  separators->setCurrentItems(AsciiLineParser::separatorsToUserString(_format.separators()));
  skipEmpty->setChecked(!_format.emptyValues());
  quotes->setChecked(_format.quotes());
  hexadecimal->setChecked(_format.hexadecimal());

  _reader->setFormat(_format);
  _reader->setFileName(exampleEdit->text());

  on_nameEdit_textChanged();
  on_headerType_currentIndexChanged(0);
}

void AsciiSignalFormatEditor::on_suffixEdit_editingFinished()
{
  TRACE;
  _format.clearSuffixList();
  _format.addSuffixList(suffixEdit->text());
}

void AsciiSignalFormatEditor::on_nameEdit_textChanged()
{
  TRACE;
  _format.setCaption(nameEdit->text());
  _format.setName(nameEdit->text());
  setWindowTitle(tr("ASCII Signal Format - ")+_format.name());
}

void AsciiSignalFormatEditor::on_headerType_currentIndexChanged(int)
{
  TRACE;
  switch(headerType->currentIndex()) {
  case 1:
    headerCount->show();
    headerPattern->hide();
    _format.setHeaderType(AsciiSignalFormat::FixedHeader);
    break;
  case 2:
    headerCount->hide();
    headerPattern->show();
    _format.setHeaderType(AsciiSignalFormat::HeaderPattern);
    break;
  case 3:
    headerCount->hide();
    headerPattern->show();
    _format.setHeaderType(AsciiSignalFormat::EndHeaderPattern);
    break;
  default:
    headerCount->hide();
    headerPattern->hide();
    _format.setHeaderType(AsciiSignalFormat::NoHeader);
    break;
  }
  _reader->setFormat(_format);
}

void AsciiSignalFormatEditor::on_headerPattern_textChanged(const QString& text)
{
  TRACE;
  _format.setHeaderPattern(text);
  _reader->setFormat(_format);
}

void AsciiSignalFormatEditor::on_headerCount_valueChanged(int value)
{
  TRACE;
  _format.setHeaderLineCount(value);
  _reader->setFormat(_format);
}

void AsciiSignalFormatEditor::on_timeFormat_textChanged(const QString& text)
{
  TRACE;
  _format.setTimeFormat(text);
  _reader->setFormat(_format);
}

void AsciiSignalFormatEditor::on_quotes_stateChanged()
{
  TRACE;
  _format.setQuotes(quotes->isChecked());
  _reader->setFormat(_format);
}

void AsciiSignalFormatEditor::on_hexadecimal_stateChanged()
{
  TRACE;
  _format.setHexadecimal(hexadecimal->isChecked());
  _reader->setFormat(_format);
}

void AsciiSignalFormatEditor::on_skipEmpty_stateChanged()
{
  TRACE;
  _format.setEmptyValues(!skipEmpty->isChecked());
  _reader->setFormat(_format);
}

void AsciiSignalFormatEditor::on_separators_currentTextChanged(const QString&)
{
  TRACE;
  _format.setSeparators(AsciiLineParser::userStringToSeparators(separators->currentText()));
  _reader->setFormat(_format);
}

void AsciiSignalFormatEditor::on_rulesButton_clicked()
{
  TRACE;
  _rules->show();
  _rules->raise();
  _rules->setFocus();
}

void AsciiSignalFormatEditor::on_componentsButton_clicked()
{
  TRACE;
  _components->show();
  _components->raise();
  _components->setFocus();
}

void AsciiSignalFormatEditor::on_exampleEdit_textChanged()
{
  TRACE;
  _reader->setFileName(exampleEdit->text());
}

void AsciiSignalFormatEditor::on_exampleButton_clicked()
{
  TRACE;
  QString fileName=Message::getOpenFileName(tr("Load Signals"), tr("Signal file (%1)")
                                              .arg(_format.suffixFilter()));
  if(!fileName.isEmpty()) {
    exampleEdit->setText(fileName);
    _reader->setFileName(fileName);
  }
}

void AsciiSignalFormatEditor::on_helpButton_clicked()
{
  TRACE;
  QUrl doc("http://www.geopsy.org/wiki/index.php/Geopsy:_Custom_ASCII_formats");
  QDesktopServices::openUrl(doc);
}

void AsciiSignalFormatEditor::on_loadButton_clicked()
{
  TRACE;
  StreamRedirection sr(exampleErrors);
  exampleErrors->clear();
  SignalDatabase * db=GeopsyGuiEngine::instance()->database(this);
  AsciiSignalFormat::setVerbose(true);
  _format.addReference();
  // Loading of file has good chance to fail, file may be loaded with no signal
  // inside. Hence, classible load() may return an empty SubsignalPool not meaning
  // that no SignalFile has been created. Thus, we use the low level API.
  SignalFile * f=new SignalFile(db, exampleEdit->text(), SignalFileFormat(SignalFileFormat::Ascii, &_format));
  if(f->load()) {
    SubSignalPool s;
    s.addFile(f);
    App::log(tr("No error while loading file, %1 signal available.\n"
                "Note that it does mean that loading was fully successful.\n"
                "Still check above log!\n")
                  .arg(s.count()));
  } else {
    App::log(tr("Error while loading file, see above log.\n") );
  }
  db->removeFile(f);
  _format.removeReference();
  AsciiSignalFormat::setVerbose(false);
}

} // namespace GeopsyGui
