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

  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 vtkKWOpenFileProperties - a helper class that encapsulates properties of a file (structured data) open with the Open Wizard

#ifndef __vtkKWOpenFileProperties_h
#define __vtkKWOpenFileProperties_h

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

class vtkImageData;

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

  // Description:
  // Reset all the internal values to their default settings
  virtual void Reset(); 

  // Description:
  // Set/Get the origin for this file
  virtual void SetOrigin(double arg[3]);
  virtual void SetOrigin(double arg1, double arg2, double arg3);
  virtual double* GetOrigin();
  virtual void GetOrigin(double &arg1, double &arg2, double &arg3);
  virtual void GetOrigin(double arg[3]);

  // Description:
  // Set/Get the spacing for this file
  virtual void SetSpacing(double arg[3]);
  virtual void SetSpacing(double arg1, double arg2, double arg3);
  virtual double* GetSpacing();
  virtual void GetSpacing(double &arg1, double &arg2, double &arg3);
  virtual void GetSpacing(double arg[3]);

  // Description:
  // Set/Get the whole extent for this file
  virtual void SetWholeExtent(int arg[6]);
  virtual void SetWholeExtent(int arg1, int arg2, int arg3,
    int arg4, int arg5, int arg6);
  virtual int* GetWholeExtent();
  virtual void GetWholeExtent(int &arg1, int &arg2, int &arg3, 
    int &arg4, int &arg5, int &arg6);
  virtual void GetWholeExtent(int arg[6]);

  // Description:
  // Set/Get the scalar type for this file
  // VTK_FLOAT, VTK_DOUBLE, VTK_INT, VTK_LONG, VTK_SHORT, VTK_CHAR, etc.
  virtual void SetScalarType(int);
  virtual int GetScalarType();

  // Description:
  // Set/Get the number of scalar components for this file
  virtual void SetNumberOfScalarComponents(int);
  virtual int GetNumberOfScalarComponents();

  // Description:
  // Set/Get how the components are to be handled for this file
  vtkBooleanMacro(IndependentComponents, int);
  vtkGetMacro(IndependentComponents, int);
  vtkSetMacro(IndependentComponents, int);
  
  // Description:
  // Set/Get the physical units for this file (e.g. mm, cm, inches)
  vtkSetStringMacro(DistanceUnits);
  vtkGetStringMacro(DistanceUnits);

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

  // Description:
  // Set/Get the databyte order for this file.
  // The above constant match vtkImageReader2's VTK_FILE_BYTE_ORDER_BIG_ENDIAN
  // and VTK_FILE_BYTE_ORDER_LITTLE_ENDIAN
  //BTX
  enum
  {
    DataByteOrderBigEndian    = 0,
    DataByteOrderLittleEndian = 1,
    DataByteOrderUnknown      = 2
  };
  //ETX
  vtkGetMacro(DataByteOrder, int);
  virtual void SetDataByteOrder(int);
  virtual void SetDataByteOrderToBigEndian();
  virtual void SetDataByteOrderToLittleEndian();
  virtual void SetDataByteOrderToUnknown();

  // Description:
  // Set/Get file dimensionality for this file
  // Set to 0 by default for "unknown"
  vtkGetMacro(FileDimensionality, int);
  vtkSetClampMacro(FileDimensionality, int, 0, 3);
  
  // Description:
  // Set/Get the scope of this file
  //BTX
  enum
  {
    ScopeUnknown = 0,
    ScopeMedical,
    ScopeScientific
  };
  //ETX
  vtkGetMacro(Scope, int);
  virtual void SetScope(int);
  virtual void SetScopeToUnknown();
  virtual void SetScopeToMedical();
  virtual void SetScopeToScientific();

  // Description:
  // Set/Get the orientation of the volume for this file
  // This constants used by the orientation filter in the Open Wizard to
  // define the mapping between input and output axis (say, for example
  // the input Column Axis +X to the output Row Axis -Y, etc).
  //BTX
  enum
  {
    AxisOrientationPlusX     = 0,  // Left
    AxisOrientationMinusX    = 1,  // Right
    AxisOrientationPlusY     = 2,  // Posterior
    AxisOrientationMinusY    = 3,  // Anterior
    AxisOrientationPlusZ     = 4,  // Superior
    AxisOrientationMinusZ    = 5,  // Inferior
    AxisOrientationUnknown   = 6
  };
  //ETX
  vtkGetMacro(SliceAxis, int);
  vtkGetMacro(RowAxis, int);
  vtkGetMacro(ColumnAxis, int);
  virtual void SetSliceAxis(int);
  virtual void SetRowAxis(int);
  virtual void SetColumnAxis(int);

  // Description:
  // Set/Get the file pattern for this file
  // This is relevant when loading a set of slices. While the open wizard
  // does a decent job at guessing the pattern, any other complex pattern
  // entered by the user should be remembered, hence this variable.
  vtkSetStringMacro(FilePattern);
  vtkGetStringMacro(FilePattern);

  // Description:
  // Return an absolute file pattern if the current FilePattern is relative.
  // This is done by assuming the absolute filename passed as a parameter is
  // one that would match the FilePattern and therefore its directory can
  // be used to build the absolute file pattern. If it was absolute already,
  // just return its current value.
  // This returns a pointer to a static buffer, so copy it ASAP.
  virtual const char* GetAbsoluteFilePatternForFile(const char *filename);

  // Description:
  // Convenience method to return if the orientation is valid, given
  // the column, row, and slice axis choices
  static int IsOrientationValid(int col_axis, int row_axis, int slice_axis);

  // Description:
  // Convenience method to get the size of the scalar type in bytes.
  virtual int GetScalarSize();

  // Description:
  // Convenience method to get the minimum and maximum values the
  // ScalarType can hold without overflowing.
  virtual double GetScalarTypeMin();
  virtual double GetScalarTypeMax();

  // Description:
  // Convenience method to copy all fields that are relevant to an
  // vtkImageData structure inside such an object, and vice/versa
  // See also DeepCopy to copy a whole instance to another.
  virtual void CopyToImageData(vtkImageData*);
  virtual void CopyFromImageData(vtkImageData*);

  // Description:
  // Query if the internal properties are the same as the internal properties
  // of a given instance.
  virtual int IsEqual(vtkKWOpenFileProperties*);

protected:
  vtkKWOpenFileProperties();
  ~vtkKWOpenFileProperties();

  // Description:
  // Distance units
  char *DistanceUnits;

  // Description:
  // Scalar units
  char *ScalarUnits[VTK_MAX_VRCOMP];

  // Description:
  // Independent components
  int IndependentComponents;

  // Description:
  // File dimensionality
  int FileDimensionality;

  // Description:
  // Data byte order
  int DataByteOrder;

  // Description:
  // Scope
  int Scope;

  // Description:
  // Orientation
  int SliceAxis;
  int RowAxis;
  int ColumnAxis;

  // Description:
  // File pattern
  char *FilePattern;

private:

  vtkImageData *ImageInformation;

  vtkKWOpenFileProperties(const vtkKWOpenFileProperties&); // Not implemented
  void operator=(const vtkKWOpenFileProperties&); // Not Implemented
};

#endif
