//  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   : 
//  Author : 
//  Module : VISU
//
#ifndef VISU_ACTOR_H
#define VISU_ACTOR_H

#include "VISU_OBJECT.h"

#include "SALOME_Actor.h"
#include "VISU_ActorBase.h"
#include "VISU_BoostSignals.h"
#include "SVTK_DeviceActor.h"

#include <string>
#include <vtkTimeStamp.h>
#include <vtkSmartPointer.h>

class vtkProp;
class vtkProperty;
class vtkTextMapper;
class vtkTextActor;
class vtkInteractorStyle;
class vtkCallbackCommand;
class VTKViewer_ShrinkFilter;
class VISU_PipeLine;
class vtkPlane;
class vtkImplicitFunctionCollection;
class vtkFeatureEdges;
class vtkTextProperty;
class vtkCellCenters;
class vtkLabeledDataMapper;
class vtkMaskPoints;
class vtkActor2D;

class VTKViewer_FramedTextActor;

class VISU_SelectVisiblePoints;

#if !defined(VTK_XVERSION)
#define VTK_XVERSION (VTK_MAJOR_VERSION<<16)+(VTK_MINOR_VERSION<<8)+(VTK_BUILD_VERSION)
#endif

namespace SVTK
{
  namespace Representation
  {
    const Type Surfaceframe = Insideframe + 1;
    const Type FeatureEdges = Insideframe + 2;
  }
}

namespace VISU 
{
  class Prs3d_i;
}

//----------------------------------------------------------------------------
class VISU_OBJECT_EXPORT VISU_Actor : public VISU_ActorBase
{
 public:
  vtkTypeMacro(VISU_Actor, VISU_ActorBase);

  //static 
  //VISU_Actor* 
  //New();

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

  virtual
  void
  ShallowCopyPL(VISU_PipeLine* thePipeLine);

  //----------------------------------------------------------------------------
  virtual
  void
  setIO(const Handle(SALOME_InteractiveObject)& theIO);

  //----------------------------------------------------------------------------
  VISU::Prs3d_i* 
  GetPrs3d();

  virtual
  void
  SetPrs3d(VISU::Prs3d_i* thePrs3d);

  virtual
  void
  SetVisibility(int theMode);

  bool
  ShouldBeDisplayed();

  virtual
  void
  SetPosition( double thePosition[3] );

  virtual
  void
  SetPosition( double theX, double theY, double theZ );

  //----------------------------------------------------------------------------
  virtual
  VISU_PipeLine* 
  GetPipeLine();

  virtual 
  void
  SetPipeLine(VISU_PipeLine* thePipeLine);

  //----------------------------------------------------------------------------
  virtual
  void
  SetRepresentation(int theMode);

  //----------------------------------------------------------------------------
  virtual
  bool
  IsShrunkable();

  virtual
  bool
  IsShrunk();

  virtual
  void
  SetShrink();

  virtual
  void
  UnShrink(); 

  virtual
  void
  SetShrinkable(bool theIsShrinkable);

  virtual
  void
  SetShrinkFactor(vtkFloatingPointType theFactor = 0.8); 

  virtual
  vtkFloatingPointType
  GetShrinkFactor();

  //----------------------------------------------------------------------------
  virtual
  bool
  IsFeatureEdgesAllowed();

  virtual
  void
  SetFeatureEdgesAllowed(bool theIsFeatureEdgesAllowed);

  virtual
  bool
  IsFeatureEdgesEnabled();

  virtual
  void
  SetFeatureEdgesEnabled(bool theIsFeatureEdgesEnabled);

  virtual
  vtkFloatingPointType
  GetFeatureEdgesAngle();

  virtual
  void
  SetFeatureEdgesAngle(vtkFloatingPointType theAngle = 30.0); 

  virtual
  void
  GetFeatureEdgesFlags(bool& theIsFeatureEdges,
                       bool& theIsBoundaryEdges,
                       bool& theIsManifoldEdges,
                       bool& theIsNonManifoldEdges);

  virtual
  void
  SetFeatureEdgesFlags(bool theIsFeatureEdges,
                       bool theIsBoundaryEdges,
                       bool theIsManifoldEdges,
                       bool theIsNonManifoldEdges);

  virtual
  bool
  GetFeatureEdgesColoring();

  virtual
  void
  SetFeatureEdgesColoring(bool theIsColoring);

  //----------------------------------------------------------------------------
  virtual
  void
  SetOpacity(vtkFloatingPointType theValue);

  virtual
  vtkFloatingPointType
  GetOpacity();

  virtual
  void
  SetLineWidth(vtkFloatingPointType theLineWidth);

  virtual
  vtkFloatingPointType
  GetLineWidth();
 
  //----------------------------------------------------------------------------
  virtual
  void
  AddToRender( vtkRenderer* ); 

  virtual
  void
  RemoveFromRender( vtkRenderer* );

  //----------------------------------------------------------------------------
  //! Just to update visibility of the highlight devices
  virtual
  void
  highlight(bool theHighlight);  

  //! To process prehighlight (called from #SVTK_InteractorStyle)
  virtual
  bool
  PreHighlight(vtkInteractorStyle* theInteractorStyle, 
               SVTK_SelectionEvent* theSelectionEvent,
               bool theIsHighlight);

  //! To process highlight (called from #SVTK_InteractorStyle)
  virtual
  bool
  Highlight(vtkInteractorStyle* theInteractorStyle, 
            SVTK_SelectionEvent* theSelectionEvent,
            bool theIsHighlight);

  //! Internal highlight.
  virtual
  void
  Highlight(bool theIsHighlight);

  virtual
  void 
  SetVTKMapping(bool theIsVTKMapping); 

  virtual
  bool 
  IsVTKMapping() const;

  virtual
  vtkDataSet* 
  GetInput(); 

  //! Gets memory size used by the instance (bytes).
  virtual
  unsigned long int
  GetMemorySize();
 
  //----------------------------------------------------------------------------
  virtual
  vtkIdType
  GetNodeObjId(vtkIdType theID);

  virtual
  vtkIdType
  GetNodeVTKID(vtkIdType theID);

  virtual
  vtkFloatingPointType* 
  GetNodeCoord(vtkIdType theObjID);

  virtual
  vtkIdType
  GetElemObjId(vtkIdType theID);

  virtual
  vtkIdType
  GetElemVTKID(vtkIdType theID);

  virtual
  vtkCell* 
  GetElemCell(vtkIdType theObjID);

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

  virtual vtkIdType GetNumberOfClippingPlanes();

  virtual bool AddClippingPlane(vtkPlane* thePlane);

  virtual vtkPlane* GetClippingPlane(vtkIdType theID);

  virtual vtkImplicitFunctionCollection* GetClippingPlanes();

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

  //----------------------------------------------------------------------------
  //! Methods for values labeling
  virtual 
  void 
  SetValuesLabeled( const bool theIsValLabeled );

  virtual 
  bool 
  GetValuesLabeled() const;

  virtual
  vtkDataSet*
  GetValLabelsInput();

  vtkTextProperty* 
  GetsValLabelsProps() const;

  enum EQuadratic2DRepresentation { eLines = 0, eArcs };

  virtual
    EQuadratic2DRepresentation GetQuadratic2DRepresentation() const;
  
  virtual void 
    SetQuadratic2DRepresentation( EQuadratic2DRepresentation theMode );
  
  
 protected:
  VISU_Actor();

  virtual
  ~VISU_Actor();
 
  virtual 
  void
  SetMapperInput(vtkDataSet* theDataSet) = 0;

  virtual
  VISU_PipeLine* 
  GetCurrentPL();

  //----------------------------------------------------------------------------
  bool
  isSubElementsHighlighted();

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

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

  //----------------------------------------------------------------------------
 private:
  void
  ResetTextActor();

  //----------------------------------------------------------------------------
 protected:
  vtkFloatingPointType myPriority;
  bool myIsVTKMapping;
  VISU::Prs3d_i* myPrs3d;
  vtkSmartPointer<VISU_PipeLine> myPipeLine;

  vtkSmartPointer<VTKViewer_ShrinkFilter> myShrinkFilter;
  bool myIsShrinkable;
  bool myIsShrunk;

  vtkSmartPointer<vtkTextMapper> myAnnotationMapper;
#if (VTK_XVERSION < 0x050100)
  vtkSmartPointer<vtkTextActor>  myAnnotationActor;
#else
  vtkSmartPointer<vtkActor2D>  myAnnotationActor;
#endif

  vtkSmartPointer<VTKViewer_FramedTextActor> myTextActor;

  vtkSmartPointer<vtkFeatureEdges> myFeatureEdges;
  bool myIsFeatureEdgesAllowed;
  bool myIsFeatureEdgesEnabled;

  Selection_Mode myLastSelectionMode;
  bool myIsSubElementsHighlighted;
  
  // fields for values labeling
  bool                    myIsValLabeled;
  vtkDataSet*             myValLblDataSet;
  vtkActor2D*             myValLabels;
  vtkMaskPoints*          myValMaskPoints;
  vtkCellCenters*         myValCellCenters;
  vtkLabeledDataMapper*   myValLabeledDataMapper;
  VISU_SelectVisiblePoints* myValSelectVisiblePoints;
};

#endif //VISU_ACTOR_H
