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

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/VolViewCopyright.htm 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.

=========================================================================*/
// .NAME vtkKWScaleBarWidget - widget for manipulating scale bar
// .SECTION Description

#ifndef __vtkKWScaleBarWidget_h
#define __vtkKWScaleBarWidget_h

#include "vtkKW3DWidget.h"
#include "XML/vtkXMLIOBaseMacros.h" // Needed for XML reader/writer macros

class vtkKWApplication;
class vtkPolyData;
class vtkActor2D;
class vtkTextActor;

class VTK_EXPORT vtkKWScaleBarWidget : public vtkKW3DWidget
{
public:
  static vtkKWScaleBarWidget *New();
  vtkTypeRevisionMacro(vtkKWScaleBarWidget, vtkKW3DWidget);
  void PrintSelf(ostream& os, vtkIndent indent);
  //BTX
  vtkKWGetXMLReaderWriterObjectsMacro();
  //ETX
  
  // Description:
  // Enable/disable the widget
  virtual void SetEnabled(int enabling);
  
  // Description:
  // Set/Get units
  virtual void SetDistanceUnits(const char *name);
  vtkGetStringMacro(DistanceUnits);

  // Description:
  // Set/Get color
  virtual void SetColor(double r, double g, double b);
  virtual void SetColor(double rgb[3])
    { this->SetColor(rgb[0], rgb[1], rgb[2]); };
  double* GetColor();
  
  // Description:
  // Place widget within bounds
  //BTX
  virtual void PlaceWidget(double vtkNotUsed(bounds)[6]) {};
  void PlaceWidget()
    {this->Superclass::PlaceWidget();}
  void PlaceWidget(double xmin, double xmax, double ymin, double ymax, 
                   double zmin, double zmax)
    {this->Superclass::PlaceWidget(xmin,xmax,ymin,ymax,zmin,zmax);}
  //ETX

  // Description:
  // Set/Get the position of the widget (normalized display coords)
  virtual void SetPosition(double x, double y);
  virtual void SetPosition(double pos[2]) { this->SetPosition(pos[0], pos[1]); }
  virtual void GetPosition(double pos[2]);
  
  // Description:
  // Set/Get the size of the widget
  virtual void SetSize(double size);
  virtual double GetSize();
  
  // Description:
  // Set/get the application; needed so a message dialog can be displayed
  // (e.g., to warn that this widget cannot be used with perspective
  // projection)
  void SetApplication(vtkKWApplication *app);
  vtkGetObjectMacro(Application, vtkKWApplication);

  // Description:
  // Can the widget be moved. On by default. If off, the widget cannot be moved
  // around. 
  //
  // (PS: This should really be a flag in a superclass, say vtk3DWidget
  // and/or vtkAbstractWidget and/or vtkInteractorObserver. Widgets in VTK
  // subclass randomly from all three... )
  vtkSetMacro( Repositionable, int );
  vtkGetMacro( Repositionable, int );
  vtkBooleanMacro( Repositionable, int );

  // Description:
  // Retrieve internal actors (for serialization)
  vtkGetObjectMacro(ScaleBarActor, vtkActor2D);
  vtkGetObjectMacro(TextActor, vtkTextActor);
  
protected:
  vtkKWScaleBarWidget();
  ~vtkKWScaleBarWidget();
  
  int MouseCursorState;
  int Moving;
  int StartPosition[2];
  
  void UpdateCursorIcon();
  void SetMouseCursor(int cursorState);
  
  //BTX
  enum WidgetStates
  {
    Outside = 0,
    Inside,
    ResizeLeft,
    ResizeRight,
    ResizeTop,
    ResizeBottom
  };
  //ETX

  // Handles the events

  static void ProcessEvents(vtkObject* object,
                            unsigned long event,
                            void* clientdata,
                            void* calldata);
  
  void OnButtonPress();
  void OnMouseMove();
  void OnButtonRelease();
  void OnScaleChange();
  
  void MoveBar();
  void ResizeBar();

  double ComputeXTextPosition(int renXSize, double currentWidth, double newWidth,
                             double startXPos);
  
  char *DistanceUnits;
  double CurrentScale;
  vtkPolyData *ScaleBar;
  vtkActor2D *ScaleBarActor;
  vtkTextActor *TextActor;
  
  double ScaleSize;
  int Initialized;
  double Width;
  
  vtkKWApplication *Application;

  // Description:
  // Update the distance text.
  virtual void UpdateDistance();
  
  int Repositionable;
  
private:
  vtkKWScaleBarWidget(const vtkKWScaleBarWidget&);  //Not implemented
  void operator=(const vtkKWScaleBarWidget&);  //Not implemented
};

#endif
