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

#include "cdm/CommonDataModel.h"
#include "cdm/properties/SEScalar.h"

QScalarWidget::QScalarWidget(const QString& name, double min, double max, double step, ScalarOptionWidget optWidget, QWidget *parent, bool seperate_label) : QWidget(parent)
{
  setAutoFillBackground(true);
  m_Layout = new QHBoxLayout(this);
  m_Layout->setSpacing(6);
  m_Layout->setContentsMargins(-1, 6, -1, 6);

  QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
  sizePolicy.setHorizontalStretch(0);
  sizePolicy.setVerticalStretch(0);
  m_Check = nullptr;
  m_Radio = nullptr;
  switch (optWidget)
  {
    case ScalarOptionWidget::Check:
    {
      m_Check = new QCheckBox(name, this);
      sizePolicy.setHeightForWidth(m_Check->sizePolicy().hasHeightForWidth());
      m_Check->setSizePolicy(sizePolicy);
      m_Label = nullptr;
      m_Layout->addWidget(m_Check);
      connect(m_Check, SIGNAL(toggled(bool)), this, SLOT(checkProperty(bool)));
      if (seperate_label)
      {
        m_Label = new QLabel(name, this);
        m_Label->setSizePolicy(sizePolicy);
        m_Layout->addWidget(m_Label);
      }
      break;
    }
    case ScalarOptionWidget::Radio:
    {
      m_Radio = new QRadioButton(name, this);
      sizePolicy.setHeightForWidth(m_Radio->sizePolicy().hasHeightForWidth());
      m_Radio->setSizePolicy(sizePolicy);
      m_Label = nullptr;
      m_Layout->addWidget(m_Radio);
      //connect(m_Radio, SIGNAL(toggled(bool)), this, SLOT(checkProperty(bool)));
      if (seperate_label)
      {
        m_Label = new QLabel(name, this);
        m_Label->setSizePolicy(sizePolicy);
        m_Layout->addWidget(m_Label);
      }
      break;
    }
    case ScalarOptionWidget::None:
    {
      m_Label = new QLabel(name, this);
      sizePolicy.setHeightForWidth(m_Label->sizePolicy().hasHeightForWidth());
      m_Label->setSizePolicy(sizePolicy);
      m_Layout->addWidget(m_Label);
      break;
    }
  }
  m_Spacer1 = new QSpacerItem(40, 30, QSizePolicy::Expanding, QSizePolicy::Maximum);
  m_Layout->addItem(m_Spacer1);
  m_Value = new QDoubleSpinBox(this);
  m_Value->setSingleStep(step);
  if (optWidget==ScalarOptionWidget::Check)
    m_Value->setSpecialValueText("nan");
  m_Value->setMinimum(optWidget==ScalarOptionWidget::Check ? min - step : min);
  m_Value->setMaximum(max);
  m_Value->setMinimumSize(QSize(70, 22));
  m_Value->setMaximumSize(QSize(70, 22));
  m_Value->setDecimals(2);
  m_Layout->addWidget(m_Value);
  m_Spacer2 = new QSpacerItem(76, 20, QSizePolicy::Fixed, QSizePolicy::Maximum);
  m_Layout->addItem(m_Spacer2);
  setLayout(m_Layout);
  reset();
  if (seperate_label)
  {
    if (m_Check != nullptr)
    {
      m_Check->setChecked(true);
      m_Check->hide();
    }
  }
}
void QScalarWidget::reset()
{
  if (m_Check != nullptr)
    m_Check->setChecked(false);
  enableInput(true, false);
  m_Value->setValue(m_Value->minimum());
  m_LastValue = m_Value->minimum();
}

bool QScalarWidget::isChecked()
{
  if (m_Check != nullptr)
    return m_Check->isChecked();
  return true;
}

void QScalarWidget::setDecimals(int prec)
{
  m_Value->setDecimals(prec);
}

void QScalarWidget::setValue(const SEScalar& s)
{
  if (s.IsValid())
  {
    m_Value->setEnabled(true);
    if (m_Check != nullptr)
      m_Check->setChecked(true);
    m_Value->setValue(s.GetValue());
    m_LastValue = s.GetValue();
  }
  else
  {
    m_Value->setValue(m_Value->minimum());
    if (m_Check != nullptr)
      m_Check->setChecked(false);
    m_LastValue = m_Value->minimum();
    m_Value->setEnabled(false);
  }
}

void QScalarWidget::getValue(SEScalar& s)
{
  if (m_Check != nullptr && m_Value->value() == m_Value->minimum())
  {
    s.Invalidate();
    return;//Skip it!! not a valid value as per the bounds
  }
  s.SetValue(m_Value->value());
}

void QScalarWidget::enableInput(bool b)
{
  enableInput(b, b);
}
void QScalarWidget::enableInput(bool check, bool value)
{
  if (m_Check != nullptr)
    m_Check->setEnabled(check);
  if (m_Radio != nullptr)
    m_Radio->setChecked(check);
  m_Value->setEnabled(value);
}

void QScalarWidget::fullDisable()
{
  enableInput(false);
  if (m_Check != nullptr)
    m_Check->setDisabled(true);
  if (m_Radio != nullptr)
    m_Radio->setDisabled(true);
}

void QScalarWidget::checkProperty(bool b)
{
  m_Value->setEnabled(b);
  if (!b)
  {
    m_LastValue = m_Value->value();
    m_Value->setValue(m_Value->minimum());
  }
  else
    m_Value->setValue(m_LastValue);
}