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

  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 vtkKWImageWidget
// .SECTION Description

#ifndef __vtkKWImageWidget_h
#define __vtkKWImageWidget_h

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

class vtkImageActor;
class vtkProperty;
class vtkKWCroppingRegionsWidget;
class vtkKWCursorWidget;
class vtkKWScaleBarWidget;
class vtkKWInteractorStyleImageView;
class vtkKW2DSplineSurfacesWidget;
class vtkKWScalarBarWidget;

class VTK_EXPORT vtkKWImageWidget : public vtkKW2DRenderWidget
{
public:
  static vtkKWImageWidget* New();
  vtkTypeRevisionMacro(vtkKWImageWidget, vtkKW2DRenderWidget);
  void PrintSelf(ostream& os, vtkIndent indent);
  //BTX
  vtkKWGetXMLReaderWriterObjectsMacro();
  //ETX

  // Description:
  // Render the scene.
  virtual void Render();

  // Description:
  // Slice navigation
  virtual void SetSlice(int n);
  virtual void IncrementPage();
  virtual void DecrementPage();

  // Description
  // Callback triggered when a slice has been changed through the UI
  virtual void SliceSelectedCallback(double value);
  
  // Description:
  // Enable/Disable cropping regions 
  virtual void SetCroppingRegionsVisibility(int state);
  virtual int  GetCroppingRegionsVisibility();
  vtkBooleanMacro(CroppingRegionsVisibility, int);
  virtual void SetCroppingPlanes(double p[6]);
  virtual double* GetCroppingPlanes();
  virtual void ResetCroppingPlanes();
  virtual void SetCroppingRegionFlags(int);
  virtual void SetCroppingPlanes(
    double p0, double p1, double p2, double p3, double p4, double p5);
  virtual int GetCroppingRegionFlags();
  vtkGetObjectMacro(CroppingWidget, vtkKWCroppingRegionsWidget);

  // Description:
  // Convenience method to set the visibility of all annotations.
  virtual void SetAnnotationsVisibility(int v);

  // Description:
  // Enable/disable scalar bar
  virtual void SetScalarBarVisibility(int state);
  virtual int  GetScalarBarVisibility();
  virtual void ToggleScalarBarVisibility();
  vtkBooleanMacro(ScalarBarVisibility, int);
  virtual void SetScalarBarComponent(int comp);
  virtual int  GetScalarBarComponent();
  vtkGetObjectMacro(ScalarBarWidget, vtkKWScalarBarWidget);
  virtual void SetSupportScalarBar(int);
  vtkGetMacro(SupportScalarBar, int);
  vtkBooleanMacro(SupportScalarBar, int);
  
  // Description:
  // Enable/Disable scale bar
  virtual void SetScaleBarVisibility(int state);
  virtual int  GetScaleBarVisibility();
  virtual void ToggleScaleBarVisibility();
  vtkBooleanMacro(ScaleBarVisibility, int);
  virtual double* GetScaleBarColor();
  virtual void SetScaleBarColor(double r, double g, double b);
  virtual void SetScaleBarColor(double *rgb)
    { this->SetScaleBarColor(rgb[0], rgb[1], rgb[2]); };
  vtkGetObjectMacro(ScaleBarWidget, vtkKWScaleBarWidget);
  virtual void SetSupportScaleBar(int);
  vtkGetMacro(SupportScaleBar, int);
  vtkBooleanMacro(SupportScaleBar, int);

  // Description:
  // Set the 3D cursor
  //BTX
  enum
  {
    CURSOR_TYPE_CROSSHAIR = 0,
    CURSOR_TYPE_PLANE = 1
  };
  //ETX
  virtual void SetCursor3DPosition(double x, double y, double z);
  virtual double* GetCursor3DPosition();
  virtual void GetCursor3DPosition(double pos[3]);
  virtual void SetCursor3DXColor(double r, double g, double b);
  virtual void SetCursor3DXColor(double *rgb)
    { this->SetCursor3DXColor(rgb[0], rgb[1], rgb[2]); };
  virtual void SetCursor3DYColor(double r, double g, double b);
  virtual void SetCursor3DYColor(double *rgb)
    { this->SetCursor3DYColor(rgb[0], rgb[1], rgb[2]); };
  virtual void SetCursor3DZColor(double r, double g, double b);
  virtual void SetCursor3DZColor(double *rgb)
    { this->SetCursor3DZColor(rgb[0], rgb[1], rgb[2]); };
  virtual double* GetCursor3DXColor();
  virtual double* GetCursor3DYColor();
  virtual double* GetCursor3DZColor();
  virtual void SetCursor3DType(int type);
  virtual int  GetCursor3DType();
  virtual void SetCursor3DVisibility(int state);
  virtual int  GetCursor3DVisibility();
  vtkBooleanMacro(Cursor3DVisibility, int);
  virtual void SetCursor3DInteractiveState(int state);
  vtkGetObjectMacro(Cursor3DWidget, vtkKWCursorWidget);
  vtkGetObjectMacro(Image, vtkImageActor);
  
  // Description:
  // Set the spline curves in 3D
  virtual void SetSplineCurves3D( vtkKW3DSplineCurvesWidget * curves );
  
  // Description:
  // Set the spline surfaces in 3D
  // Set their visibility as a group
  // Set the visibility of a single spline surface
  virtual void SetSplineSurfaces3D( vtkKW3DSplineSurfacesWidget * surfaces );
  void SetSplineSurfaces3DVisibility(int v);
  void SetSplineSurfaces3DVisibility(const char * surfaceId, int v);
  void SetSplineSurfaces3DProperty(const char * surfaceId, vtkProperty * property);
 
  // Description:
  // Get the interactor style
  virtual vtkKWInteractorStyle2DView* GetInteractorStyle();

  // Description:
  // Given mouse coordinate, compute world coordinate, eventually return
  // the id of the renderer if the widget supports multiple renderers
  // (see vtkKWRenderWidget::GetNthRenderer, 
  // vtkKWRenderWidget::GetRendererIndex)
  virtual int ComputeWorldCoordinate(int x, int y, double *result, int *id = 0);

  // Description:
  // Configure the event map
  virtual void ConfigureEventMap();

  // Description:
  // Enable/Disable linear interpolation
  virtual void SetInterpolate(int state);
  virtual int  GetInterpolate();

protected:
  vtkKWImageWidget();
  ~vtkKWImageWidget();
  
  // Description:
  // Create the widget
  virtual void CreateWidget();
  
  // Description:
  // Connects the internal object together given the Input.
  virtual int ConnectInternalPipeline();

  // Description:
  // Those methods are called automatically by UpdateAccordingToInput() if:
  // - InputScalarStructureHasChanged(): the input scalar structure has changed
  // - InputBoundsHaveChanged(): the input bounds have changed
  // - InputHasChanged(): any of the above changes happened, it is passed
  //                      a mask representing the changes.
  // Returns 1 on success, 0 on error or to signal that it is safe to abort
  virtual int InputScalarStructureHasChanged();
  virtual int InputBoundsHaveChanged();
  virtual int InputHasChanged(int mask);

  // Description:
  // Update the display extent according to what part of the Input has to
  // be displayed. It is probably the right place to adjust/place the 3D
  // widget which position depends on the display extent.
  virtual void UpdateDisplayExtent();

  // Description:
  // Update the image map
  virtual void UpdateImageMap();

  // Description:
  // Update internal objects according to the orientation and type
  virtual void UpdateSliceOrientationAndType();
  
  // Description:
  // Update internal objects according to the current unit
  virtual void UpdateAccordingToUnits();

  // Update the orientation and position of the implicit plane defining the
  // image plane.
  void UpdateImplicitPlaneSplineSurfaces();

  // Description:
  // Populate the context menu
  virtual void PopulateContextMenuWithAnnotationEntries(vtkKWMenu*);

  vtkImageActor *Image;
  
  vtkKWInteractorStyleImageView *InteractorStyle;

  int Cursor3DType;
  int SupportScaleBar;
  int SupportScalarBar;

  vtkKWCursorWidget           *Cursor3DWidget;
  vtkKWCroppingRegionsWidget  *CroppingWidget;
  vtkKWScalarBarWidget        *ScalarBarWidget;
  vtkKWScaleBarWidget         *ScaleBarWidget;
  vtkKW2DSplineSurfacesWidget *SplineSurfaces;
  
private:
  vtkKWImageWidget(const vtkKWImageWidget&);  // Not implemented
  void operator=(const vtkKWImageWidget&);  // Not implemented
};

#endif
