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

#include "pulse/CommonDataModel.h"
#include "pulse/PhysiologyEngine.h"
#include "pulse/properties/SEScalar0To1.h"
#include "pulse/properties/SEScalarVolumePerTime.h"


class QHemorrhageWidget::Controls // based off of chronic anemia widget
{
public:
  Controls(QPulse& qp) : Pulse(qp) {}
  QPulse&                                   Pulse;
  SEHemorrhage                              Action;

  QLabeledComboBox*                         Type;
  QScalarQuantityWidget<VolumePerTimeUnit>* FlowRate;
  QScalarWidget*                            Severity;
  QLabeledComboBox*                         ExternalCmpts;
  QLabeledComboBox*                         InternalCmpts;
};

QHemorrhageWidget::QHemorrhageWidget(QPulse& qp, QWidget *parent, Qt::WindowFlags flags) : QActionWidget(qp, parent, flags)
{
  m_Controls = new Controls(qp);
  
  std::vector<QString> typeOptions = {"External", "Internal"};
  m_Controls->Type = new QLabeledComboBox(this, "Type", typeOptions);
  Properties()->layout()->addWidget(m_Controls->Type);

  m_Controls->Severity = new QScalarWidget("Severity", 0, 1, 0.1, ScalarOptionWidget::Radio, this);
  layout()->addWidget(m_Controls->Severity);
  Properties()->layout()->addWidget(m_Controls->Severity);

  m_Controls->FlowRate = new QScalarQuantityWidget<VolumePerTimeUnit>("Flow Rate", 0, 1000, 1, VolumePerTimeUnit::mL_Per_min, ScalarOptionWidget::Radio, this);
  m_Controls->FlowRate->AddUnit(VolumePerTimeUnit::mL_Per_min);
  m_Controls->FlowRate->AddUnit(VolumePerTimeUnit::L_Per_s);
  m_Controls->FlowRate->AddUnit(VolumePerTimeUnit::L_Per_min);
  Properties()->layout()->addWidget(m_Controls->FlowRate);

  connect(m_Controls->Severity->GetRadioButton(), SIGNAL(clicked()), this, SLOT(EnableSeverity()));
  connect(m_Controls->FlowRate->GetRadioButton(), SIGNAL(clicked()), this, SLOT(EnableFlowRate()));

  std::vector<QString> externalCmpts = { "RightLeg", "LeftLeg", "RightArm", "LeftArm", "Skin", "Muscle",
                                         "Brain", "LeftKidney", "RightKidney", "Liver", "Spleen",
                                         "Splanchnic", "SmallIntestine", "LargeIntestine", "Aorta", "VenaCava" };
  m_Controls->ExternalCmpts = new QLabeledComboBox(this, "Compartment", externalCmpts, 120);
  Properties()->layout()->addWidget(m_Controls->ExternalCmpts);
  m_Controls->ExternalCmpts->show();

  std::vector<QString> internalCmpts = { "LeftKidney", "RightKidney", "Liver", "Spleen", "Splanchnic", "SmallIntestine", "LargeIntestine", "Aorta", "VenaCava" };
  m_Controls->InternalCmpts = new QLabeledComboBox(this, "Compartment", internalCmpts, 120);
  Properties()->layout()->addWidget(m_Controls->InternalCmpts);
  m_Controls->InternalCmpts->hide();

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

  connect(m_Controls->Type->GetComboBox(), SIGNAL(currentIndexChanged(int)), this, SLOT(ChangeType()));
  Reset();
}

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

void QHemorrhageWidget::Reset()
{
  QActionWidget::Reset();
  m_Controls->Action.Clear();
}

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

void QHemorrhageWidget::SetEnabled(bool b)
{
  QActionWidget::SetEnabled(b);
  m_Controls->Type->SetEnabled(b);
  if (!b)
  {
    m_Controls->ExternalCmpts->SetEnabled(b);
    m_Controls->InternalCmpts->SetEnabled(b);

    m_Controls->FlowRate->FullDisable();
    m_Controls->Severity->FullDisable();
  }
  else
  {
    ChangeType();

    m_Controls->FlowRate->FullEnable();
    m_Controls->Severity->FullEnable();
    m_Controls->FlowRate->EnableInput(!b);
    m_Controls->Severity->EnableInput(b);
  }
}

void QHemorrhageWidget::EnableFlowRate()
{
  bool b = m_Controls->FlowRate->GetRadioButton()->isChecked();
  m_Controls->FlowRate->EnableInput(b);
  m_Controls->Severity->EnableInput(!b);
}
void QHemorrhageWidget::EnableSeverity()
{
  bool b = m_Controls->Severity->GetRadioButton()->isChecked();
  m_Controls->FlowRate->EnableInput(!b);
  m_Controls->Severity->EnableInput(b);
}

void QHemorrhageWidget::ChangeType()
{
  if (m_Controls->Type->GetText() == "External")
  {
    m_Controls->ExternalCmpts->show();
    m_Controls->ExternalCmpts->SetEnabled(true);
    m_Controls->InternalCmpts->hide();
    m_Controls->InternalCmpts->SetEnabled(false);
  }
  else
  {
    m_Controls->ExternalCmpts->hide();
    m_Controls->ExternalCmpts->SetEnabled(false);
    m_Controls->InternalCmpts->show();
    m_Controls->InternalCmpts->SetEnabled(true);
  }
}

void QHemorrhageWidget::ControlsToAction()
{
  QActionWidget::ControlsToAction();

  std::string cmpt;
  if (m_Controls->Type->GetText() == "External")
  {
    cmpt = m_Controls->ExternalCmpts->GetText();
    m_Controls->Action.SetType(eHemorrhage_Type::External);
  }
  else
  {
    cmpt = m_Controls->InternalCmpts->GetText();
    m_Controls->Action.SetType(eHemorrhage_Type::Internal);
  }
  m_Controls->Action.SetCompartment(cmpt);
  if (m_Controls->Severity->IsChecked())
  {
    m_Controls->Action.GetFlowRate().Invalidate();
    m_Controls->Severity->GetValue(m_Controls->Action.GetSeverity());
  }
  else
  {
    m_Controls->Action.GetSeverity().Invalidate();
    m_Controls->FlowRate->GetValue(m_Controls->Action.GetFlowRate());
  }
  emit UpateAction(m_Controls->Action, GetProcessTime());
}


void QHemorrhageWidget::ActionToControls(const SEHemorrhage& action)
{
  QActionWidget::ActionToControls(action);
  QComboBox* typeBox = m_Controls->Type->GetComboBox();
  switch (action.GetType())
  {
  case eHemorrhage_Type::External:
    typeBox->setCurrentIndex(typeBox->findText("External"));
    m_Controls->ExternalCmpts->GetComboBox()->setCurrentIndex(
      m_Controls->ExternalCmpts->GetComboBox()->findText(QString::fromStdString(action.GetCompartment()))
    );
    break;
  default:
    typeBox->setCurrentIndex(typeBox->findText("Internal"));
    m_Controls->InternalCmpts->GetComboBox()->setCurrentIndex(
      m_Controls->InternalCmpts->GetComboBox()->findText(QString::fromStdString(action.GetCompartment()))
    );
    break;
  }
  if (action.HasSeverity())
  {
    m_Controls->FlowRate->EnableInput(false);
    m_Controls->Severity->EnableInput(true);
    SEScalar0To1 severity;
    severity.SetValue(action.GetSeverity());
    m_Controls->Severity->SetValue(severity);
  }
  else if (action.HasFlowRate())
  {
    EnableFlowRate();
    SEScalarQuantity<VolumePerTimeUnit>(rateQuantity);
    rateQuantity.SetValue(action.GetFlowRate(VolumePerTimeUnit::mL_Per_min), VolumePerTimeUnit::mL_Per_min);
    m_Controls->FlowRate->SetValue(rateQuantity);
  }

}
