//  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
//

//  VISU OBJECT : interactive object for VISU entities implementation
//  File   : VISU_ScalarMapAct.h
//  Author : Laurent CORNABE with help of Nicolas REJNERI
//  Module : VISU
//  $Header: /home/server/cvs/VISU/VISU_SRC/src/OBJECT/VISU_GaussPtsAct.h,v 1.6.2.4.8.1 2010-04-21 16:20:15 vsr Exp $
//
#ifndef VISU_GaussPtsAct_HeaderFile
#define VISU_GaussPtsAct_HeaderFile

#include "VISU_OBJECT.h"
#include "VISU_Actor.h"
#include "VISU_GaussPtsActorFactory.h"

#include <vtkCommand.h>
#include <vtkSmartPointer.h>

class VISU_GaussPointsPL;
class VISU_WidgetCtrl;
class VISU_OpenGLPointSpriteMapper;

class vtkTextMapper;
class vtkTextActor;

class vtkSphereSource;
class vtkPolyDataMapper;
class vtkActor;
class vtkImageData;
class vtkInteractorStyle;

class VISU_GaussPtsDeviceActor;
class VISU_CursorPyramid;

class vtkUnstructuredGrid;
class vtkPolyDataMapper;
class vtkDataArray;

class vtkCellDataToPointData;
class vtkWarpVector;

class vtkInteractorObserver;
class vtkCallbackCommand;

class VISU_ScalarBarCtrl;
class VISU_InsideCursorSettings;
class VISU_OutsideCursorSettings;

class SALOME_ExtractPolyDataGeometry;
class vtkImplicitBoolean;

//============================================================================
//! Base class for Gauss Points Actors.
/*!
  The actor is responsible for representation of Gauss Points.
  It render corresponding presentation by usage of corresponding VISU_GaussPtsDeviceActor.
  Usage of such technic of rendering gives addititional flexibility to change its behaviour in run-time.
  Also, the base class implements the following functionality:
  - implements a highlight and prehighlight functionality;
  - defining a way to handle VISU_ImplicitFunctionWidget;
  - global / local scalar bar mamangement.
*/
class VISU_OBJECT_EXPORT VISU_GaussPtsAct : public VISU_Actor
{
 public:
  vtkTypeMacro(VISU_GaussPtsAct,VISU_Actor);
  typedef vtkSmartPointer<VISU_GaussPtsDeviceActor> PDeviceActor;

  static
  VISU_GaussPtsAct* 
  New();

  //----------------------------------------------------------------------------
  virtual
  void
  SetPipeLine(VISU_PipeLine* thePipeLine) ;
  
  VISU_GaussPointsPL*
  GetGaussPointsPL();

  //! Copies all properties from the given actor
  virtual
  void
  DeepCopy(VISU_Actor *theActor);

  virtual
  void
  ShallowCopyPL(VISU_PipeLine* thePipeLine);

  //----------------------------------------------------------------------------
  //! Redefined method of getting a native mapper of the actor.
  virtual
  vtkMapper* 
  GetMapper();

  //! Redefined method of getting an actor bounds.
  virtual
  vtkFloatingPointType* 
  GetBounds();

  //! Redefined method of getting an actor input.
  virtual
  vtkDataSet* 
  GetInput(); 

  //! Gets memory size used by the instance (bytes).
  virtual
  unsigned long int
  GetMemorySize();
 
  //----------------------------------------------------------------------------
  virtual
  void
  SetOpacity(vtkFloatingPointType theValue);

  //----------------------------------------------------------------------------
  virtual
  void
  SetFactory(VISU::TActorFactory* theActorFactory);
  
  VISU::TGaussPtsActorFactory*
  GetGaussPtsFactory();    

  virtual
  void 
  SetPosition(double _arg[3]);

  //----------------------------------------------------------------------------
  //! Add actor to the renderer.
  virtual
  void
  AddToRender(vtkRenderer* theRenderer); 

  //! Remove actor from the renderer.
  virtual
  void
  RemoveFromRender(vtkRenderer* theRenderer);

  //! Set the Render Window Interactor to the actor.
  virtual
  void
  SetInteractor(vtkRenderWindowInteractor* theInteractor);

  //! Apply the transform on the actor.
  virtual
  void
  SetTransform(VTKViewer_Transform* theTransform);

  //! Redefined method of rendering the Opaque Geometry.
  virtual
  int
  RenderOpaqueGeometry(vtkViewport *viewport);

  //! Redefined method of rendering the Translucent Geometry.
  virtual
  int
  RenderTranslucentGeometry(vtkViewport *viewport);

  //----------------------------------------------------------------------------
  //! Set actor visibility.
  virtual
  void
  SetVisibility(int theMode);

  //! Get segmentation visibility.
  virtual
  int
  IsSegmentationEnabled();

  //! Set Scalar Bar Control to the actor.
  VISU_ScalarBarCtrl* 
  GetScalarBarCtrl();

  //! Set the Scalar Bar Control visibility.
  void
  SetBarVisibility(bool theMode);

  //! Get the Scalar Bar Control visibility.
  bool
  GetBarVisibility();

  virtual 
  void
  SetWidgetCtrl(VISU_WidgetCtrl* theWidgetCtrl);

  //! Return the information about pipeline magnification changing.
  /*! True indicates that magnification is increased, false - decreased. */
  bool
  GetChangeMagnification();

  //! Change the pipeline magnification.
  virtual
  void
  ChangeMagnification( bool );

  //----------------------------------------------------------------------------
  //! Internal highlight.
  virtual
  void
  Highlight(bool theIsHighlight);
 
  //! Redefined method of the actor's prehighlighting 
  virtual
  bool
  PreHighlight(vtkInteractorStyle* theInteractorStyle, 
               SVTK_SelectionEvent* theSelectionEvent,
               bool theIsHighlight);

  //! Redefined method of the actor's highlighting 
  virtual
  bool
  Highlight(vtkInteractorStyle* theInteractorStyle, 
            SVTK_SelectionEvent* theSelectionEvent,
            bool theIsHighlight);

  //----------------------------------------------------------------------------
  //! Set the picking settings to the actor.
  void
  SetInsideCursorSettings(VISU_InsideCursorSettings* theInsideCursorSettings);

  virtual void
  UpdateInsideCursorSettings();

  virtual void
  UpdateInsideCursorSettings( PDeviceActor );

  //----------------------------------------------------------------------------
  //! Apply the picking settings on the actor.
  void
  UpdatePickingSettings();

  virtual
  bool
  IsInfinitive();

  virtual
  int
  GetPickable();

  //----------------------------------------------------------------------------
  virtual
  unsigned long int 
  GetMTime();

  //----------------------------------------------------------------------------
  virtual void RemoveAllClippingPlanes();

  virtual vtkIdType GetNumberOfClippingPlanes();

  virtual bool AddClippingPlane(vtkPlane* thePlane);

  virtual vtkPlane* GetClippingPlane(vtkIdType theID);

  virtual vtkImplicitFunctionCollection* GetClippingPlanes();

  //----------------------------------------------------------------------------
  virtual
  vtkDataSet*
  GetValLabelsInput();
 
 protected:
  //----------------------------------------------------------------------------
  VISU_GaussPtsAct();

  virtual 
  ~VISU_GaussPtsAct();

  // Redefined method of setting mapper input.
  virtual 
  void
  SetMapperInput(vtkDataSet* theDataSet);

  virtual
  VISU_PipeLine* 
  GetCurrentPL();

  //! To get current value of the radius of the Point Sprite
  virtual
  vtkFloatingPointType
  GetRadius(vtkIdType theObjID,
            vtkIdType theVTKID,
            vtkDataArray *theScalarArray);

  //! To get current value of the magnification
  virtual
  vtkFloatingPointType
  GetMagnification(vtkIdType theObjID);

  //! To get current value of the clamp
  virtual
  vtkFloatingPointType
  GetClamp(vtkIdType theObjID);

  //----------------------------------------------------------------------------
  vtkSmartPointer<vtkCallbackCommand> myEventCallbackCommand;

  //! Main process VTK event method
  static
  void
  ProcessEvents(vtkObject* theObject, 
                unsigned long theEvent,
                void* theClientData, 
                void* theCallData);

  // To process VTK event method
  virtual
  void
  OnInteractorEvent(unsigned long theEvent);

  vtkFloatingPointType myPriority;
  bool myChangeMagnification;
  VISU::TGaussPtsActorFactory* myGaussPtsActorFactory;
  boost::signal1<void,VISU_GaussPtsAct*> myUpdatePrs3dSignal;

  //----------------------------------------------------------------------------
  PDeviceActor myDeviceActor;

  VISU_WidgetCtrl* myWidgetCtrl;

  VISU_GaussPointsPL* myCurrentPL;
  vtkSmartPointer<VISU_GaussPointsPL> myGaussPointsPL;

  vtkSmartPointer<vtkPolyDataMapper> myMapper;
  vtkSmartPointer<SALOME_ExtractPolyDataGeometry> myPolyDataExtractor;
  vtkSmartPointer<vtkImplicitBoolean> myFunction;

  vtkIdType myLastPreHighlightObjID;

  vtkSmartPointer<VISU_CursorPyramid> myCursorPyramid;
  vtkSmartPointer<VISU_CursorPyramid> myCursorPyramidSelected;
  
  vtkSmartPointer<vtkUnstructuredGrid> myCellSource;
  vtkSmartPointer<SVTK_Actor> myCellActor;

  vtkSmartPointer<vtkWarpVector> myWarpVector;
  vtkSmartPointer<vtkCellDataToPointData> myCellDataToPointData;

  bool myBarVisibility;
  vtkSmartPointer<VISU_ScalarBarCtrl> myScalarBarCtrl;

  VISU_InsideCursorSettings* myInsideCursorSettings;
};


//============================================================================
class VISU_GaussPtsAct2;

//! Gauss Points Actor, displayed in the Base View.
/*!
 * Contains device actor (VISU_GaussPtsDeviceActor),
 * which has two representation modes - outside and
 * inside segmentation cursor.
 */
class VISU_OBJECT_EXPORT VISU_GaussPtsAct1 : public VISU_GaussPtsAct
{
 public:
  vtkTypeMacro(VISU_GaussPtsAct1,VISU_GaussPtsAct);

  static
  VISU_GaussPtsAct1* 
  New();

  virtual
  void
  ShallowCopyPL(VISU_PipeLine* thePipeLine);

  //----------------------------------------------------------------------------
  //! Set actor visibility.
  virtual
  void
  SetVisibility(int theMode);

  virtual 
  void
  Connect(VISU_GaussPtsAct2* theActor);

  //----------------------------------------------------------------------------
  virtual void
  UpdateInsideCursorSettings();

  //----------------------------------------------------------------------------
  //! Set the Outside Cursor Gauss Points settings to the actor.
  void
  SetOutsideCursorSettings(VISU_OutsideCursorSettings* theOutsideCursorSettings);

  //! Apply the Outside Cursor Gauss Points settings on the actor.
  void
  UpdateOutsideCursorSettings();

  //----------------------------------------------------------------------------
  //! Add actor to the renderer.
  virtual
  void
  AddToRender(vtkRenderer* theRenderer); 

  //! Remove actor from the renderer.
  virtual
  void
  RemoveFromRender(vtkRenderer* theRenderer);

  //! Apply the transform on the actor.
  virtual
  void
  SetTransform(VTKViewer_Transform* theTransform);

  virtual 
  void
  SetWidgetCtrl(VISU_WidgetCtrl* theWidgetCtrl);

  //! Redefined method of rendering the Opaque Geometry.
  virtual
  int
  RenderOpaqueGeometry(vtkViewport *viewport);

  //! Redefined method of rendering the Translucent Geometry.
  virtual
  int
  RenderTranslucentGeometry(vtkViewport *viewport);
                      
  virtual
  void 
  SetPosition(double _arg[3]);

  //! Gets memory size used by the instance (bytes).
  virtual
  unsigned long int
  GetMemorySize();
 
 protected:
  //----------------------------------------------------------------------------
  VISU_GaussPtsAct1();

  virtual 
  ~VISU_GaussPtsAct1();

  // Redefined method of setting mapper input.
  virtual 
  void
  SetMapperInput(vtkDataSet* theDataSet);

  //! To get current value of the radius of the Point Sprite
  virtual
  vtkFloatingPointType
  GetRadius(vtkIdType theObjID,
            vtkIdType theVTKID,
            vtkDataArray *theScalarArray);

  //! To get current value of the magnification
  virtual
  vtkFloatingPointType
  GetMagnification(vtkIdType theObjID);

  //! To get current value of the clamp
  virtual
  vtkFloatingPointType
  GetClamp(vtkIdType theObjID);

  //----------------------------------------------------------------------------
  // Main process VTK event method
  static
  void
  ProcessEvents(vtkObject* theObject, 
                unsigned long theEvent,
                void* theClientData, 
                void* theCallData);

  // To process VTK event method
  virtual 
  void
  OnInteractorEvent(unsigned long theEvent);

  boost::signal1<void,int> mySetVisibilitySignal;
  boost::signal1<void,double*> myUpdatePositionSignal;
  VISU_OutsideCursorSettings* myOutsideCursorSettings;

  //----------------------------------------------------------------------------
  PDeviceActor myInsideDeviceActor;
  PDeviceActor myOutsideDeviceActor;
};


//! Gauss Points Actor, displayed in the Segmented View.
class VISU_OBJECT_EXPORT VISU_GaussPtsAct2 : public VISU_GaussPtsAct
{
 public:
  vtkTypeMacro(VISU_GaussPtsAct2,VISU_GaussPtsAct);

  static
  VISU_GaussPtsAct2* 
  New();

  // Redefined method of setting mapper input.
  virtual 
  void
  SetMapperInput(vtkDataSet* theDataSet);

  virtual
  void
  ShallowCopyPL(VISU_PipeLine* thePipeLine);

  //----------------------------------------------------------------------------
  //! Set actor visibility.
  virtual
  void
  SetVisibility(int theMode);

  virtual 
  void
  SetWidgetCtrl(VISU_WidgetCtrl* theWidgetCtrl);

  //! Gets memory size used by the instance (bytes).
  virtual
  unsigned long int
  GetMemorySize();
                      
  virtual
  void 
  SetPosition(double _arg[3]);
  
 protected:
  //----------------------------------------------------------------------------
  VISU_GaussPtsAct2();

  virtual 
  ~VISU_GaussPtsAct2();

  //----------------------------------------------------------------------------
  // To process VTK event method
  virtual 
  void
  OnInteractorEvent(unsigned long theEvent);
};


#endif
