//=========================================================================
//  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 vtk_aeva_ext_vtkVolumeInspectionWidget_h
#define vtk_aeva_ext_vtkVolumeInspectionWidget_h

#include "vtk/aeva/ext/AEVAExtModule.h" // For export macro
#include "vtkAbstractWidget.h"

class vtkVolumeInspectionRepresentation;

/**
 * @class   vtkVolumeInspectionWidget
 * @brief   3D widget that shows 3 axis-aligned slice planes rooted at a center of a in a bounding box.
 *
 * To use this widget, you pair it with a vtkVolumeInspectionRepresentation.
 *
 * @par Event Bindings:
 * By default, the widget responds to the following VTK events (i.e., it
 * watches the vtkRenderWindowInteractor for these events):
 * <pre>
 * If the center point (handle) is selected:
 *   LeftButtonPressEvent - select handle (if on slider)
 *   LeftButtonReleaseEvent - release handle (if selected)
 *   MouseMoveEvent - move the center point (constrained to plane or on the
 *                    axis if CTRL key is pressed)
 * </pre>
 *
 * @par Event Bindings:
 * In turn, when these widget events are processed, the vtkConeWidget
 * invokes the following VTK events on itself (which observers can listen for):
 * <pre>
 *   vtkCommand::StartInteractionEvent (on vtkWidgetEvent::Select)
 *   vtkCommand::EndInteractionEvent (on vtkWidgetEvent::EndSelect)
 *   vtkCommand::InteractionEvent (on vtkWidgetEvent::Move)
 * </pre>
 *
*/
class AEVAEXT_EXPORT vtkVolumeInspectionWidget : public vtkAbstractWidget
{
public:
  /**
   * Instantiate the object.
   */
  static vtkVolumeInspectionWidget* New();

  //@{
  /**
   * Standard vtkObject methods
   */
  vtkTypeMacro(vtkVolumeInspectionWidget, vtkAbstractWidget);
  void PrintSelf(ostream& os, vtkIndent indent) override;
  //@}

  /**
   * Specify an instance of vtkWidgetRepresentation used to represent this
   * widget in the scene. Note that the representation is a subclass of vtkProp
   * so it can be added to the renderer independent of the widget.
   */
  void SetRepresentation(vtkVolumeInspectionRepresentation* rep);

  /// Control widget interactivity, allowing users to interact with the camera or other widgets.
  ///
  /// The camera is unobserved when the widget is disabled.
  void SetEnabled(int enabling) override;

  /**
   * Return the representation as a vtkVolumeInspectionRepresentation.
   */
  vtkVolumeInspectionRepresentation* GetVolumeInspectionRepresentation()
  {
    return reinterpret_cast<vtkVolumeInspectionRepresentation*>(this->WidgetRep);
  }

  /**
   * Create the default widget representation if one is not set.
   */
  void CreateDefaultRepresentation() override;

protected:
  vtkVolumeInspectionWidget();
  ~vtkVolumeInspectionWidget() override;

  // Manage the state of the widget
  int WidgetState;
  enum _WidgetState
  {
    Start = 0,
    Active
  };

  // These methods handle events
  static void SelectAction(vtkAbstractWidget*);
  static void TranslateAction(vtkAbstractWidget*);
  /*
   * I guess scaling doesn't make sense in this widget because there is no dimension/size
   */
  // static void ScaleAction(vtkAbstractWidget*);
  static void EndSelectAction(vtkAbstractWidget*);
  static void MoveAction(vtkAbstractWidget*);

  /**
   * Update the cursor shape based on the interaction state. Returns 1
   * if the cursor shape requested is different from the existing one.
   */
  int UpdateCursorShape(int interactionState);

private:
  vtkVolumeInspectionWidget(const vtkVolumeInspectionWidget&) = delete;
  void operator=(const vtkVolumeInspectionWidget&) = delete;
};

#endif
