/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#include <QPropertyAnimation>

#include "CollapsableWidget.h"

QCollapsableWidget::QCollapsableWidget(const QString & title, const int animationDuration, QWidget *parent) : QWidget(parent), animationDuration(animationDuration)
{
  contentHeight = 0;
  toggleButton.setStyleSheet("QToolButton { border: none; }");
  toggleButton.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
  toggleButton.setArrowType(Qt::ArrowType::RightArrow);
  toggleButton.setText(title);
  toggleButton.setCheckable(true);
  toggleButton.setChecked(false);

  headerLine.setFrameShape(QFrame::HLine);
  headerLine.setFrameShadow(QFrame::Sunken);
  headerLine.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); 
  headerLine.setStyleSheet("QFrame { border: none; }");

  this->setContextMenuPolicy(Qt::CustomContextMenu);
  //contentArea.setStyleSheet("QScrollArea { border: none; }");
  contentArea.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
  // start out collapsed
  contentArea.setMaximumHeight(0);
  contentArea.setMinimumHeight(0);
  // let the entire widget grow and shrink with its content
  toggleAnimation.addAnimation(new QPropertyAnimation(this, "minimumHeight"));
  toggleAnimation.addAnimation(new QPropertyAnimation(this, "maximumHeight"));
  toggleAnimation.addAnimation(new QPropertyAnimation(&contentArea, "maximumHeight"));
  // don't waste space
  mainLayout.setVerticalSpacing(0);
  mainLayout.setContentsMargins(0, 0, 0, 0);
  int row = 0;
  mainLayout.addWidget(&toggleButton, row, 0, 1, 1, Qt::AlignLeft);
  mainLayout.addWidget(&headerLine, row++, 2, 1, 1);
  mainLayout.addWidget(&contentArea, row, 0, 1, 3);
  setLayout(&mainLayout);
  QObject::connect(&toggleButton, &QToolButton::clicked, [this](const bool checked)
  {
    toggleButton.setArrowType(checked ? Qt::ArrowType::DownArrow : Qt::ArrowType::RightArrow);
    toggleAnimation.setDirection(checked ? QAbstractAnimation::Forward : QAbstractAnimation::Backward);
    toggleAnimation.start();
  });
}

bool QCollapsableWidget::expanded()
{
  return toggleButton.isChecked();
}

void QCollapsableWidget::expand(bool b)
{
  if (toggleButton.isChecked() != b)
    toggleButton.click();
}

void QCollapsableWidget::paintEvent(QPaintEvent*)
{
  QStyleOption opt;
  opt.init(this);
  QPainter p(this);
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

void QCollapsableWidget::setContentLayout(QLayout & contentLayout)
{
  delete contentArea.layout();
  contentArea.setLayout(&contentLayout);
  const auto collapsedHeight = sizeHint().height() - contentArea.maximumHeight();
  contentHeight = contentLayout.sizeHint().height();
  for (int i = 0; i < toggleAnimation.animationCount() - 1; ++i)
  {
    QPropertyAnimation * spoilerAnimation = static_cast<QPropertyAnimation *>(toggleAnimation.animationAt(i));
    spoilerAnimation->setDuration(animationDuration);
    spoilerAnimation->setStartValue(collapsedHeight);
    spoilerAnimation->setEndValue(collapsedHeight + contentHeight);
  }
  QPropertyAnimation * contentAnimation = static_cast<QPropertyAnimation *>(toggleAnimation.animationAt(toggleAnimation.animationCount() - 1));
  contentAnimation->setDuration(animationDuration);
  contentAnimation->setStartValue(0);
  contentAnimation->setEndValue(contentHeight);
  contentHeight = collapsedHeight + contentHeight;
}
