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

  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 vtkImageStencilDataFlip  flips a vtkImageStencilData 
// 
// .SECTION Description
// vtkImageStencilDataFlip will create a stencil with complementary extents.
// 
// There are subtle differences between this class and just using a 
// 
// \code
// vtkImageStencilData->GetNextExtent (...,..., iter = -1)
// \endcode
// 
// This class can return an inverted stencil with much larger extents than 
// the one specified.  
//
// .SECTION Motivation
// This class was written as one of a collection of classes intented for contour
// segmentation. The user would draw a contour and the contour would be 
// rasterized. The rasterization was done only within the extents of the 
// contour, to save time. The rasterization resulted in a \c vtkImageStencilData
// with extents the same as the contour. We then needed a class that could 
// conveniently flip stencils to give us the the regions outside the contour,
// (since a segmentation might cut away or cut everything but the contour).
// The stencil needed to be flipped not with respect to the extents of the 
// stencil data itself, but with respect to the extents of the image, (the 
// extents of the image can be much larger than the one of the contour).
// 
// .SECTION Parameters and Usage
// There are 2 ways to use this class.
//
// 1. To flip a vtkImageStencilData
// \code
// myvtkImageStencilDataFlip->SetInput( myvtkImageStencilData );
// myvtkImageStencilDataFlip->Update();
// myFlippedStencilData = myvtkImageStencilDataFlip->GetOutput();
// \endcode
//
// 2. To flip with respect to a larger extent. 
// \code
// myvtkImageStencilDataFlip->SetInput( myvtkImageStencilData );
// myvtkImageStencilDataFlip->SetFlipExtent(sliceExtent);
// myvtkImageStencilDataFlip->Update();
// myFlippedStencilData = myvtkImageStencilDataFlip->GetOutput();
// \endcode
//
#ifndef __vtkImageStencilDataFlip_h
#define __vtkImageStencilDataFlip_h

#include "vtkImageStencilSource.h"

class VTK_EXPORT vtkImageStencilDataFlip : public vtkImageStencilSource
{
public:
  static vtkImageStencilDataFlip *New();
  vtkTypeRevisionMacro( vtkImageStencilDataFlip, vtkImageStencilSource );
  void PrintSelf(ostream &os, vtkIndent indent);

  // Description:
  // Specify the stencil data to invert
  void SetInput(vtkImageStencilData *input);
  vtkImageStencilData *GetInput();

  // Description:
  // Optionally you may specify extents that are larger than the current 
  // extents of the stencil. (Repeat LARGER, no checking is performed to 
  // ensure this). If this is done, the stencil will be flipped with 
  // respect to these extents. (The extents computed are such that anything 
  // outside the stencil or outside the extents of the stencilData set as 
  // input via SetInput() is 1. Everything within the stencil is 0). If no
  // extents are set, the extents of the stencil are used.
  vtkSetVector6Macro(FlipExtent, int);  
  vtkGetVector6Macro(FlipExtent, int);

protected:
  vtkImageStencilDataFlip();
  ~vtkImageStencilDataFlip();

  virtual int RequestData(vtkInformation *, vtkInformationVector **, 
                                            vtkInformationVector *);

  // The input extent is the same as the one for the stencil data. The ouptut
  // extent should not always be copied to the input. The output extent will 
  // be the FlipExtent if one is specified; if not specified, it will be the
  // same as the input stencil
  virtual int RequestUpdateExtent (vtkInformation *, vtkInformationVector **, 
                                                     vtkInformationVector *);
  virtual int RequestInformation( vtkInformation *, vtkInformationVector **, 
                                         vtkInformationVector *outputVector);
  
  // Specify explicitly that we can handle only ImageStencilData as input.
  virtual int FillInputPortInformation(int, vtkInformation*);

  int FlipExtent[6];
   
private:
  vtkImageStencilDataFlip(const vtkImageStencilDataFlip&);  // Not implemented.
  void operator=(const vtkImageStencilDataFlip&);  // Not implemented.

};

#endif

