//=========================================================================
//  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/rgg/plugin/smtkRGGScaleToolBar.h"

// Client side
#include "vtkTransform.h"
#include "vtkCamera.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMRenderViewProxy.h"
#include "vtkSMPVRepresentationProxy.h"
#include "vtkSMViewProxy.h"

#include "pqActiveObjects.h"
#include "pqApplicationCore.h"
#include "pqPipelineSource.h"
#include "pqRenderView.h"
#include "pqServerManagerModel.h"
#include "pqSetName.h"

// Qt
#include <QHBoxLayout>
#include <QLabel>
#include <QSlider>
#include <QSpinBox>
#include <QToolBar>
#include <QWidget>

smtkRGGScaleToolBar::smtkRGGScaleToolBar(QWidget* parent)
  : Superclass("SMTK RGG Scale", parent), m_scaleSlider(nullptr)
{
  this->setObjectName("smtkRGGScale");

  m_scaleSlider = new QSlider(Qt::Horizontal, this);
  m_scaleSlider->setMaximumWidth(300);
  m_scaleSlider->setMinimum(1);
  m_scaleSlider->setMaximum(100);
  m_scaleSlider->setValue(100);
  m_scaleSlider->setToolTip("Scale the view along z axis");

  this->addWidget(m_scaleSlider);

  QLabel* scaleLabel = new QLabel("Z scale", this);
  this->addWidget(scaleLabel);

  QSpinBox* scaleSpinBox = new QSpinBox(this);
  scaleSpinBox->setMinimum(1);
  scaleSpinBox->setMaximum(100);
  scaleSpinBox->setValue(100);
  QObject::connect(m_scaleSlider, &QSlider::valueChanged,
                   scaleSpinBox, &QSpinBox::setValue);
  QObject::connect(scaleSpinBox, (void (QSpinBox::*)(int ) ) &QSpinBox::valueChanged,
                   m_scaleSlider, &QSlider::setValue);
  QObject::connect(m_scaleSlider, &QSlider::valueChanged,
                   this, &smtkRGGScaleToolBar::onValueChanged);
  this->addWidget(scaleSpinBox);

  // Add per view scale support. It's suggested that we shall not rely on pqView pointer
  // to cache per view z scalue value.
  QObject::connect(&pqActiveObjects::instance(), &pqActiveObjects::viewChanged, this
                   , &smtkRGGScaleToolBar::onViewChanged);

}

smtkRGGScaleToolBar::~smtkRGGScaleToolBar()
{
}

void smtkRGGScaleToolBar::onValueChanged(int v)
{
  double zScale = 0.01* v;
  pqRenderView* renView = qobject_cast<pqRenderView*>(pqActiveObjects::instance().activeView());
  pqPipelineSource* source = pqActiveObjects::instance().activeSource();
  if (!renView || !source)
  {
    return;
  }

  QList<pqDataRepresentation*> reps = source->getRepresentations(renView);
  for( pqDataRepresentation* rep: reps)
  {
    auto proxy = rep->getProxy();
    vtkSMPropertyHelper(proxy, "Scale").Set(2, zScale);
    proxy->UpdateVTKObjects();
    rep->renderViewEventually();
  }
}

void smtkRGGScaleToolBar::onViewChanged(pqView* v)
{
  if (!v)
  {
    return;
  }
  pqRenderView* renView = qobject_cast<pqRenderView*>(v);
  pqPipelineSource* source = pqActiveObjects::instance().activeSource();
  if (!renView || !source)
  {
    return;
  }

  QList<pqDataRepresentation*> reps = source->getRepresentations(renView);
  for( pqDataRepresentation* rep: reps)
  {
    if (rep)
    {
      auto proxy = rep->getProxy();
      vtkVector3d scaleVec;
      vtkSMPropertyHelper(proxy, "Scale").Get(scaleVec.GetData(), 3);
      this->m_scaleSlider->setValue(static_cast<int>(scaleVec[2]*100));
      break;
    }
  }
}
