//=========================================================================
//  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.
//=========================================================================
#ifndef smtk_session_aeva_pqFeatureReaction_h
#define smtk_session_aeva_pqFeatureReaction_h

#include "pqReaction.h"

#include "smtk/view/Manager.h"
#include "smtk/view/OperationIcons.h"

#include "smtk/extension/qt/SVGIconEngine.h"

class pqSMTKWrapper;
class pqServer;

/**\brief A toolbar button to trigger an SMTK operation.
  *
  * This is a base class for toolbar buttons that expose an operation.
  * It is required because templated classes cannot have Qt slots.
  *
  * The toolbar button's icon is whatever icon is registered with the
  * view manager's operation-icon factory.
  * When the toolbar button is clicked, this method locates the SMTK
  * operation panel and requests that it display the operation parameters
  * for user editing.
  *
  * In the future, it may also allow other interactions that run the
  * operation with default parameters (where possible).
  */
class pqFeatureReactionBase : public pqReaction
{
  Q_OBJECT
  using Superclass = pqReaction;

public:
  /// set \a immediate to execute the operation immediately when triggered.
  pqFeatureReactionBase(QAction* parent, bool immediate = false);
  ~pqFeatureReactionBase() override = default;

  /// allow external code (pqAEVAShortcuts) to activate the operation.
  void onTriggered() override;
protected slots:
  void onWrapperAdded(pqSMTKWrapper* wrapper, pqServer* server);

protected:
  virtual std::string svg(const std::shared_ptr<smtk::view::Manager>& viewManager) const = 0;

  virtual std::shared_ptr<smtk::operation::Operation> operation(
    const std::shared_ptr<smtk::operation::Manager>& operationManager) const = 0;

  bool m_immediate;
};

/**\brief A toolbar button for the given \a FeatureOperation.
  *
  * The operation should be registered with the operation manager (held by
  * a ParaView/SMTK wrapper object) and have an icon registered with the view
  * manager (also held by the wrapper).
  */
template<typename FeatureOperation>
class pqFeatureReaction : public pqFeatureReactionBase
{
public:
  /// set \a immediate to execute the operation immediately when triggered.
  pqFeatureReaction(QAction* parent, bool immediate = false)
    : pqFeatureReactionBase(parent, immediate)
  {
  }

  /// Look up SVG for the operation.
  std::string svg(const std::shared_ptr<smtk::view::Manager>& viewManager) const override
  {
    // TODO: Handle dark mode.
    return viewManager->operationIcons().createIcon<FeatureOperation>("#ffffff");
  }

  /// Create an instance of the operation for the base class to use.
  std::shared_ptr<smtk::operation::Operation> operation(
    const std::shared_ptr<smtk::operation::Manager>& operationManager) const override
  {
    return operationManager->create<FeatureOperation>();
  }
};
#endif
