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

  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 vtkKW3DSplineSurfacesWidget - widget for measuring distance along a line
// .SECTION Description

#ifndef __vtkKW3DSplineSurfacesWidget_h
#define __vtkKW3DSplineSurfacesWidget_h

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

#include <vtkstd/map>    // used for keeping track of the SplineSurfaces
#include <vtkstd/string> // used for the index of the SplineSurfaces map

class vtkSplineSurfaceWidget;
class vtkProperty;
class vtkPoints;

class VTK_EXPORT vtkKW3DSplineSurfacesWidget : public vtkKW3DWidget
{
public:
  static vtkKW3DSplineSurfacesWidget *New();
  vtkTypeRevisionMacro(vtkKW3DSplineSurfacesWidget, vtkKW3DWidget);
  void PrintSelf(ostream& os, vtkIndent indent);
  //BTX
  vtkKWGetXMLReaderWriterObjectsMacro();
  //ETX
  
  virtual void SetEnabled(int enabling);

  // Description:
  // Add, a Spline Surface
  virtual void AddSplineSurface(const char * name=NULL);
  virtual void AddSplineSurface( double bounds[6], const char * name=NULL );

  // Description:
  // Add, a Spline Surface
  virtual void AddIrregularSplineSurface(const char *name=NULL);
  virtual void AddIrregularSplineSurface( double bounds[6],const char *name=NULL);

  // Description:
  // Get the current number of spline surface
  virtual unsigned int GetNumberOfSplineSurfaces();
   
  // Description:
  // Get the current number of points in a spline surface
  virtual unsigned int GetNumberOfPointsInASplineSurface(const char * id);

  // Description: 
  // Get the points from a spline surface (those are the points used
  // for representing the surface, not the control points of the spline
  virtual vtkPoints * GetPointsInASplineSurface(const char * id);

  // Description:
  // Get the selected active spline surface
  virtual vtkSplineSurfaceWidget * GetSplineSurfaceWidget(const char * id);
  
  // Description:
  // Remove a specific spline surface identified with id
  // Remove all the spline surfaces
  virtual void RemoveSplineSurfaceId(const char * id);
  virtual void RemoveAllSplineSurfaces();

  // Description:
  // Check if a particular spline surface already exists
  virtual int HasSplineSurface(const char * surfaceId);

  // Description:
  // Set/Get the Property associated with the surface of a particular spline widget.
  // Return the Visibility associated with the surface of a particular spline widget.
  virtual  void          SetSplineSurfaceProperty(const char * surfaceId,vtkProperty * property);
  virtual  vtkProperty * GetSplineSurfaceProperty(const char * surfaceId);
  virtual  int   GetSplineSurfaceVisibility(const char * surfaceId);
  virtual  void  SetSplineSurfaceVisibility(const char * surfaceId,int v);


  // Description:
  // Set number of handles for the spline surface
  // Get number of handles along each direcction
  // Get the coordinates of a control point (handle)
  // Set the coordinates of a control point (handle)
  // Set the coordinates of all the control points in a particular spline surface
  virtual  void  SetSplineSurfaceNumberOfHandles(const char * surfaceId,int nh );
  virtual  int   GetNumberOfHandles( const char * surfaceId );
  virtual  double * GetSplineSurfaceControlPoint(const char * surfaceId, vtkIdType pointId);
  virtual  void SetSplineSurfaceControlPoint(const char * surfaceId, vtkIdType pointId, double *);
  virtual  void SetSplineSurfaceControlPoints(const char * surfaceId, float * allPointCoordinates);

  // Description:
  // Update widget representation when the bound have changed.
  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); }


//BTX - Set of Events for Command/Observer interface
  enum SplineSurfaceInteractions
  {
    AddSplineSurfaceEvent=10000,
    RemoveSplineSurfaceEvent
  };
//ETX


//BTX
  typedef vtkstd::string                                    MapKeyType;
  typedef vtkstd::map<MapKeyType,vtkSplineSurfaceWidget *>  SplineSurfacesContainer;
  SplineSurfacesContainer SplineSurfaces;
  // The active spline surface
  typedef SplineSurfacesContainer::iterator                 Iterator;
  typedef SplineSurfacesContainer::const_iterator           ConstIterator;

  Iterator Begin();
  Iterator End();
//ETX


protected:
  vtkKW3DSplineSurfacesWidget();
  ~vtkKW3DSplineSurfacesWidget();

  
  int DeallocateMarkerResources(unsigned int id);

  // handles the events
  static void ProcessEvents(vtkObject* object,
                            unsigned long event,
                            void* clientdata,
                            void* calldata);
  

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


};

#endif
