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

#include <GeopsyGui.h>

#include "Preferences.h"
#include "geopsyVersion.h"
#include "MainWindow.h"
#include "ViewParamEditor.h"
#include "GeopsyGui.h"
#include "CustomAsciiFormatsEditor.h"
#include "ToolFactory.h"

/*
 *  Constructs a Preferences as a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'.
 *
 *  The dialog will by default be modeless, unless you set 'modal' to
 *  true to construct a modal dialog.
 */
Preferences::Preferences(QWidget *parent, Qt::WindowFlags f)
    : Dialog(parent, f)
{
  TRACE;
  setupUi(this);

  GeopsyPluginSettings reg;
  QStringList paths=reg.paths();
  pathList->addItems(paths);
  setPluginList(reg.pluginList());

  QList< QPair<QString, SignalFileFormat> > formats=SignalFileFormat::importList();
  for(int i=0; i<formats.count(); i++) {
     fileFormat->addItem(formats.at(i).first);
  }
}

/*
 *  Destroys the object and frees any allocated resources
 */
Preferences::~Preferences()
{
  TRACE;
  // no need to delete child widgets, Qt does it all for us
}

void Preferences::updateAll()
{
  TRACE;
  on_formatFixed_toggled();
  on_winDoIt_toggled();
  on_graphicMakeUpSwitch_toggled();
  on_mapMakeUpSwitch_toggled();
  on_chronogramMakeUpSwitch_toggled();
}

void Preferences::on_formatFixed_toggled()
{
  TRACE;
  fileFormat->setEnabled(formatFixed->isChecked());
}

/*!
  Edits list of custom ASCII formats
*/
void Preferences::on_formatCustomAscii_clicked()
{
  TRACE;
  CustomAsciiFormatsEditor * d=new CustomAsciiFormatsEditor(this);
  CustomFileFormats * f=GeopsyCoreEngine::instance()->customFileFormats();
  if(d->exec()==QDialog::Accepted) {
    f->save();
  }
  f->restore();
  delete d;
}

void Preferences::on_winDoIt_toggled()
{
  TRACE;
  winNofFiles->setEnabled(winDoIt->isChecked());
}

void Preferences::on_stationNameFile_clicked()
{
  TRACE;
  if(stationNameFile->isChecked()) stationNameRxxx->setChecked(false);
}

void Preferences::on_stationNameRxxx_clicked()
{
  TRACE;
  if(stationNameRxxx->isChecked()) stationNameFile->setChecked(false);

}

void Preferences::saveToolList()
{
  TRACE;
  QStringList paths=getPaths();
  GeopsyPluginSettings reg;
  reg.setPaths(paths);
  QStringList tools=getTools();
  reg.setPluginList(tools);
}

void Preferences::on_searchTool_clicked()
{
  TRACE;
  QStringList paths=getPaths();
  toolList->clear();
  bool ok;
  QStringList plugins=GeopsyPlugins::getList(File::getLibList(paths), ok);
  if(ok) {
    if(plugins.isEmpty()) {
      QString dll;
#ifdef Q_OS_MAC
      dll="/Library/Geopsy/plugins";
#else
      const PackageInfo * p=PackageInfo::package("geopsy");
      if(p) {
        dll=p->dllDir();
      }
#endif
      Message::warning(MSG_ID, tr("Searching plugins"), tr("No plugin found in your search path(s). Search for plugins is not recursive, so "
                                                           "you must select the exact path of library installation (e.g. %1).")
                                                          .arg(dll));
    } else {
      setPluginList(plugins);
      Message::information(MSG_ID, tr("Searching plugins"), tr("Restart geopsy now to enjoy the new plugins."));
    }
  } else {
    Message::warning(MSG_ID, tr("Searching plugins"), tr("One ore more plugins in your search path(s) are "
                         "not compatible with this geopsy version. It is likely that old versions of plugins "
                         "were not de-installed properly."));
  }
}

void Preferences::on_addSep_clicked()
{
  TRACE;
  ToolSeparator tool;
  QListWidgetItem * item=new QListWidgetItem(tool.title());
  item->setData(32, "");
  toolList->addItem(item);
}

void Preferences::on_removeTool_clicked()
{
  TRACE;
  if(toolList->currentRow() >= 0)
    delete toolList->takeItem(toolList->currentRow());
}

void Preferences::on_moveToolUp_clicked()
{
  TRACE;
  int i=toolList->currentRow();
  if(i > 0) {
    QListWidgetItem * item=toolList->takeItem(i);
    toolList->insertItem(i - 1, item);
  }
}

void Preferences::on_moveToolDown_clicked()
{
  TRACE;
  int i=toolList->currentRow();
  if(i >= 0 && i < (int) toolList->count() - 1) {
    QListWidgetItem * item=toolList->takeItem(i);
    toolList->insertItem(i + 1, item);
  }
}

void Preferences::on_addPath_clicked()
{
  TRACE;
  QString path=Message::getExistingDirectory(tr( "Add plugin search path" ));
  if( !path.isEmpty()) pathList->addItem(path);
}

void Preferences::on_removePath_clicked()
{
  TRACE;
  delete pathList->takeItem(pathList->currentRow());
}

QStringList Preferences::getPaths()
{
  TRACE;
  QStringList paths;
  int n=pathList->count();
  for(int i=0;i < n;i++ ) {
    paths << pathList->item(i) ->text();
  }
  return paths;
}

QStringList Preferences::getTools()
{
  TRACE;
  QStringList toolFiles;
  int n=toolList->count();
  for(int i=0;i < n;i++ ) {
    toolFiles << toolList->item(i) ->data(32).toString();
  }
  return toolFiles;
}

void Preferences::setPluginList(QStringList plugins)
{
  TRACE;
  int n=plugins.count();

  for(int i=0;i < n;i++ ) {
    QString libFile=plugins.at(i);
    if(libFile.isEmpty()) {
      on_addSep_clicked();
    } else {
      GeopsyCoreInterface * p= GeopsyPlugins::load(libFile);
      if(p) {
        if(p->isValid()) {
          QListWidgetItem * item=new QListWidgetItem(p->title());
          item->setWhatsThis(p->description());
          item->setData(32, libFile);
          toolList->addItem(item);
        }
        CoreApplication::instance()->deletePlugin(p);
      }
    }
  }
}

void Preferences::on_cacheSwapDirBut_clicked()
{
  TRACE;
  QString path=Message::getExistingDirectory(tr( "Swap folder" ));
  if( !path.isEmpty()) cacheSwapDir->setText(path);
}

void Preferences::on_fileDefaults_clicked()
{
  TRACE;
  GeopsyCoreEngine::instance()->preferences()->restoreFileDefaults();
  GeopsyPreferences * prefs=GeopsyCoreEngine::instance()->preferences();

  formatAsk->setChecked(prefs->askForFormat());
  formatFixed->setChecked(!prefs->askForFormat());
  QList<QPair<QString, SignalFileFormat> > formats=SignalFileFormat::importList();
  QPair<QString, SignalFileFormat> formatPair;
  formatPair.first=prefs->fileFormat().captionFilter();
  formatPair.second=prefs->fileFormat();
  formats.indexOf(formatPair);
  fileFormat->setCurrentIndex(formats.indexOf(formatPair));
  winDoIt->setChecked(prefs->viewIfFewFiles());
  winNofFiles->setValue(prefs->maxNofFiles());
  winTable->setChecked(prefs->showTable());
  winGraphic->setChecked(prefs->showGraphic());
  oneWindowPerFile->setChecked(prefs->oneWindowPerFile());
  stationNameFile->setChecked(prefs->stationNameFile());
  stationNameRxxx->setChecked(prefs->stationNameRxxx());
  updateAll();
}

void Preferences::on_poolDefaults_clicked()
{
  TRACE;
  GeopsyCoreEngine::instance()->preferences()->restorePoolDefaults();
  GeopsyPreferences * prefs=GeopsyCoreEngine::instance()->preferences();
  cacheSize->setValue(prefs->cacheSize());
  cacheSwapDir->setText(prefs->cacheSwapDir());
}

void Preferences::on_graphicMakeUpSwitch_toggled()
{
  TRACE;
  bool b=graphicMakeUpSwitch->isChecked();
  graphicMakeUpEdit->setEnabled(b);
  graphicMakeUpBrowse->setEnabled(b);
}

void Preferences::on_graphicMakeUpBrowse_clicked()
{
  TRACE;
  QString fileName=Message::getOpenFileName(tr("Make-up for graphics"), tr("Graph make-up (*.mkup)"));
  if( !fileName.isEmpty()) graphicMakeUpEdit->setText(fileName);
}

void Preferences::on_mapMakeUpSwitch_toggled()
{
  TRACE;
  bool b=mapMakeUpSwitch->isChecked();
  mapMakeUpEdit->setEnabled(b);
  mapMakeUpBrowse->setEnabled(b);
}

void Preferences::on_mapMakeUpBrowse_clicked()
{
  TRACE;
  QString fileName=Message::getOpenFileName(tr("Make-up for maps"), tr("Graph make-up (*.mkup)"));
  if( !fileName.isEmpty()) mapMakeUpEdit->setText(fileName);
}

void Preferences::on_chronogramMakeUpSwitch_toggled()
{
  TRACE;
  bool b=chronogramMakeUpSwitch->isChecked();
  chronogramMakeUpEdit->setEnabled(b);
  chronogramMakeUpBrowse->setEnabled(b);
}

void Preferences::on_chronogramMakeUpBrowse_clicked()
{
  TRACE;
  QString fileName=Message::getOpenFileName(tr("Make-up for chronograms"), tr("Graph make-up (*.mkup)"));
  if( !fileName.isEmpty()) chronogramMakeUpEdit->setText(fileName);
}
