//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
//
//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
//
//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//

#ifndef __VISU_SphereWidget_h
#define __VISU_SphereWidget_h

#include "VISUPipeline.hxx"
#include "VISU_ImplicitFunctionWidget.hxx"

class VISU_UnScaledActor;

class vtkActor;
class vtkPolyDataMapper;
class vtkPoints;
class vtkPolyData;
class vtkSphereSource;
class vtkSphere;
class vtkCellPicker;
class vtkProperty;
class vtkSphere;
class vtkImplicitSum;
class vtkImplicitFunction;
//
class VISU_PIPELINE_EXPORT VISU_SphereWidget : public VISU_ImplicitFunctionWidget
{
public:
  // Description:
  // Instantiate the object.
  static VISU_SphereWidget *New();
  vtkTypeRevisionMacro(VISU_SphereWidget,VISU_ImplicitFunctionWidget);
  void PrintSelf(ostream& os, vtkIndent indent);

  virtual vtkImplicitFunction* ImplicitFunction();
  
  // Description:
  // Methods that satisfy the superclass' API.
  virtual void SetEnabled(int);
  //
  //PlaceWidget
  virtual void PlaceWidget(vtkFloatingPointType bounds[6]);
  //
  // Description:
  // Set/Get the resolution of the sphere in the Theta direction.
  void SetThetaResolution(int r);
  int GetThetaResolution(); 
  // Description:
  // Set/Get the resolution of the sphere in the Phi direction.
  void SetPhiResolution(int r);
  int GetPhiResolution();

  // Description:
  // Set/Get the radius of sphere. Default is .5.
  void SetRadius(vtkFloatingPointType r); 
  vtkFloatingPointType GetRadius();
  

  // Description:
  // Set/Get the center of the sphere.
  void SetCenter(vtkFloatingPointType x, 
                 vtkFloatingPointType y, 
                 vtkFloatingPointType z); 
  void SetCenter(vtkFloatingPointType x[3]); 
  
  vtkFloatingPointType* GetCenter(); 
  void GetCenter(vtkFloatingPointType xyz[3]); 
  
  // Description:
  // Set the ratio of the radius changing.
  void SetRatio(vtkFloatingPointType r) { myRatio = r; } 
  vtkFloatingPointType GetRatio() { return myRatio; } 

  void ChangeRadius(bool up);

  void GetPolyData(vtkPolyData *pd);

  void GetSphere(vtkSphere *sphere);

  
  vtkProperty* GetSphereProperty ();
  vtkProperty* GetSelectedSphereProperty ();
  
    
protected:
  VISU_SphereWidget();
  ~VISU_SphereWidget();

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

  // ProcessEvents() dispatches to these methods.
  void OnLeftButtonDown();
  void OnLeftButtonUp();
  void OnMiddleButtonDown();
  void OnMiddleButtonUp();
  void OnMouseMove();

  void HighlightSphere(int highlight);

  // Methods to manipulate the sphere widget
  void Translate(double *p1, double *p2);
  void Scale(double *p1, double *p2, int X, int Y);

  //virtual void SizeHandles();
  void CreateDefaultProperties();

  //BTX - manage the state of the widget
  int myState;
  enum WidgetState
  {
    Start=0,
    Moving,
    Scaling,
    Positioning,
    Outside
  };
  //ETX
  // the sphere
  vtkActor       *mySphereActor;
  vtkPolyDataMapper *mySphereMapper;
  vtkSphereSource   *mySphereSource;
  //
  // the Picker
  vtkCellPicker *myPicker;
  // Properties used to control the appearance of selected objects and
  // the manipulator in general.
  vtkProperty *mySphereProperty;
  vtkProperty *mySelectedSphereProperty;
  vtkFloatingPointType myRmin;
  vtkSphere *mySphere;
  vtkImplicitSum* myImplicitSum;
  vtkFloatingPointType myRatio;
private:
  VISU_SphereWidget(const VISU_SphereWidget&);  //Not implemented
  void operator=(const VISU_SphereWidget&);  //Not implemented
};

#endif
