#include "colouredlineedit.h"

#include "../stylesheethandler/stylesheethandler.h"

#include <QDebug>

QColor ColouredLineEdit::defaultTextColor() noexcept {
  const static QColor m_text =
      QApplication::palette("QLineEdit").color(QPalette::Text);
  return m_text;
}

QColor ColouredLineEdit::defaultBackgroundColor() noexcept {
  const static QColor m_background =
      QApplication::palette("QLineEdit").color(QPalette::Background);
  return m_background;
}

QColor ColouredLineEdit::defaultBorderColor() noexcept {
  const static QColor m_border =
      QApplication::palette("QLineEdit").color(QPalette::Dark);
  return m_border;
}

void ColouredLineEdit::createAnimators() {
  m_colorProperty = new Animator(this, "text");
  m_backgroundColorProperty = new Animator(this, "background");
  m_borderColorProperty = new Animator(this, "border");
  m_parallelAnimationGroup = new QParallelAnimationGroup(this);
  m_parallelAnimationGroup->addAnimation(m_colorProperty);
  m_parallelAnimationGroup->addAnimation(m_backgroundColorProperty);
  m_parallelAnimationGroup->addAnimation(m_borderColorProperty);
}

void ColouredLineEdit::setStartColors(const QColor &color) {
  foreach (auto currentColor, findChildren<Animator *>())
    currentColor->setStartValue(color);
  return;
}

void ColouredLineEdit::setEndColors(const QColor &color) {
  foreach (auto currentColor, findChildren<Animator *>())
    currentColor->setEndValue(color);
  return;
}

void ColouredLineEdit::setStartColors() {
  m_colorProperty->setStartValue(defaultTextColor());
  m_backgroundColorProperty->setStartValue(defaultBackgroundColor());
  m_borderColorProperty->setStartValue(defaultBorderColor());
}

void ColouredLineEdit::setEndColors() {
  m_colorProperty->setEndValue(defaultTextColor());
  m_backgroundColorProperty->setEndValue(defaultBackgroundColor());
  m_borderColorProperty->setEndValue(defaultBorderColor());
}

void ColouredLineEdit::setTextColor(const QColor &color) {
  StyleSheetHandler::setValue(this, "color", 0, color);
}

void ColouredLineEdit::setBackgroundColor(const QColor &color) {
  StyleSheetHandler::setValue(this, "background-color", 0, color);
}

void ColouredLineEdit::setBorderColor(const QColor &color) {
  StyleSheetHandler::setValue(this, "border-color", 0, color);
}

ColouredLineEdit::ColouredLineEdit(QWidget *parent) : QLineEdit(parent) {
  createAnimators();
  configureAnimators();
  setStyleSheet(styleSheet());
}

void ColouredLineEdit::configureAnimators() {
  m_colorProperty->setEasingCurve(QEasingCurve::OutExpo);
  m_backgroundColorProperty->setEasingCurve(QEasingCurve::OutCirc);
  m_borderColorProperty->setEasingCurve(QEasingCurve::InCubic);
}

void ColouredLineEdit::setIntermediateColor(const QColor &color) noexcept {
  qreal step = 0.5;
  m_colorProperty->setKeyValueAt(step, color);
  m_backgroundColorProperty->setKeyValueAt(step, color);
  m_borderColorProperty->setKeyValueAt(step, color);
}

void ColouredLineEdit::setDuration(int milliseconds) noexcept {
  m_colorProperty->setDuration(milliseconds);
  m_backgroundColorProperty->setDuration(milliseconds);
  m_borderColorProperty->setDuration(milliseconds);
}

void ColouredLineEdit::animate() {
  m_parallelAnimationGroup->stop();
  m_parallelAnimationGroup->start();
}

void ColouredLineEdit::notice(const QColor &color, bool illuminate) {
  setStartColors(color);
  if (illuminate) {
    StyleSheetHandler::setValue(this, "border-width", 0, "2px");
    m_colorProperty->setEndValue(defaultTextColor());
    m_backgroundColorProperty->setEndValue(defaultBackgroundColor());
    m_borderColorProperty->setEndValue(color);
  } else {
    StyleSheetHandler::setValue(this, "border-width", 0, "1px");
    setEndColors();
  }
  setDuration(2000);
  animate();
}

// void ColouredLineEdit::softlyReset() {}

constexpr const char *ColouredLineEdit::styleSheetTemplate() const noexcept {
  return "color: %1;"
         "background-color: %2;"
         "border-color: %3;"
         "border-style: solid;"
         "border-width: 1px;";
}

QString ColouredLineEdit::styleSheet() const noexcept {
  return QString(styleSheetTemplate())
      .arg(defaultTextColor().name(), defaultBackgroundColor().name(),
           defaultBorderColor().name());
}
