/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#include "controls/actions/SerializeStateWidget.h"
#include "controls/ScalarWidget.h"
#include "controls/ScalarQuantityWidget.h"

#include "pulse/CommonDataModel.h"
#include "pulse/PhysiologyEngine.h"
#include "pulse/utils/FileUtils.h"

#include <QPushButton>
#include <QLineEdit>
#include <QFileDialog>

class QSerializeStateWidget::Controls
{
public:
  Controls(QPulse& qp) : Pulse(qp) {}
  QPulse&          Pulse;
  SESerializeState Action;
  // File selection widgets
  QWidget*         fsWidget;
  QHBoxLayout*     fsLayout;
  QLabel*          Label;
  QSpacerItem*     Spacer;
  QLineEdit*       Filename;
  QPushButton*     Browse;
  // Name postfix widgets
  QWidget*         pfWidget;
  QHBoxLayout*     pfLayout;
  //QCheckBox*       Checkbox;
};

QSerializeStateWidget::QSerializeStateWidget(QPulse& qp, QWidget *parent, Qt::WindowFlags flags) : QActionWidget(qp, parent, flags)
{
  m_Controls = new Controls(qp);

  m_Controls->fsWidget = new QWidget(this);
  m_Controls->fsLayout = new QHBoxLayout(this);
  m_Controls->fsWidget->setLayout(m_Controls->fsLayout);
  m_Controls->Label = new QLabel("State Filename");
  m_Controls->Spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
  m_Controls->Filename = new QLineEdit();
  m_Controls->Browse = new QPushButton("Browse");
  m_Controls->fsLayout->addWidget(m_Controls->Label);
  m_Controls->fsLayout->addSpacerItem(m_Controls->Spacer);
  m_Controls->fsLayout->addWidget(m_Controls->Filename);
  m_Controls->fsLayout->addWidget(m_Controls->Browse);
  Properties()->layout()->addWidget(m_Controls->fsWidget);

  m_Controls->pfWidget = new QWidget(this);
  m_Controls->pfLayout = new QHBoxLayout(this);
  m_Controls->pfWidget->setLayout(m_Controls->pfLayout);
  //m_Controls->Checkbox = new QCheckBox("Postfix simulation time to filename");
  //m_Controls->Checkbox->setChecked(true);
  //m_Controls->pfLayout->addWidget(m_Controls->Checkbox);
  Properties()->layout()->addWidget(m_Controls->pfWidget);

  Properties()->layout()->addWidget(GetProcessTimeCtrl());


  connect(m_Controls->Browse, SIGNAL(clicked()), this, SLOT(Browse()));
  Reset();
}

QSerializeStateWidget::~QSerializeStateWidget()
{
  delete m_Controls;
}

void QSerializeStateWidget::Reset()
{
  QActionWidget::Reset();
  m_Controls->Action.Clear();
  m_Controls->Filename->setText("");
  //m_Controls->Checkbox->setChecked(true);
}

void QSerializeStateWidget::Browse()
{
  QString filename = QFileDialog::getSaveFileName(this, "Save State", "./states", "JSON (*.json);;Protobuf Binary  (*.pbb)");
  // Let's try to make the separate file relative to the working directory
  std::string cwd = GetCurrentWorkingDirectory();
  std::replace(cwd.begin(), cwd.end(), '\\', '/');
  QStringList pieces = filename.split(QString::fromStdString(cwd));
  if (pieces.size() > 1)
    filename = "." + pieces[1];
  m_Controls->Filename->setText(filename);
}

SEAction& QSerializeStateWidget::GetAction()
{
  return m_Controls->Action;
}
const SEAction& QSerializeStateWidget::GetAction() const
{
  return m_Controls->Action;
}

void QSerializeStateWidget::SetEnabled(bool b)
{
  QActionWidget::SetEnabled(b);
  m_Controls->Filename->setEnabled(b);
  m_Controls->Browse->setEnabled(b);
  //m_Controls->Checkbox->setEnabled(b);
}

void QSerializeStateWidget::ControlsToAction()
{
  QActionWidget::ControlsToAction();
  m_Controls->Action.SetFilename(m_Controls->Filename->text().toStdString());
  emit UpateAction(m_Controls->Action, GetProcessTime());
}

void QSerializeStateWidget::ActionToControls(const SESerializeState& action)
{
  QActionWidget::ActionToControls(action);
  m_Controls->Filename->setText(QString::fromStdString(action.GetFilename()));
}

void QSerializeStateWidget::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
  //if (ProcessAction() && m_Controls->Checkbox->isChecked())
  //{
  //  // Insert the current simulation time into the filename
  //  std::string filename = m_Controls->Action.GetFilename();
  //  std::size_t lastIndex = filename.find_last_of(".");
  //  std::string name_path = filename.substr(0, lastIndex);
  //  std::string ext = filename.substr(lastIndex);
  //  filename = name_path + "@" + cdm::to_string(pulse.GetSimulationTime(TimeUnit::s)) + "s" + ext;
  //  m_Controls->Action.SetFilename(filename);
  //}
  QActionWidget::ProcessPhysiology(pulse);
}
