/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#include "DataRequestViewWidget.h"
#include "ui_DataRequestView.h"

#include <QList>
#include <QLayout>

#include <QDebug>
#include <QMdiArea>
#include <QMdiSubWindow>
#include "PlotSetWidget.h"

#include "PulsePhysiologyEngine.h"
#include "PulseScenario.h"
#include "engine/SEEngineTracker.h"
#include "engine/SEDataRequestManager.h"

class QDataRequestViewWidget::Controls : public Ui::DataRequestViewWidget
{
public:
  Controls(QPulse& qp) : Pulse(qp),
                         DataRequestManager(qp.GetEngine().GetLogger()) {}
  QPulse&                Pulse;
  SEDataRequestManager   DataRequestManager;
};

QDataRequestViewWidget::QDataRequestViewWidget(QPulse& qp, QWidget *parent, Qt::WindowFlags flags) : QDockWidget(parent, flags)
{
  m_Controls = new Controls(qp);
  m_Controls->setupUi(this);

  PlotWidget = nullptr;
  EnableControls(false);
  m_Controls->mdiArea->setOption(QMdiArea::DontMaximizeSubWindowOnActivation);
  qp.GetEngine().GetEngineTracker()->SetTrackMode(TrackMode::Dynamic);
  connect(m_Controls->NewPlotSetButton, SIGNAL(clicked()), SLOT(NewPlotSet()));
  connect(m_Controls->TileButton, SIGNAL(clicked()), SLOT(Tile()));
}

QDataRequestViewWidget::~QDataRequestViewWidget()
{
  Clear();
  delete m_Controls;
}

void QDataRequestViewWidget::Clear()
{
  while (m_Controls->mdiArea->subWindowList().size() > 0)
  {
    QMdiSubWindow* item = m_Controls->mdiArea->subWindowList().first();
    m_Controls->mdiArea->removeSubWindow(item);
    delete item;
  }
  EnableControls(true);
  m_Controls->DataRequestManager.Clear();
}

void QDataRequestViewWidget::Reset()
{
  for (QMdiSubWindow* sub : m_Controls->mdiArea->subWindowList())
  {
    QPlotSetWidget* plotWidget = dynamic_cast<QPlotSetWidget*>(sub->widget());
    if (plotWidget)
    {
      plotWidget->Clear();
    }
  }
}

void QDataRequestViewWidget::EnableControls(bool b)
{
  m_Controls->TileButton->setEnabled(b);
  m_Controls->NewPlotSetButton->setEnabled(b);
}

void QDataRequestViewWidget::LoadScenario(SEScenario& scenario)
{
  // Copy data requests from the scenario into our engine
  if (scenario.GetDataRequestManager().HasDataRequests())
  {
    if (m_Controls->mdiArea->subWindowList().size() == 0)
      NewPlotSet();
    for (SEDataRequest* dr : scenario.GetDataRequestManager().GetDataRequests())
    {
      SEDataRequest& edr = m_Controls->DataRequestManager.CopyDataRequest(*dr);
      PlotWidget->AddDataRequest(edr);
    }
  }
}

void QDataRequestViewWidget::SaveScenario(SEScenario& scenario)
{
  for (QMdiSubWindow* sub : m_Controls->mdiArea->subWindowList())
  {
    QPlotSetWidget* plotWidget = dynamic_cast<QPlotSetWidget*>(sub->widget());
    if (plotWidget)
    {
      for (const SEDataRequest* dr : m_Controls->DataRequestManager.GetDataRequests())
      {
        scenario.GetDataRequestManager().CopyDataRequest(*dr);
      }
    }
  }
}

void QDataRequestViewWidget::CreatePlot(SEDataRequest& dr)
{
  if (m_Controls->mdiArea->subWindowList().size() == 0)
    NewPlotSet();
  PlotWidget->AddDataRequest(dr);
}

void QDataRequestViewWidget::NewPlotSet()
{
  PlotWidget = new QPlotSetWidget(m_Controls->Pulse, m_Controls->DataRequestManager, this);
  PlotWidget->setTitleBarWidget(new QWidget());
  QMdiSubWindow* sub = m_Controls->mdiArea->addSubWindow(PlotWidget);
  sub->show();
  sub->setWindowFlags(windowFlags() ^ Qt::WindowMaximizeButtonHint);
  Tile();
}

void QDataRequestViewWidget::Tile()
{
  m_Controls->mdiArea->tileSubWindows();
}

void QDataRequestViewWidget::AtSteadyState(PhysiologyEngine& pulse)
{
  for (QMdiSubWindow* subwindow : m_Controls->mdiArea->subWindowList())
    ((QPlotSetWidget*)subwindow->widget())->AtSteadyState(pulse);
}
void QDataRequestViewWidget::AtSteadyStateUpdateUI()
{
  for (QMdiSubWindow* subwindow : m_Controls->mdiArea->subWindowList())
    ((QPlotSetWidget*)subwindow->widget())->AtSteadyStateUpdateUI();
}

void QDataRequestViewWidget::ProcessPhysiology(PhysiologyEngine& pulse)
{// This is called from a thread, you should NOT update UI here
  // This is where we pull data from pulse, and push any actions to it
  pulse.GetEngineTracker()->TrackData();
  for (QMdiSubWindow* subwindow : m_Controls->mdiArea->subWindowList())
    ((QPlotSetWidget*)subwindow->widget())->ProcessPhysiology(pulse);
}

void QDataRequestViewWidget::PhysiologyUpdateUI()
{
  for (QMdiSubWindow* subwindow : m_Controls->mdiArea->subWindowList())
    ((QPlotSetWidget*)subwindow->widget())->PhysiologyUpdateUI();
}
