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

  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 vtkSubdivisionSplineSurfaceWidget - 3D widget for manipulating a spline surface patch.
// .SECTION Description
//
// This class was created as a variation of the vtkSplineSurfaceWidget.
// Here a surface is generated using a set of cubic Bezier patches providing C2
// continuity on the surface.
// 
// .SECTION See Also
// vtkSplineSurfaceWidget vtk3DWidget vtkBoxWidget vtkLineWidget vtkPointWidget
// vtkSphereWidget vtkImagePlaneWidget vtkImplicitPlaneWidget vtkPlaneWidget


#ifndef __vtkSubdivisionSplineSurfaceWidget_h
#define __vtkSubdivisionSplineSurfaceWidget_h

#include "vtkSplineSurfaceWidget.h"

class vtkDelaunay2D;
class vtkTriangleFilter;
class vtkButterflySubdivisionFilter;


class VTK_EXPORT vtkSubdivisionSplineSurfaceWidget : public vtkSplineSurfaceWidget
{
public:
  // Description:
  // Instantiate the object.
  static vtkSubdivisionSplineSurfaceWidget *New();

  vtkTypeRevisionMacro(vtkSubdivisionSplineSurfaceWidget,vtkSplineSurfaceWidget);
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Methods that satisfy the superclass' API.
  virtual void PlaceWidget(double bounds[6]);
  virtual void PlaceWidget()
    {this->Superclass::PlaceWidget();}
  virtual void PlaceWidget(double xmin, double xmax, double ymin, double ymax, 
                   double zmin, double zmax)
    {this->Superclass::PlaceWidget(xmin,xmax,ymin,ymax,zmin,zmax);}

  // Description:
  // Set the resolution level of the surface. This value is used directly as
  // the number of subdivision levels to be performed by the SubdivisionFilter.
  // Note that the number of resulting surface points will be proportional to
  // the expression:  NumberOfHandles * 4 ^ Resolution.
  vtkSetMacro(Resolution,unsigned int);
  vtkGetMacro(Resolution,unsigned int);

  // Description:
  // Generate the points on the Spline Surface
  virtual void GenerateSurfacePoints();

protected:
  vtkSubdivisionSplineSurfaceWidget();
  ~vtkSubdivisionSplineSurfaceWidget();

  virtual void Initialize();
  virtual void BuildRepresentation();

  // Insert and Remove Handles. Note that not all derived classes will respond
  // to this invokations. By default these methods are a null operation.
  virtual void InsertHandle();
  virtual void InsertHandle(double position[3]);
  virtual void RemoveHandle();
  virtual void RemoveHandle(int handleIndex)
    {this->Superclass::RemoveHandle(handleIndex);}

private:
  vtkSubdivisionSplineSurfaceWidget(const vtkSubdivisionSplineSurfaceWidget&);  //Not implemented
  void operator=(const vtkSubdivisionSplineSurfaceWidget&);  //Not implemented

  // Polydata for holding the grid of handles
  vtkPolyData * HandlesGrid;

  // Filters for generating the topology of the handles grid
  vtkDelaunay2D * DelaunayFilter;
  vtkTriangleFilter * TriangleFilter;
  vtkButterflySubdivisionFilter * SubdivisionFilter;

  // controls the number of levels of the subdivision
  unsigned int Resolution; 
};

#endif
