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

  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 vtkVVDataItemVolume - a class that encapsulates a single volume
// .SECTION Description
// This is a single volume.

#ifndef __vtkVVDataItemVolume_h
#define __vtkVVDataItemVolume_h

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

class vtkImageData;
class vtkKWCroppingRegionsWidget;
class vtkKWCursorWidget;
class vtkKWHistogram;
class vtkKWHistogramSet;
class vtkKWImageWidget;
class vtkKWInteractorStyle2DView;
class vtkKWLightboxWidget;
class vtkKWOpenFileProperties;
class vtkKWOpenWizard;
class vtkKWProbeImageWidget;
class vtkKWRenderWidget;
class vtkKWRenderWidgetPro;
class vtkKWVolumeWidget;
class vtkMedicalImageProperties;
class vtkVVDataItemVolumeInternals;
class vtkVVLODDataItemVolumeHelper;
class vtkVVSelectionFrame;
class vtkVVDataItemVolumeContourCollection;
class vtkVolumeProperty;

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

  // Description:
  // Set/Get the image data (i.e. the main data/volume).
  // It is ref counted.
  virtual void SetImageData(vtkImageData *data);
  vtkGetObjectMacro(ImageData, vtkImageData);

  // Description:
  // Set/Get the scalar units for this dataset (e.g. density, T1, T2, etc)
  // There are up to four values depending on how many components the
  // dataset has
  virtual const char *GetScalarUnits(int c);
  virtual void SetScalarUnits(int c, const char *units);

  // Description:
  // Set/Get the volume property.
  // It is ref counted.
  virtual void SetVolumeProperty(vtkVolumeProperty *prop);
  virtual vtkVolumeProperty* GetVolumeProperty();

  // Description:
  // Set/Get the medical image properties.
  // It is ref counted.
  virtual void SetMedicalImageProperties(vtkMedicalImageProperties *prop);
  vtkGetObjectMacro(MedicalImageProperties, vtkMedicalImageProperties);

  // Description:
  // Specify which mode are allowed (by default everything is turned on):
  // - Volume
  // - LightBox
  // - Axial
  // - Coronal
  // - Sagittal
  // E.g. If you would like only Axial & Coronal, specify: 
  // SetDisplayMode(vtkVVDataItemVolume::ModeAxial | 
  //                vtkVVDataItemVolume::ModeCoronal)
  //BTX
  typedef enum 
  {
    ModeVolume   = 1,
    ModeLightBox = 2,
    ModeAxial    = 4,
    ModeCoronal  = 8,
    ModeSagittal = 16
  } DisplayModes;
  //ETX
  vtkGetMacro(DisplayMode, int);
  vtkSetMacro(DisplayMode, int);

  // Description:
  // Check if there is enough memory to load a volume which structure is
  // described by a vtkImageData or vtkKWOpenFileProperties. 
  // The application parameter is required to prompt the user for input.
  static int CheckForMemory(
    vtkImageData *input, vtkKWApplication *app);
  static int CheckForMemory(
    vtkKWOpenFileProperties *open_prop, vtkKWApplication *app);

  // Description:
  // Get the scalar range across the whole volume for a given component.
  // Return 1 of success, 0 otherwise
  virtual int GetScalarRange(int c, double range[2]);

  // Description:
  // Get the histogram for the whole volume at a given component.
  virtual vtkKWHistogram* GetHistogram(int component);
  vtkGetObjectMacro(HistogramSet, vtkKWHistogramSet);

  // Description:
  // Get the collection of contours on this volume
  vtkGetObjectMacro(Contours, vtkVVDataItemVolumeContourCollection);

  // Description:
  // Load from open wizard
  // Return 1 of success, 0 otherwise
  virtual int LoadFromOpenWizard(vtkKWOpenWizard *, int output_port);

  // Description:
  // Set/Get the descriptive name of the data item. 
  // The descriptive name is used to provide a reasonable but short clue to 
  // the user about the data. If not set, it default to the name of the
  // data item. Since the name is usually the filename to the data, subclasses
  // are suggested to set the descriptive name to something more meaningful,
  // say the name of the patient if the data item is a medical data.
  // Override the parent method to use the internal medical properties
  virtual const char *GetDescriptiveName();

  // Description:
  // Get the bounds of the data
  virtual void GetBounds(double bounds[6]);
  
  // Description:
  // Release data. This comply with the superclass API, and will set
  // ImageData to NULL.
  virtual void ReleaseData();

  // Description:
  // Update the annotations of all the render widgets associated to this
  // data.
  virtual void UpdateRenderWidgetsAnnotations();

  // -----------------------------------------------------------------------
  // Undo/Redo for plugins

  // Description:
  // Set/Get the Undo or Redo image data. Once plugins operate on the dataset,
  // this stores the previous volume, to aid quick undo or redo plugin
  // operations. 
  // It is ref counted.
  virtual int SetUndoRedoImageData(vtkImageData *data);
  vtkGetObjectMacro(UndoRedoImageData, vtkImageData);

  // Description:
  // Set/Get the plugin name that produced the UndoRedoImageData. See
  // UndoRedoPluginName below
  vtkGetStringMacro(UndoRedoPluginName);
  vtkSetStringMacro(UndoRedoPluginName);

  // Description:
  // The type of plugin operation that must be allowed by a plugin. This must
  // be an iVar of the DataItemVolume, since it is the responsiblity of each
  // DataItemVolume to maintain its Undo/Redo data and know which plugin
  // should be allowed to invoke this Undo/Redo and whether this operation 
  // should be an Undo or a Redo.
  //BTX
  enum
  {
    Undo=0,
    Redo,
    Nothing
  };
  //ETX
  
  // Description:
  // Set/Get the type of operation here. Note: Setting it to none, destroys the
  // UndoRedo dataset.
  virtual void SetUndoRedoImageDataType(unsigned int);
  vtkGetMacro( UndoRedoImageDataType, unsigned int );
  virtual void SetUndoRedoImageDataTypeToUndo()
  { this->SetUndoRedoImageDataType(vtkVVDataItemVolume::Undo); };
  virtual void SetUndoRedoImageDataTypeToRedo()
  { this->SetUndoRedoImageDataType(vtkVVDataItemVolume::Redo); };
  virtual void SetUndoRedoImageDataTypeToNothing()
  { this->SetUndoRedoImageDataType(vtkVVDataItemVolume::Nothing); };

  // -----------------------------------------------------------------------
  // The following methods are per-window, i.e. one can add/retrieve/configure
  // the default render widgets to several windows...

  // Description:
  // Add/Remove default widgets to a widget layout manager.
  // For image/volume data, this will create the default 3D view, 2D views,
  // lightbox, etc.
  virtual void AddDefaultRenderWidgets(vtkVVWindowBase *win);
  virtual void RemoveDefaultRenderWidgets(vtkVVWindowBase *win);

  // Description:
  // Get some of the unique widgets (if valid) for a given window
  virtual vtkKWLightboxWidget *GetLightboxWidget(vtkVVWindowBase *win);
  virtual vtkKWVolumeWidget *GetVolumeWidget(vtkVVWindowBase *win);
  virtual vtkKWProbeImageWidget *GetObliqueProbeWidget(vtkVVWindowBase *win);
  virtual vtkKWRenderWidget *GetNthRenderWidget(vtkVVWindowBase *win, int idx);

  // Description:
  // Query if the data item has a representation (say a 2D or 3D view) in
  // a given window.
  virtual int HasRenderWidgetInWindow(vtkVVWindowBase *win);
  
  // Description:
  // Enable/Disable the oblique probe in a given window
  virtual void SetObliqueProbeVisibility(vtkVVWindowBase *win, int state);
  virtual int GetObliqueProbeVisibility(vtkVVWindowBase *win);
  
  // Description:
  // Enable/Disable cropping for all the render widgets associated to this
  // data, also set cropping planes, etc.
  virtual void SetCroppingMode(vtkVVWindowBase *win, int state);
  virtual int GetCroppingMode(vtkVVWindowBase *win);
  virtual void SetCroppingPlanes(
    vtkVVWindowBase *win, 
    double p0, double p1, double p2, double p3, double p4, double p5);
  virtual void ResetCroppingPlanes(vtkVVWindowBase *win);

  // Description:
  // Enable/Disable 3D cursors for all the render widgets associated to this
  // data, also set cursor position, etc.
  virtual void SetCursorVisibility(vtkVVWindowBase *win, int state);
  virtual int GetCursorVisibility(vtkVVWindowBase *win);
  virtual void SetCursorPosition(
    vtkVVWindowBase *win, double x, double y, double z);

  // Description:
  // Get number of renderwidgets (including all windows) amd a specific widget
  virtual int GetNumberOfRenderWidgets();
  virtual vtkKWRenderWidget *GetNthRenderWidget(int idx);

  // Description:
  // Get some of the unique widgets (if valid) for a given internal class
  virtual vtkKWImageWidget *GetImageWidgetUsingCroppingRegionsWidget(
    vtkKWCroppingRegionsWidget *cropping_w);
  virtual vtkKWImageWidget *GetImageWidgetUsingCursorWidget(
    vtkKWCursorWidget *cursor_w);
  virtual vtkKWProbeImageWidget *GetObliqueProbeWidgetUsingInteractorStyle(
    vtkKWInteractorStyle2DView *style);

  // Description:
  // Reset all renderwidgets' inputs. This can be useful if the ImageData
  // has been updated/reloaded. 
  virtual void ResetRenderWidgetsInput();

  // Description:
  // The volume can manage datasets at multiple resolutions. (Limited to low and
  // high for now). This will be created only when this method is invoked by
  // the user for the first time.
  virtual vtkVVLODDataItemVolumeHelper *GetLODHelper();

  // Description:
  // Enable garbage collection. There are ref counting cycles with 
  // vtkVVDataItemVolumeContourCollection
  virtual void Register(vtkObjectBase* o);
  virtual void UnRegister(vtkObjectBase* o);  

protected:
  vtkVVDataItemVolume();
  ~vtkVVDataItemVolume();

  // Description:
  // Histograms
  vtkKWHistogramSet *HistogramSet;

  // Contours (surfaces):
  vtkVVDataItemVolumeContourCollection * Contours;

  // Description:
  // PIMPL Encapsulation for STL containers
  //BTX
  vtkVVDataItemVolumeInternals *Internals;
  //ETX

  // Description:
  // The image data itself
  vtkImageData *ImageData;

  // Description:
  // Once plugins operate on the dataset, this stores the Undo or the
  // Redo data.
  vtkImageData *UndoRedoImageData;

  // Description:
  // Plugin that gave the UndoRedoImageData. An UndoRedoImageData is 
  // associated to a volume and the plugin that produced it. This string is
  // set by the appropriate plugin using 
  // vtkVVPluginSelector::GetPrettyPluginName()
  char *UndoRedoPluginName;

  // Description:
  // Type of plugin operation 
  unsigned int UndoRedoImageDataType;

  // Description:
  // The common volume property
  vtkVolumeProperty *VolumeProperty;
 
  // Description:
  // Scalar units
  char *ScalarUnits[VTK_MAX_VRCOMP];

  // Description:
  // Some medical image properties
  vtkMedicalImageProperties *MedicalImageProperties;

  // Description:
  // Create and configure a renderwidget for a specific window, and
  // add it to the window's layout manager inside a new instance
  // of vtkKWSelectionFrame (or subclass).
  // Note that the widget's RenderState is set to Off and the RenderMode to
  // Disabled, so that several widgets can be created in a row without
  // extra Render's. It is therefore up to the caller to set the RenderState
  // back to On and the RenderMode back to Still, then call Render(). 
  virtual int CreateRenderWidget(
    vtkVVWindowBase *win, vtkKWRenderWidgetPro *rwp);

  // Description:
  // Update a renderwidget's annotations
  virtual void UpdateRenderWidgetAnnotations(vtkKWRenderWidgetPro *rwp);

  // Description:
  // Processes the events that are passed through CallbackCommand (or others).
  // Subclasses can override this method to process their own events, but
  // should call the superclass too.
  virtual void ProcessCallbackCommandEvents(
    vtkObject *caller, unsigned long event, void *calldata);
  
  // Description:
  // Add Auto Window Level Presets
  // Return the number of presets that were added
  virtual int AddAutoWindowLevelPresets();

  // Description:
  // Store the mode that will be displayed:
  int DisplayMode;

  // Description:
  // See documentation of GetLODDataItemVolumeHelper()
  vtkVVLODDataItemVolumeHelper *LODHelper;

  // Report reference count loops. The contours refcount us
  virtual void ReportReferences(vtkGarbageCollector* collector);

  // Invoke the memory dialog. In quiet mode, we will assume that the user's
  // answer is Yes to dialogs posed and try to load the dataset automatically
  // without bringing up dialogs. If the dataset does not fit in memory at
  // all, the load will silently fail. When quiet mode is off, the behaviour is 
  // the same as before. The return value indicates whether to proceed with the
  // load or not (1 to proceed, 0 to halt).
  static int InvokeMemoryDialog( vtkKWApplication *app, 
                const char *message, int icon, int messageBoxStyle );
  
private:
  vtkVVDataItemVolume(const vtkVVDataItemVolume&); // Not implemented
  void operator=(const vtkVVDataItemVolume&); // Not implemented
};

#endif




