/** Applies this axis' parameters to the graph
 *
 */
void ScaleDetails::apply() {
  if (m_modified && valid()) {
    // as the classes are separate now this may cause a problem as ideally i'd
    // get this from the axis tab,
    // but at the moment there's nothing to cause a problem as the only other
    // cases that are used are Date
    // and Time and Mantid doesn't support them in data yet i've been told
    ScaleDraw::ScaleType type = m_graph->axisType(m_mappedaxis);

    double start = 0.0, end = 0.0, step = 0.0, breakLeft = -DBL_MAX,
           breakRight = DBL_MAX;
    if (type == ScaleDraw::Date) {
      ScaleDraw *sclDraw = dynamic_cast<ScaleDraw *>(
          m_graph->plotWidget()->axisScaleDraw(m_mappedaxis));
      QDateTime origin = sclDraw->dateTimeOrigin();
      start = (double)origin.secsTo(m_dteStartDateTime->dateTime());
      end = (double)origin.secsTo(m_dteEndDateTime->dateTime());
    } else if (type == ScaleDraw::Time) {
      ScaleDraw *sclDraw = dynamic_cast<ScaleDraw *>(
          m_graph->plotWidget()->axisScaleDraw(m_mappedaxis));
      QTime origin = sclDraw->dateTimeOrigin().time();
      start = (double)origin.msecsTo(m_timStartTime->time());
      end = (double)origin.msecsTo(m_timEndTime->time());
    } else {
      start = m_dspnStart->value();
      end = m_dspnEnd->value();
    }

    if (m_radStep->isChecked()) {
      step = m_dspnStep->value();
      if (type == ScaleDraw::Time) {
        switch (m_cmbUnit->currentIndex()) {
        case 0:
          break;
        case 1:
          step *= 1e3;
          break;
        case 2:
          step *= 6e4;
          break;
        case 3:
          step *= 36e5;
          break;
        }
      } else if (type == ScaleDraw::Date) {
        switch (m_cmbUnit->currentIndex()) {
        case 0:
          step *= 86400;
          break;
        case 1:
          step *= 604800;
          break;
        }
      }
    }

    if (m_grpAxesBreaks->isChecked()) {
      breakLeft = qMin(m_dspnBreakStart->value(), m_dspnBreakEnd->value());
      breakRight = qMax(m_dspnBreakStart->value(), m_dspnBreakEnd->value());
    }
    m_graph->setScale(
        m_mappedaxis, start, end, step, m_spnMajorValue->value(),
        m_cmbMinorValue->currentText().toInt(), m_cmbScaleType->currentIndex(),
        m_chkInvert->isChecked(), breakLeft, breakRight,
        m_spnBreakPosition->value(), m_dspnStepBeforeBreak->value(),
        m_dspnStepAfterBreak->value(),
        m_cmbMinorTicksBeforeBreak->currentText().toInt(),
        m_cmbMinorTicksAfterBreak->currentText().toInt(),
        m_chkLog10AfterBreak->isChecked(), m_spnBreakWidth->value(),
        m_chkBreakDecoration->isChecked(), m_dspnN->value());
    m_graph->changeIntensity(true);
    m_graph->notifyChanges();
    m_modified = false;
  }
}
/** Initialisation method. Sets up all widgets and variables not done in the
 * constructor.
 *
 */
void ScaleDetails::initWidgets() {
  if (m_initialised) {
    return;
  } else {
    Plot *d_plot = m_graph->plotWidget();
    const QwtScaleDiv *scDiv = d_plot->axisScaleDiv(m_mappedaxis);
    double start = qMin(scDiv->lBound(), scDiv->hBound());
    double end = qMax(scDiv->lBound(), scDiv->hBound());
    ScaleDraw::ScaleType type = m_graph->axisType(m_mappedaxis);
    if (type == ScaleDraw::Date) {
      ScaleDraw *sclDraw =
          dynamic_cast<ScaleDraw *>(d_plot->axisScaleDraw(m_mappedaxis));
      if (!sclDraw) {
        throw std::runtime_error("Could not convert the axis Scale Draw object "
                                 "to a ScaleDraw object");
      }
      QDateTime origin = sclDraw->dateTimeOrigin();

      m_dspnStart->hide();
      m_timStartTime->hide();
      m_dteStartDateTime->show();
      m_dteStartDateTime->setDisplayFormat(sclDraw->format());
      m_dteStartDateTime->setDateTime(origin.addSecs((int)start));

      m_dspnEnd->hide();
      m_timEndTime->hide();
      m_dteEndDateTime->show();
      m_dteEndDateTime->setDisplayFormat(sclDraw->format());
      m_dteEndDateTime->setDateTime(origin.addSecs((int)end));

      m_cmbUnit->show();
      m_cmbUnit->addItem(tr("days"));
      m_cmbUnit->addItem(tr("weeks"));
      m_dspnStep->setValue(m_graph->axisStep(m_mappedaxis) / 86400.0);
      m_dspnStep->setSingleStep(1);
    } else if (type == ScaleDraw::Time) {
      if (ScaleDraw *sclDraw =
              dynamic_cast<ScaleDraw *>(d_plot->axisScaleDraw(m_mappedaxis))) {
        QTime origin = sclDraw->dateTimeOrigin().time();

        m_dspnStart->hide();
        m_dteStartDateTime->hide();
        m_timStartTime->show();
        m_timStartTime->setDisplayFormat(sclDraw->format());
        m_timStartTime->setTime(origin.addMSecs((int)start));

        m_dspnEnd->hide();
        m_dteEndDateTime->hide();
        m_timEndTime->show();
        m_timEndTime->setDisplayFormat(sclDraw->format());
        m_timEndTime->setTime(origin.addMSecs((int)end));

        m_cmbUnit->show();
        m_cmbUnit->addItem(tr("millisec."));
        m_cmbUnit->addItem(tr("sec."));
        m_cmbUnit->addItem(tr("min."));
        m_cmbUnit->addItem(tr("hours"));
        m_cmbUnit->setCurrentIndex(1);
        m_dspnStep->setValue(m_graph->axisStep(m_mappedaxis) / 1e3);
        m_dspnStep->setSingleStep(1000);
      }
    } else {
      m_dspnStart->show();
      m_dspnStart->setValue(start);
      m_timStartTime->hide();
      m_dteStartDateTime->hide();
      m_dspnEnd->show();
      m_dspnEnd->setValue(end);
      m_timEndTime->hide();
      m_dteEndDateTime->hide();
      m_dspnStep->setValue(m_graph->axisStep(m_mappedaxis));
      m_dspnStep->setSingleStep(0.1);
    }

    double range = fabs(scDiv->range());
    QwtScaleEngine *qwtsc_engine = d_plot->axisScaleEngine(m_mappedaxis);
    ScaleEngine *sc_engine = dynamic_cast<ScaleEngine *>(qwtsc_engine);
    if (sc_engine) {
      if (sc_engine->axisBreakLeft() > -DBL_MAX) {
        m_dspnBreakStart->setValue(sc_engine->axisBreakLeft());
      } else {
        m_dspnBreakStart->setValue(start + 0.25 * range);
      }

      if (sc_engine->axisBreakRight() < DBL_MAX) {
        m_dspnBreakEnd->setValue(sc_engine->axisBreakRight());
      } else {
        m_dspnBreakEnd->setValue(start + 0.75 * range);
      }
      m_grpAxesBreaks->setChecked(sc_engine->hasBreak());

      m_spnBreakPosition->setValue(sc_engine->breakPosition());
      m_spnBreakWidth->setValue(sc_engine->breakWidth());
      m_dspnStepBeforeBreak->setValue(sc_engine->stepBeforeBreak());
      m_dspnStepAfterBreak->setValue(sc_engine->stepAfterBreak());

      ScaleTransformation::Type scale_type = sc_engine->type();
      m_cmbMinorTicksBeforeBreak->clear();
      if (scale_type == ScaleTransformation::Log10) {
        m_cmbMinorTicksBeforeBreak->addItems({"0", "2", "4", "8"});
      } else {
        m_cmbMinorTicksBeforeBreak->addItems({"0", "1", "4", "9", "14", "19"});
      }
      m_cmbMinorTicksBeforeBreak->setEditText(
          QString::number(sc_engine->minTicksBeforeBreak()));

      m_cmbMinorTicksAfterBreak->setEditText(
          QString::number(sc_engine->minTicksAfterBreak()));
      m_chkLog10AfterBreak->setChecked(sc_engine->log10ScaleAfterBreak());
      m_chkBreakDecoration->setChecked(sc_engine->hasBreakDecoration());
      m_chkInvert->setChecked(
          sc_engine->testAttribute(QwtScaleEngine::Inverted));
      m_cmbScaleType->setCurrentIndex(scale_type);
      m_dspnN->setValue(sc_engine->nthPower());
      m_cmbMinorValue->clear();
      if (scale_type == ScaleTransformation::Log10) {
        m_cmbMinorValue->addItems({"0", "2", "4", "8"});
      } else {
        m_cmbMinorValue->addItems({"0", "1", "4", "9", "14", "19"});
      }
      m_cmbMinorValue->setEditText(
          QString::number(d_plot->axisMaxMinor(m_mappedaxis)));

      bool isColorMap = m_graph->isColorBarEnabled(m_mappedaxis);
      m_grpAxesBreaks->setEnabled(!isColorMap);
      if (isColorMap) {
        m_grpAxesBreaks->setChecked(false);
      }
    } else {
      m_grpAxesBreaks->setChecked(false);
      m_grpAxesBreaks->setEnabled(false);
    }

    const QwtValueList &lst = scDiv->ticks(QwtScaleDiv::MajorTick);
    m_spnMajorValue->setValue(lst.count());

    checkstep();
    checkscaletype();

    connect(m_grpAxesBreaks, SIGNAL(clicked()), this, SLOT(setModified()));
    connect(m_chkInvert, SIGNAL(clicked()), this, SLOT(setModified()));
    connect(m_chkLog10AfterBreak, SIGNAL(clicked()), this, SLOT(setModified()));
    connect(m_chkBreakDecoration, SIGNAL(clicked()), this, SLOT(setModified()));
    connect(m_radStep, SIGNAL(clicked()), this, SLOT(setModified()));
    connect(m_radMajor, SIGNAL(clicked()), this, SLOT(setModified()));
    connect(m_cmbMinorTicksBeforeBreak, SIGNAL(currentIndexChanged(int)), this,
            SLOT(setModified()));
    connect(m_cmbMinorTicksAfterBreak, SIGNAL(currentIndexChanged(int)), this,
            SLOT(setModified()));
    connect(m_cmbMinorValue, SIGNAL(currentIndexChanged(int)), this,
            SLOT(setModified()));
    connect(m_cmbUnit, SIGNAL(currentIndexChanged(int)), this,
            SLOT(setModified()));
    connect(m_cmbScaleType, SIGNAL(currentIndexChanged(int)), this,
            SLOT(setModified()));
    connect(m_cmbScaleType, SIGNAL(currentIndexChanged(int)), this,
            SLOT(checkscaletype()));
    connect(m_dspnEnd, SIGNAL(valueChanged(double)), this, SLOT(setModified()));
    connect(m_dspnStart, SIGNAL(valueChanged(double)), this,
            SLOT(setModified()));
    connect(m_dspnN, SIGNAL(valueChanged(double)), this, SLOT(setModified()));
    connect(m_dspnStep, SIGNAL(valueChanged(double)), this,
            SLOT(setModified()));
    connect(m_dspnBreakStart, SIGNAL(valueChanged(double)), this,
            SLOT(setModified()));
    connect(m_dspnStepBeforeBreak, SIGNAL(valueChanged(double)), this,
            SLOT(setModified()));
    connect(m_dspnStepAfterBreak, SIGNAL(valueChanged(double)), this,
            SLOT(setModified()));
    connect(m_dspnBreakEnd, SIGNAL(valueChanged(double)), this,
            SLOT(setModified()));
    connect(m_spnMajorValue, SIGNAL(valueChanged(int)), this,
            SLOT(setModified()));
    connect(m_spnBreakPosition, SIGNAL(valueChanged(int)), this,
            SLOT(setModified()));
    connect(m_spnBreakWidth, SIGNAL(valueChanged(int)), this,
            SLOT(setModified()));
    connect(m_dteStartDateTime, SIGNAL(dateTimeChanged(QDateTime)), this,
            SLOT(setModified()));
    connect(m_dteStartDateTime, SIGNAL(dateChanged(QDate)), this,
            SLOT(setModified()));
    connect(m_dteStartDateTime, SIGNAL(timeChanged(QTime)), this,
            SLOT(setModified()));
    connect(m_dteEndDateTime, SIGNAL(dateTimeChanged(QDateTime)), this,
            SLOT(setModified()));
    connect(m_dteEndDateTime, SIGNAL(dateChanged(QDate)), this,
            SLOT(setModified()));
    connect(m_dteEndDateTime, SIGNAL(timeChanged(QTime)), this,
            SLOT(setModified()));
    connect(m_timStartTime, SIGNAL(dateTimeChanged(QDateTime)), this,
            SLOT(setModified()));
    connect(m_timStartTime, SIGNAL(dateChanged(QDate)), this,
            SLOT(setModified()));
    connect(m_timStartTime, SIGNAL(timeChanged(QTime)), this,
            SLOT(setModified()));
    connect(m_timEndTime, SIGNAL(dateTimeChanged(QDateTime)), this,
            SLOT(setModified()));
    connect(m_timEndTime, SIGNAL(dateChanged(QDate)), this,
            SLOT(setModified()));
    connect(m_timEndTime, SIGNAL(timeChanged(QTime)), this,
            SLOT(setModified()));

    m_initialised = true;
  }
}