//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//=========================================================================
#include "smtk/session/aeva/plugin/pqVolumeInspectionPropertyWidget.h"
#include "smtk/extension/paraview/widgets/pqPointPickingVisibilityHelper.h"
#include "smtk/session/aeva/plugin/ui_pqVolumeInspectionPropertyWidget.h"

#include "pqColorChooserButtonWithPalettes.h"
#include "pqCoreUtilities.h"
#include "pqPointPickingHelper.h"

#include "vtkSMNewWidgetRepresentationProxy.h"
#include "vtkSMPropertyGroup.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMVectorProperty.h"

#include "vtkCommand.h"
#include "vtkMath.h"
#include "vtkVector.h"
#include "vtkVectorOperators.h"

class pqVolumeInspectionPropertyWidget::Internals
{
public:
  Ui::VolumeInspectionPropertyWidget Ui;
  bool PickOrigin{ true }; // origin point
};

pqVolumeInspectionPropertyWidget::pqVolumeInspectionPropertyWidget(vtkSMProxy* smproxy,
  vtkSMPropertyGroup* smgroup,
  QWidget* parentObj)
  : Superclass("representations",
      "VolumeInspectionWidgetRepresentation",
      smproxy,
      smgroup,
      parentObj)
  , m_p(new pqVolumeInspectionPropertyWidget::Internals())
{
  Ui::VolumeInspectionPropertyWidget& ui = m_p->Ui;
  ui.setupUi(this);

  // link show3DWidget checkbox
  this->connect(ui.show3DWidget, SIGNAL(toggled(bool)), SLOT(setWidgetVisible(bool)));
  ui.show3DWidget->connect(this, SIGNAL(widgetVisibilityToggled(bool)), SLOT(setChecked(bool)));
  this->setWidgetVisible(ui.show3DWidget->isChecked());

#ifdef Q_OS_MAC
  ui.pickLabel->setText(ui.pickLabel->text().replace("Ctrl", "Cmd"));
#endif

  if (vtkSMProperty* p1 = smgroup->GetProperty("OriginPoint"))
  {
    ui.originLabel->setText(tr(p1->GetXMLLabel()));
    this->addPropertyLink(ui.originX, "text2", SIGNAL(textChangedAndEditingFinished()), p1, 0);
    this->addPropertyLink(ui.originY, "text2", SIGNAL(textChangedAndEditingFinished()), p1, 1);
    this->addPropertyLink(ui.originZ, "text2", SIGNAL(textChangedAndEditingFinished()), p1, 2);
  }
  else
  {
    qCritical("Missing required property for function 'OriginPoint'.");
  }

  this->addPropertyLink(ui.PlaneColorButton, "PlaneColor");
  this->addPropertyLink(ui.SelectedPlaneColorButton, "SelectedPlaneColor");

  auto* pickHelper = new pqPointPickingHelper(QKeySequence(tr("1")), false, this);
  pickHelper->connect(this, SIGNAL(viewChanged(pqView*)), SLOT(setView(pqView*)));
  pickHelper->connect(this, SIGNAL(widgetVisibilityUpdated(bool)), SLOT(setShortcutEnabled(bool)));
  this->connect(
    pickHelper, SIGNAL(pick(double, double, double)), SLOT(pickOrigin(double, double, double)));
  pqPointPickingVisibilityHelper<pqPointPickingHelper>{ *this, *pickHelper };

  auto* pickHelper2 = new pqPointPickingHelper(QKeySequence(tr("Ctrl+1")), true, this);
  pickHelper2->connect(this, SIGNAL(viewChanged(pqView*)), SLOT(setView(pqView*)));
  pickHelper2->connect(this, SIGNAL(widgetVisibilityUpdated(bool)), SLOT(setShortcutEnabled(bool)));
  this->connect(
    pickHelper2, SIGNAL(pick(double, double, double)), SLOT(pickOrigin(double, double, double)));
  pqPointPickingVisibilityHelper<pqPointPickingHelper>{ *this, *pickHelper2 };
}

pqVolumeInspectionPropertyWidget::~pqVolumeInspectionPropertyWidget() = default;

void pqVolumeInspectionPropertyWidget::addPropertyLink(pqColorChooserButton* color,
  const char* propertyName,
  int smindex)
{
  auto* smProperty =
    vtkSMVectorProperty::SafeDownCast(this->propertyGroup()->GetProperty(propertyName));
  if (smProperty)
  {
    switch (smProperty->GetNumberOfElements())
    {
      case 4:
        color->setShowAlphaChannel(true);
        this->addPropertyLink(color,
          "chosenColorRgbaF",
          SIGNAL(chosenColorChanged(const QColor&)),
          smProperty,
          smindex);
        break;
      case 3:
        color->setShowAlphaChannel(false);
        this->addPropertyLink(
          color, "chosenColorRgbF", SIGNAL(chosenColorChanged(const QColor&)), smProperty, smindex);
        break;
      default:
      {
        qCritical("Color property must have 3 or 4 components.");
      }
      break;
    }
    if (auto* cbwp = qobject_cast<pqColorChooserButtonWithPalettes*>(color))
    {
      new pqColorPaletteLinkHelper(cbwp, this->proxy(), this->proxy()->GetPropertyName(smProperty));
    }
  }
  else
  {
    color->hide();
  }
}

void pqVolumeInspectionPropertyWidget::placeWidget()
{
  //nothing to do
}

void pqVolumeInspectionPropertyWidget::pickOrigin(double wx, double wy, double wz)
{
  double position[3] = { wx, wy, wz };
  vtkSMNewWidgetRepresentationProxy* wdgProxy = this->widgetProxy();
  vtkSMPropertyHelper(wdgProxy, "OriginPoint").Set(position, 3);
  wdgProxy->UpdateVTKObjects();
  emit this->changeAvailable();
  this->render();
}
