/*=========================================================================

  Program:   ParaView
  Module:    vtkSMProxy.h

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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.

=========================================================================*/
/**
 * @class   vtkPVAxesWidget
 * @brief   A widget to manipulate an axe
 *
 *
 * This widget creates and manages its own vtkPVAxesActor.
*/

#ifndef vtkPVAxesWidget_h
#define vtkPVAxesWidget_h

#include "vtkInteractorObserver.h"
#include "vtkPVVTKExtensionsRenderingModule.h" // needed for export macro

class vtkActor2D;
class vtkKWApplication;
class vtkPolyData;
class vtkPVAxesActor;
class vtkPVAxesWidgetObserver;
class vtkRenderer;

class VTKPVVTKEXTENSIONSRENDERING_EXPORT vtkPVAxesWidget : public vtkInteractorObserver
{
public:
  static vtkPVAxesWidget* New();
  vtkTypeMacro(vtkPVAxesWidget, vtkInteractorObserver);
  void PrintSelf(ostream& os, vtkIndent indent);

  /**
   * Layer number to use for the internal renderer created by vtkPVAxesWidget.
   */
  static const int RendererLayer = 1;

  //@{
  /**
   * Set/get the axes actor to be displayed in this 3D widget.
   */
  void SetAxesActor(vtkPVAxesActor* actor);
  vtkGetObjectMacro(AxesActor, vtkPVAxesActor);
  //@}

  /**
   * Enable the 3D widget.
   */
  virtual void SetEnabled(int);

  //@{
  /**
   * Set the renderer this 3D widget will be contained in.
   */
  void SetParentRenderer(vtkRenderer* ren);
  vtkRenderer* GetParentRenderer();
  //@}

  //@{
  /**
   * Get the renderer.
   */
  vtkGetObjectMacro(Renderer, vtkRenderer);
  //@}

  /**
   * Callback to keep the camera for the axes actor up to date with the
   * camera in the parent renderer
   */
  void ExecuteEvent(vtkObject* o, unsigned long event, void* calldata);

  //@{
  /**
   * Set/get whether to allow this 3D widget to be interactively moved/scaled.
   */
  void SetInteractive(int state);
  vtkGetMacro(Interactive, int);
  vtkBooleanMacro(Interactive, int);
  //@}

  //@{
  /**
   * Set/get the color of the outline of this widget.  The outline is visible
   * when (in interactive mode) the cursor is over this 3D widget.
   */
  void SetOutlineColor(double r, double g, double b);
  double* GetOutlineColor();
  //@}

  //@{
  /**
   * Set/get the color of the axis labels of this widget.
   */
  void SetAxisLabelColor(double r, double g, double b);
  double* GetAxisLabelColor();
  //@}

  //@{
  /**
   * Set/get the viewport to position/size this 3D widget.
   */
  void SetViewport(double minX, double minY, double maxX, double maxY);
  double* GetViewport();
  //@}

protected:
  vtkPVAxesWidget();
  ~vtkPVAxesWidget();

  vtkRenderer* Renderer;
  vtkRenderer* ParentRenderer;

  vtkPVAxesActor* AxesActor;
  vtkPolyData* Outline;
  vtkActor2D* OutlineActor;

  static void ProcessEvents(
    vtkObject* object, unsigned long event, void* clientdata, void* calldata);

  vtkPVAxesWidgetObserver* Observer;
  int StartTag;

  int MouseCursorState;
  int Moving;
  int StartPosition[2];

  int Interactive;

  void UpdateCursorIcon();
  void SetMouseCursor(int cursorState);

  int State;

  enum AxesWidgetState
  {
    Outside = 0,
    Inside,
    TopLeft,
    TopRight,
    BottomLeft,
    BottomRight
  };

  void OnButtonPress();
  void OnMouseMove();
  void OnButtonRelease();

  void MoveWidget();
  void ResizeTopLeft();
  void ResizeTopRight();
  void ResizeBottomLeft();
  void ResizeBottomRight();

  void SquareRenderer();

  unsigned long StartEventObserverId;

private:
  vtkPVAxesWidget(const vtkPVAxesWidget&) VTK_DELETE_FUNCTION;
  void operator=(const vtkPVAxesWidget&) VTK_DELETE_FUNCTION;
};

#endif
