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

  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 vtkCardinalSplinePatch - a 2D patch embedded in 3D made of the tensor product of CardinalSplines
// .SECTION Description
//
// This class implements a 2D Cardinal Spline patch with nodes in 3D space.
// The patch is computed as the tensor product of two 1D Cardinal Spline interpolators.
//

// .SECTION See Also
// vtkSpline


#ifndef __CardinalSplinePatch_h
#define __CardinalSplinePatch_h

#include "vtkObject.h"

class vtkSpline;
class SplineVectorType;

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

  vtkTypeRevisionMacro(vtkCardinalSplinePatch,vtkObject);
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Set/Get the number of control points along directions U and V
  // this widget.
  vtkSetMacro(NumberOfHandlesU,unsigned int);
  vtkSetMacro(NumberOfHandlesV,unsigned int);
  vtkGetMacro(NumberOfHandlesU,unsigned int);
  vtkGetMacro(NumberOfHandlesV,unsigned int);

  // Description:
  // Set/Get the position of the spline handles. Call GetNumberOfHandlesU and
  // GetNumberOfHandlesV to determine the valid range of handle indices.
  void SetHandlePosition(unsigned int u, unsigned int v, double x, double y, double z);
  void SetHandlePosition(unsigned int u, unsigned int v, double xyz[3]);
  void GetHandlePosition(unsigned int u, unsigned int v, double xyz[3]);
  double* GetHandlePosition(unsigned int u, unsigned int v);

  // Description:
  // Allocate memory for the container of Handles. This method must be called
  // before attempting to set any handler coordinates, and after setting the
  // number of handles along U and V.
  void Allocate();

  // Description:
  // Evaluate the position of the CardinalSpline patch at the parametric point (u,v)
  // The user must allocate the memory for "point". This method will simply
  // write at the position indicated by this pointer.
  void Evaluate( double u, double v, double * point );
  void PrepareToEvaluateAlongV( double v );
  void EvaluateAfterFixingV( double u, double * point );

  // Description:
  // Evaluate the position of the points representing the CardinalSpline patch surface
  void Compute();

protected:
  vtkCardinalSplinePatch();
  ~vtkCardinalSplinePatch();

  unsigned int NumberOfHandlesU;
  unsigned int NumberOfHandlesV;

  vtkSpline* CreateDefaultSpline();

  void ReleaseAllSplines();
  void CreateSplines();

//BTX
  // The spline
  SplineVectorType * XSpline;
  SplineVectorType * YSpline;
  SplineVectorType * ZSpline;

  vtkSpline * VXSpline;
  vtkSpline * VYSpline;
  vtkSpline * VZSpline;
//ETX

  // an array of 3 x NumberOfHandlesU x NumberOfHandlesV doubles containing the
  // coordinates of all the control points.
  double *Handles;  

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

#endif
