/***************************************************************************
**
**  This file is part of QGpGuiTools.
**
**  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: 2008-07-11
**  Copyright: 2008-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "ColumnTextWidget.h"
#include "ColumnTextItem.h"
#include "Settings.h"
#include "ColumnTextDelegate.h"
#include "ColumnTextLinesProperties.h"
#include "ColumnTextColumnsProperties.h"
#include "ColumnTextSectionsProperties.h"

namespace QGpGuiTools {

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

    Initialized with a default parser (of type ColumnTextParser), it can be
    customized with any parser derived from ColumnTextParser with setParser().
  */

  /*!
    Description of constructor still missing
  */
  ColumnTextWidget::ColumnTextWidget(QWidget * parent)
      : QWidget(parent)
  {
    TRACE;
    setupUi(this);

    ColumnTextItem * itemModel=new ColumnTextItem(this);
    connect(itemModel, SIGNAL(typeChanged()), this, SIGNAL(typeChanged()));
    fileView->setModel(itemModel);
    fileView->setItemDelegate(new ColumnTextDelegate(this));
    fileView->setSelectionMode(QAbstractItemView::SingleSelection);
    fileView->setEditTriggers(QAbstractItemView::AllEditTriggers);

    _fileEngine=0;
    setFileEngine(new ColumnTextFile);
  }

  /*!
    Description of destructor still missing
  */
  ColumnTextWidget::~ColumnTextWidget()
  {
    TRACE;
    if(_fileEngine && !_fileEngine->parserFile().isEmpty()) {
      QFileInfo fi(_fileEngine->parserFile());
      Settings::setColumnWidth(fileView, "ColumnTextParsers/"+fi.baseName());
    }
    delete _fileEngine;
  }

  /*!
    Initialize parser.
    If ColumnTextParser::standardTypes() must be changed after initialization, you have to use
    ColumnTextWidget::setStandardTypes() rather than ColumnTextParser::setStandardTypes() directly.
  */
  void ColumnTextWidget::setFileEngine(ColumnTextFile * f)
  {
    TRACE;
    delete _fileEngine;
    _fileEngine=f;
    connect(_fileEngine, SIGNAL(typeChanged()), this, SIGNAL(typeChanged()));
    connect(_fileEngine, SIGNAL(parserFileChanged(const QString&)), this, SLOT(parserFileChanged(const QString&)));

    connect(_fileEngine, SIGNAL(rowsParsed()), this, SLOT(restoreColumnWidths()));
    static_cast<ColumnTextItem *>(fileView->model())->setParser(_fileEngine);
    static_cast<ColumnTextDelegate *>(fileView->itemDelegate())->setTypes(_fileEngine->standardTypes());
  }

  /*!
    Called only once after any parser file change (setParserFile()) through
    signal/slot mechanism if parser rowsParsed() is triggered.
  */
  void ColumnTextWidget::restoreColumnWidths()
  {
    TRACE;
    if(!_restoreColumnWidth.isEmpty()) {
      Settings::columnWidth(fileView, _restoreColumnWidth);
      _restoreColumnWidth="";
    }
  }

  void ColumnTextWidget::setStandardTypes(const QStringList& t)
  {
    TRACE;
    _fileEngine->setStandardTypes(t);
    static_cast<ColumnTextDelegate *>(fileView->itemDelegate())->setTypes(_fileEngine->standardTypes());
  }

  void ColumnTextWidget::on_linesBut_clicked()
  {
    TRACE;
    ColumnTextLinesProperties * d=new ColumnTextLinesProperties(this);
    Settings::getRect(d, "ColumnTextLinesProperties" );
    d->isStartLine->setChecked(_fileEngine->startLine()>0);
    d->isEndLine->setChecked(_fileEngine->endLine()>0);
    d->startLine->setValue(_fileEngine->startLine());
    d->endLine->setValue(_fileEngine->endLine());
    d->acceptPattern->setText(_fileEngine->acceptPattern());
    d->rejectPattern->setText(_fileEngine->rejectPattern());
    d->hasComments->setChecked(_fileEngine->hasComments());
    d->updateWidgets();
    if(d->exec()==QDialog::Accepted) {
      Settings::setRect(d, "ColumnTextLinesProperties" );
      _fileEngine->stopUpdates();
      _fileEngine->setStartLine(d->isStartLine->isChecked() ? d->startLine->value() : 0);
      _fileEngine->setEndLine(d->isEndLine->isChecked() ? d->endLine->value() : 0);
      _fileEngine->setAcceptPattern(d->acceptPattern->text());
      _fileEngine->setRejectPattern(d->rejectPattern->text());
      _fileEngine->setHasComments(d->hasComments->isChecked());
      _fileEngine->startUpdates();
    }
    delete d;
  }

  void ColumnTextWidget::on_parserName_editTextChanged(const QString& text)
  {
    TRACE;
    _fileEngine->setParserFile(text);
  }

  void ColumnTextWidget::on_columnsBut_clicked()
  {
    TRACE;
    ColumnTextColumnsProperties * d=new ColumnTextColumnsProperties(this);
    Settings::getRect(d, "ColumnTextColumnsProperties");
    if(_fileEngine->isFixedWidth()) {
      d->fixedWidthsOption->setChecked(true);
    } else {
      d->delimitersOption->setChecked(true);
    }
    d->tabDelimiter->setChecked(_fileEngine->delimiters().contains("\t"));
    d->spaceDelimiter->setChecked(_fileEngine->delimiters().contains(" "));
    d->otherDelimiters->setText(_fileEngine->delimiters().replace(QRegExp("[ \t]"),""));
    d->acceptNullColumns->setChecked(_fileEngine->acceptNullColumns());
    d->maximumColumnCount->setValue(_fileEngine->maximumColumnCount());
    d->columnWidths->setText(_fileEngine->columnWidths());
    d->updateWidgets();
    if(d->exec()==QDialog::Accepted) {
      Settings::setRect(d, "ColumnTextColumnsProperties");
      _fileEngine->stopUpdates();
      _fileEngine->setFixedWidth(d->fixedWidthsOption->isChecked());
      _fileEngine->setDelimiters(d->delimiters());
      _fileEngine->setAcceptNullColumns(d->acceptNullColumns->isChecked());
      _fileEngine->setMaximumColumnCount(d->maximumColumnCount->value());
      _fileEngine->setColumnWidths(d->columnWidths->text());
      _fileEngine->startUpdates();
    }
    delete d;
  }

  void ColumnTextWidget::on_sectionsBut_clicked()
  {
    TRACE;
    ColumnTextSectionsProperties * d=new ColumnTextSectionsProperties(this);
    Settings::getRect(d, "ColumnTextSectionsProperties" );
    d->isLinePattern->setChecked(_fileEngine->isSectionLinePattern());
    d->linePattern->setText(_fileEngine->sectionLinePattern());
    d->isLineCount->setChecked(_fileEngine->isSectionLineCount());
    d->lineCount->setValue(_fileEngine->sectionLineCount());
    d->isRowCount->setChecked(_fileEngine->isSectionRowCount());
    d->rowCount->setValue(_fileEngine->sectionRowCount());
    d->isCellPattern->setChecked(_fileEngine->isSectionCellPattern());
    d->cellColumn->setValue(_fileEngine->sectionCellColumn());
    d->cellPattern->setText(_fileEngine->sectionCellPattern());
    d->updateWidgets();
    if(d->exec()==QDialog::Accepted) {
      Settings::setRect(d, "ColumnTextSectionsProperties" );
      _fileEngine->stopUpdates();
      _fileEngine->setSectionLinePattern(d->isLinePattern->isChecked());
      _fileEngine->setSectionLinePattern(d->linePattern->text());
      _fileEngine->setSectionLineCount(d->isLineCount->isChecked());
      _fileEngine->setSectionLineCount(d->lineCount->value());
      _fileEngine->setSectionRowCount(d->isRowCount->isChecked());
      _fileEngine->setSectionRowCount(d->rowCount->value());
      _fileEngine->setSectionCellPattern(d->isCellPattern->isChecked());
      _fileEngine->setSectionCellColumn(d->cellColumn->value());
      _fileEngine->setSectionCellPattern(d->cellPattern->text());
      _fileEngine->startUpdates();
    }
    delete d;
  }

  void ColumnTextWidget::on_loadBut_clicked()
  {
    TRACE;
    QString str=Message::getOpenFileName(tr("Load parser"),
                                           tr("Column text parser (*.ctparser)"));
    _fileEngine->setParserFile(str);
  }

  void ColumnTextWidget::on_saveBut_clicked()
  {
    TRACE;
    QString str=Message::getSaveFileName(tr("Save parser"), tr("Column text parser (*.ctparser)"));
    if(!str.isEmpty()) {
      XMLHeader hdr(_fileEngine);
      hdr.xml_saveFile(str);
      _fileEngine->setParserFile(str);
      parserName->setEditText(str);
    }
  }

  void ColumnTextWidget::restoreParserSettings()
  {
    QSettings& reg=CoreApplicationPrivate::instance()->globalSettings();
    reg.beginGroup("ColumnTextParsers");
    parserName->addItems(Settings::getHistory(reg, objectName()));
  }

  void ColumnTextWidget::saveParserSettings()
  {
    QSettings& reg=CoreApplicationPrivate::instance()->globalSettings();
    reg.beginGroup("ColumnTextParsers");
    Settings::setHistory(reg, objectName(), _fileEngine->parserFile());
  }

  void ColumnTextWidget::parserFileChanged(const QString& pf)
  {
    QFileInfo fi(pf);
    _restoreColumnWidth="ColumnTextParsers/"+fi.baseName();
    parserName->setEditText(pf);
    saveParserSettings();
  }

} // namespace QGpGuiTools
