/***************************************************************************
**
**  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: 2006-07-09
**  Copyright: 2006-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <GeopsyCore.h>
#include <QGpCoreTools.h>

#include "GeopsyGuiEngine.h"
#include "CityLoader.h"
#include "CitySignalItem.h"

namespace GeopsyGui {

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

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

  _scanner=new CityScanner(this);
  // Create log stream for scanner thread
  Application::instance()->setStream(logView , _scanner);

  signalView->setModel(new CitySignalItem (_scanner, this) );
  signalView->setSelectionBehavior(QAbstractItemView::SelectRows);
  signalView->setSelectionMode(QAbstractItemView::ExtendedSelection);
  signalView->setEditTriggers(QAbstractItemView::NoEditTriggers);

  connect (pathEdit, SIGNAL(editTextChanged(const QString&)), this, SLOT(scan()));
  connect (_scanner, SIGNAL(beginSignalChange()), this, SLOT(beginSignalChange()), Qt::QueuedConnection);
  connect (_scanner, SIGNAL(endSignalChange()), this, SLOT(endSignalChange()), Qt::QueuedConnection);

#ifndef Q_OS_LINUX
  delete mountBut;
  mountBut=0;
  delete unmountBut;
  unmountBut=0;
#endif

  pathEdit->addItems(Settings::getHistory("CityFlashCardPath"));
}

/*!
  Description of destructor still missing
*/
CityLoader::~CityLoader()
{
  TRACE;
  logView->remove();
}

void CityLoader::scan()
{
  TRACE;
  if(!pathEdit->currentText().isEmpty()) {
    QDir d(pathEdit->currentText());
    logView->clear();
    _scanner->setPath(d);
  }
}

void CityLoader::beginSignalChange()
{
  TRACE;
  // File has been validated, add to history
  Settings::setHistory("CityFlashCardPath", pathEdit->currentText());

  CitySignalItem * item=qobject_cast<CitySignalItem *>(signalView->model());
  item->beginSignalChange();
}

void CityLoader::endSignalChange()
{
  TRACE;
  CitySignalItem * item=qobject_cast<CitySignalItem *>(signalView->model());
  item->endSignalChange();
  signalView->resizeColumnsToContents();
  signalView->resizeRowsToContents();
  cityInfo->setText(tr("Cityshark software version %1").arg(_scanner->softwareVersion()) );
}

void CityLoader::on_mountBut_clicked()
{
  TRACE;
#ifdef Q_OS_LINUX
  if(mountUnmount("mount")) {
    App::log(_scanner, tr("Flash card successfully mounted\n"));
    scan();
  }
#endif
}

void CityLoader::on_unmountBut_clicked()
{
  TRACE;
#ifdef Q_OS_LINUX
  emit beginSignalChange();
  _scanner->clear(); // Make sure scanner is not reading card
  if(mountUnmount("umount")) {    
    App::log(_scanner, tr("Flash card successfully unmounted\n"));
  }
  emit endSignalChange();
#endif
}

bool CityLoader::mountUnmount(const char * cmd)
{
  TRACE;
  if(!pathEdit->currentText().isEmpty()) {
    // File has been validated, add to history
    Settings::setHistory("CityFlashCardPath", pathEdit->currentText());
    QProcess p;
    QStringList args;
    args << pathEdit->currentText();
    p.setProcessChannelMode(QProcess::MergedChannels);
    p.start(cmd, args);
    int timeOut=5; // default wait 5 seconds
    while(true) {
      if(p.waitForFinished(timeOut * 1000) ) {
        if(p.exitCode()==0)
          return true;
      }
      switch (p.error()) {
      case QProcess::Timedout:
        if(Message::warning(MSG_ID, tr( "Unmounting/Mounting flash card" ), tr( "No responding after %1 seconds, do want to wait again?" ).arg(timeOut), Message::yes(), Message::no())==Message::Answer0) {
          timeOut *= 2;
        } else
          return false;
      default:
        Message::critical(MSG_ID, tr( "Unmounting/Mounting flash card" ), QString(p.readAllStandardOutput ()) );
        return false;
      }
    }
  }
  return false;
}

bool CityLoader::isAnySelected()
{
  TRACE;
  QItemSelectionModel & selModel=*signalView->selectionModel();
  bool isAnySelected=false;
  QModelIndex rIndex=signalView->rootIndex();
  int n=_scanner->count();
  for(int i=0;i < n;i++ ) {
    if(selModel.isRowSelected(i, rIndex) ) {
      isAnySelected=true;
      break;
    }
  }
  return isAnySelected;
}

void CityLoader::on_loadBut_clicked()
{
  TRACE;
  _scanner->cleanStop();
  SignalDatabase * db=GeopsyGuiEngine::instance()->database(parentWidget());
  ASSERT(db);

  bool selectAll=false;
  if( !isAnySelected()) {
    if(Message::question(MSG_ID, tr( "Loading flash card" ),
                               tr( "No files were selected, do you want to load all of them?" ),
                               Message::yes(), Message::cancel())==Message::Answer1) {
      return ;
    }
    selectAll=true;
  }

  QFile * stream=_scanner->readStream();
  SignalFilePool& fpool=db->filePool();
  SubSignalPool subPool;
  if(stream) {
    QItemSelectionModel & selModel=*signalView->selectionModel();
    QModelIndex rIndex=signalView->rootIndex();
    int n=_scanner->count();
    for(int i=0;i < n;i++ ) {
      if(selectAll || selModel.isRowSelected(i, rIndex) ) {
        if(_scanner->at(i)->loadSignals(db, stream)) {
          subPool.addFile(fpool.last());
          if(GeopsyCoreEngine::instance()->preferences()->oneWindowPerFile()) {
            SubSignalPool subPool;
            subPool.addFile(fpool.last());
            GeopsyCoreEngine::instance()->newSignalViewer(subPool);
          }
        }
      }
    }
    if(!GeopsyCoreEngine::instance()->preferences()->oneWindowPerFile() && !subPool.isEmpty()) {
      GeopsyCoreEngine::instance()->newSignalViewer(subPool);
    }
    delete stream;
  }
}

void CityLoader::on_closeBut_clicked()
{
  TRACE;
  _scanner->cleanStop();
  reject();
}

void CityLoader::on_clearBut_clicked()
{
  TRACE;
  if(Message::question(MSG_ID, tr("Erasing a flash card"),
                       tr("Do you really want to erase this flash card and loose all recorded data?"),
                       Message::yes(), Message::no())==Message::Answer0) {
    _scanner->cleanStop();
    _scanner->erase();
  }
}

void CityLoader::on_pathBrowse_clicked()
{
  TRACE;
  QString str=Message::getExistingDirectory(tr("Flash card directory"), pathEdit->currentText());
  if(!str.isEmpty()) {
    pathEdit->setEditText(str);
  }
}



} // namespace GeopsyGui
