/***************************************************************************
**
**  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: 2010-08-06
**  Copyright: 2010-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#include "Engine.h"
#include "ToolFactory.h"
#include "MainWindow.h"
#include "TableWindow.h"
#include "GraphicWindow.h"
#include "ChronogramWindow.h"
#include "MapWindow.h"


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

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
Engine::Engine()
  : GeopsyGuiEngine()
{
}

/*!
  Description of destructor still missing
*/
Engine::~Engine()
{
}

/*!
  Scan all parents of \a w for a MainWindow, if found returns the attached database.
*/
SignalDatabase * Engine::database(QWidget * w)
{
  TRACE;
  MainWindow * mw=static_cast<MainWindow *>(WindowEnvironment::instance()->window(w));
  if(mw) {
    return mw->database();
  } else {
    return nullptr;
  }
}

/*!
  This slot is called whenever a signal is modified.
*/
void Engine::beginSignalChange(Signal * sig)
{
  TRACE;
  if(WindowEnvironment::instance()) {
    MainWindow * mw=WindowEnvironment::window(sig->database());
    QList<MultiDocumentSubWindow *> windows=mw->subWindowList();
    for(QList<MultiDocumentSubWindow *>::iterator it=windows.begin(); it!=windows.end(); it++) {
      SubPoolWindow * spw=qobject_cast<SubPoolWindow *>((*it)->widget());
      if(spw && spw->subPool().contains(sig)) {
        spw->beginSignalChange(sig);
      }
    }
  }
}

/*!
  This slot is call whenever a signal is modified.
*/
void Engine::endSignalChange(Signal * sig)
{
  TRACE;
  if(WindowEnvironment::instance()) {
    MainWindow * mw=WindowEnvironment::window(sig->database());
    QList<MultiDocumentSubWindow *> windows=mw->subWindowList();
    for(QList<MultiDocumentSubWindow *>::iterator it=windows.begin(); it!=windows.end(); it++) {
      SubPoolWindow * spw=qobject_cast<SubPoolWindow *>((*it)->widget());
      if(spw && spw->subPool().contains(sig)) {
        spw->endSignalChange(sig);
      }
    }
  }
}

/*!
  This slot is call whenever a signal is modified.
*/
void Engine::beginSignalChange(SignalDatabase * db)
{
  TRACE;
  if(WindowEnvironment::instance()) {
    MainWindow * mw=WindowEnvironment::window(db);
    QList<MultiDocumentSubWindow *> windows=mw->subWindowList();
    for(QList<MultiDocumentSubWindow *>::iterator it=windows.begin(); it!=windows.end(); it++) {
      SubPoolWindow * spw=qobject_cast<SubPoolWindow *>((*it)->widget());
      if(spw) {
        spw->beginSignalChange();
      }
    }
  }
}

/*!
  This slot is call whenever a signal is modified.
*/
void Engine::endSignalChange(SignalDatabase * db)
{
  TRACE;
  if(WindowEnvironment::instance()) {
    MainWindow * mw=WindowEnvironment::window(db);
    QList<MultiDocumentSubWindow *> windows=mw->subWindowList();
    for(QList<MultiDocumentSubWindow *>::iterator it=windows.begin(); it!=windows.end(); it++) {
      SubPoolWindow * spw=qobject_cast<SubPoolWindow *>((*it)->widget());
      if(spw) {
        spw->endSignalChange();
      }
    }
  }
}

void Engine::beginAddFile(SignalDatabase * db)
{
  TRACE;
  if(WindowEnvironment::instance()) {
    MainWindow * mw=WindowEnvironment::window(db);
    mw->beginAddFile();
  }
}

void Engine::endAddFile(SignalDatabase * db)
{
  TRACE;
  if(WindowEnvironment::instance()) {
    MainWindow * mw=WindowEnvironment::window(db);
    mw->endAddFile();
  }
}

SubPoolWindow * Engine::newTableWindow(QWidget * parent, const SubSignalPool& subPool)
{
  TRACE;
  if(!parent) {
    parent=WindowEnvironment::instance()->currentTab();
  }
  TableWindow * w=new TableWindow(parent);
  addSubWindow(parent, w);
  w->setSubPool(subPool);
  return w;
}

AbstractGraphicWindow * Engine::newGraphicWindow(QWidget * parent, const SubSignalPool& subPool)
{
  TRACE;
  if(!parent) {
    parent=WindowEnvironment::instance()->currentTab();
  }
  GraphicWindow * w=new GraphicWindow(parent);
  addSubWindow(parent, w);
  w->setSubPool(subPool);
  w->show();
  return w;
}

SubPoolWindow * Engine::newMapWindow(QWidget * parent, const SubSignalPool& subPool)
{
  TRACE;
  if(!parent) {
    parent=WindowEnvironment::instance()->currentTab();
  }
  MapWindow * w=new MapWindow(parent);
  addSubWindow(parent, w);
  w->setSubPool(subPool);
  return w;
}

SubPoolWindow * Engine::newChronogramWindow(QWidget * parent, const SubSignalPool& subPool)
{
  TRACE;
  if(!parent) {
    parent=WindowEnvironment::instance()->currentTab();
  }
  ChronogramWindow * w=new ChronogramWindow(parent);
  addSubWindow(parent, w);
  w->setSubPool(subPool);
  return w;
}

void Engine::newSignalViewer(const SubSignalPool& subPool)
{
  QWidget * parent=WindowEnvironment::instance()->currentTab();
  if(preferences()->showTable()) {
    newTableWindow(parent, subPool);
  }
  if(preferences()->showGraphic()) {
    newGraphicWindow(parent, subPool);
  }
}

QWidgetList Engine::subWindowList(QWidget * parent) const
{
  TRACE;
  WindowEnvironment * e=WindowEnvironment::instance();
  if(!parent) {
    parent=e->currentWindow();
  }
  MainWindow * mw=e->window(parent);
  QWidgetList wl;
  if(mw) {
    QList<MultiDocumentSubWindow *> l=mw->subWindowList();
    for(QList<MultiDocumentSubWindow *>::iterator it=l.begin(); it!=l.end(); it++) {
      wl.append((*it)->widget());
    }
  }
  return wl;
}

void Engine::setProgressMaximum(SignalDatabase * db, int value)
{
  if(WindowEnvironment::instance()) {
    WindowEnvironment::window(db)->setProgressMaximum(value);
  }
}

int Engine::progressMaximum(SignalDatabase * db)
{
  if(WindowEnvironment::instance()) {
    return WindowEnvironment::window(db)->progressMaximum();
  } else {
    return 0;
  }
}

void Engine::setProgressValue(SignalDatabase * db, int value)
{
  if(WindowEnvironment::instance()) {
    WindowEnvironment::window(db)->setProgressValue(value);
  }
}

int Engine::progressValue(SignalDatabase * db)
{
  if(WindowEnvironment::instance()) {
    return WindowEnvironment::window(db)->progressValue();
  } else {
    return 0;
  }
}

void Engine::increaseProgressValue(SignalDatabase * db, int value)
{
  if(WindowEnvironment::instance()) {
    WindowEnvironment::window(db)->increaseProgressValue(value);
  }
}

void Engine::showMessage(SignalDatabase * db, QString message)
{
  if(WindowEnvironment::instance()) {
    WindowEnvironment::window(db)->showMessage(message);
  }
}

