//  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_GaussPointsPL.hxx
// Author:  
// Module : VISU
//
#ifndef VISU_GaussPointsPL_HeaderFile
#define VISU_GaussPointsPL_HeaderFile

#include "VISUPipeline.hxx"
#include "VISU_MergedPL.hxx"
#include "VISU_ColoredPL.hxx"

#include <vector>

class VISU_OpenGLPointSpriteMapper;
class VISU_PointSpriteMapperHolder;

class vtkGeometryFilter;
class vtkGlyph3D;
class vtkSphereSource;
class vtkDataArray;
class vtkImageData;
class vtkPointSet;
class vtkPassThroughFilter;
class vtkDataSet;

class vtkWarpVector;
class SALOME_Transform;

class VISU_AppendFilter;
class VISU_GaussMergeFilter;

//----------------------------------------------------------------------------
//! Pipeline for the Gauss Points presentation.
/*!
 * This class uses the special mapper (VISU_OpenGLPointSpriteMapper)
 * for rendering the Gauss Points as Point Sprites.
 */
class VISU_PIPELINE_EXPORT VISU_GaussPointsPL : public VISU_MergedPL,
                                                public VISU_ColoredPL
{
public:
  //----------------------------------------------------------------------------
  vtkTypeMacro(VISU_GaussPointsPL, VISU_ColoredPL);

  static 
  VISU_GaussPointsPL* 
  New();
  
  virtual
  unsigned long int 
  GetMTime();

  //----------------------------------------------------------------------------
  void 
  SetGaussPtsIDMapper(const VISU::PGaussPtsIDMapper& theGaussPtsIDMapper);

  const VISU::PGaussPtsIDMapper&  
  GetGaussPtsIDMapper();

  VISU_PointSpriteMapperHolder*
  GetPointSpriteMapperHolder();

  //! Get the internal #VISU_OpenGLPointSpriteMapper.
  VISU_OpenGLPointSpriteMapper*
  GetPointSpriteMapper();

  vtkDataSet*  
  GetParentMesh();

  //! Get an intermediate dataset that can be picked  
  vtkPolyData*
  GetPickableDataSet();

  //----------------------------------------------------------------------------
  //! Redefined method for initialization of the pipeline.
  virtual
  void
  Init();

  //! Redefined method for updating the pipeline.
  virtual
  void
  Update();

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

  //----------------------------------------------------------------------------
  //! Update glyph.
  void
  UpdateGlyph();

  virtual 
  VISU::TGaussPointID 
  GetObjID(vtkIdType theID);

  //! Set the Bicolor mode.
  /*!
   * When the Bicolor parameter is set to true, scalar bars are
   * drawing with two colors : red color correspoonds to positive
   * scalar values, blue color - to negative values.
   */
  void
  SetBicolor(bool theBicolor);

  //! Get the Bicolor mode.
  bool
  GetBicolor();

  //! Set the Multicolored mode.
  /*!
   * This parameter is using to switch between Results and Geometry
   * modes. Multiple colors are using when the presentation is
   * drawing in the Results mode, one color - in the Geometry mode.
   */
  void
  SetIsColored(bool theIsColored);

  bool 
  GetIsColored();

  //! Set type of the primitives.
  void
  SetPrimitiveType(int thePrimitiveType);

  //! Get type of the primitives.
  int
  GetPrimitiveType();

  //! Get the maximum Point Sprite size, which is supported by hardware.
  vtkFloatingPointType 
  GetMaximumSupportedSize();

  //! Redirect the request to VISU_OpenGLPointSpriteMapper::SetPointSpriteClamp.
  void
  SetClamp(vtkFloatingPointType theClamp);

  //! Redirect the request to VISU_OpenGLPointSpriteMapper.vtkGetMacro(PointSpriteClamp, vtkFloatingPointType).
  vtkFloatingPointType
  GetClamp();

  //! Redirect the request to VISU_OpenGLPointSpriteMapper::SetPointSpriteSize.
  void
  SetSize(vtkFloatingPointType theSize);

  //! Redirect the request to VISU_OpenGLPointSpriteMapper.vtkGetMacro(PointSpriteSize, vtkFloatingPointType).
  vtkFloatingPointType 
  GetSize();

  //! Redirect the request to VISU_OpenGLPointSpriteMapper::SetPointSpriteMinSize.
  void
  SetMinSize(vtkFloatingPointType theMinSize);

  //! Redirect the request to VISU_OpenGLPointSpriteMapper.vtkGetMacro(PointSpriteMinSize, vtkFloatingPointType).
  vtkFloatingPointType 
  GetMinSize();

  //! Redirect the request to VISU_OpenGLPointSpriteMapper::SetPointSpriteMinSize.
  void
  SetMaxSize(vtkFloatingPointType theMaxSize);

  //! Redirect the request to VISU_OpenGLPointSpriteMapper.vtkGetMacro(PointSpriteMaxSize, vtkFloatingPointType).
  vtkFloatingPointType 
  GetMaxSize();

  //! Redirect the request to VISU_OpenGLPointSpriteMapper::SetPointSpriteMagnification.
  void
  SetMagnification(vtkFloatingPointType theMagnification);

  //! Redirect the request to VISU_OpenGLPointSpriteMapper.vtkGetMacro(PointSpriteMagnification, vtkFloatingPointType).
  vtkFloatingPointType
  GetMagnification();

  //! Set the increment of changing Magnification parameter.
  void
  SetMagnificationIncrement(vtkFloatingPointType theIncrement);

  //! Get the increment of changing Magnification parameter.
  vtkFloatingPointType
  GetMagnificationIncrement() { return myMagnificationIncrement; }

  //! Redirect the request to VISU_OpenGLPointSpriteMapper::SetPointSpriteAlphaThreshold.
  void
  SetAlphaThreshold(vtkFloatingPointType theAlphaThreshold);

  //! Redirect the request to VISU_OpenGLPointSpriteMapper.vtkGetMacro(PointSpriteAlphaThreshold, vtkFloatingPointType).
  vtkFloatingPointType
  GetAlphaThreshold();

  //! Redirect the request to VISU_OpenGLPointSpriteMapper::SetPointSpriteOpacity.
  void
  SetOpacity(vtkFloatingPointType theOpacity);

  //! Redirect the request to VISU_OpenGLPointSpriteMapper.vtkGetMacro(PointSpriteOpacity, vtkFloatingPointType).
  vtkFloatingPointType
  GetOpacity();

  //! Set resolution of the Geometrical Sphere.
  void
  SetResolution(int theResolution);

  //! Get resolution of the Geometrical Sphere.
  int
  GetResolution();

  //! Method for changing the Magnification parameter.
  void
  ChangeMagnification( bool up );

  //! Get the maximum size of Point Sprites in the presentation.
  vtkFloatingPointType
  GetMaxPointSize();

  //! Get point size by element's Id.
  vtkFloatingPointType
  GetPointSize(vtkIdType theID);

  //! Get point size by element's Id using the specified scalar array.
  vtkFloatingPointType
  GetPointSize(vtkIdType theID, vtkDataArray* theScalarArray);

  //! Redirect the request to VISU_OpenGLPointSpriteMapper.vtkSetMacro(AverageCellSize, vtkFloatingPointType).
  void
  SetAverageCellSize(vtkFloatingPointType AverageCellSize);

  //! Redirect the request to VISU_OpenGLPointSpriteMapper.vtkGetMacro(AverageCellSize, vtkFloatingPointType).
  vtkFloatingPointType
  GetAverageCellSize();

  //! Set image data for the Point Sprite texture.
  void
  SetImageData(vtkImageData* theImageData);

  //! Make the image data for Point Sprite texture.
  /*!
   * First parameter - texture for shape.
   * Second parameter - texture for alpha mask.
   */
  static
  vtkSmartPointer<vtkImageData>
  MakeTexture( const char* theMainTexture,
               const char* theAlphaTexture );

public:
  //----------------------------------------------------------------------------
  virtual 
  void
  SetIsDeformed( bool theIsDeformed );

  virtual
  bool
  GetIsDeformed();

  virtual
  void
  SetScale( vtkFloatingPointType theScale );

  virtual
  vtkFloatingPointType 
  GetScale();

  virtual
  void
  SetMapScale( vtkFloatingPointType theMapScale = 1.0 );

public:

  virtual  
  void  
  SetSourceGeometry();

  virtual
  int
  AddGeometry(vtkDataSet* theGeometry, const VISU::TName& theGeomName);

  virtual
  vtkDataSet*
  GetGeometry(int theGeomNumber, VISU::TName& theGeomName);

  virtual
  int
  GetNumberOfGeometry();

  virtual
  bool 
  IsExternalGeometryUsed();

  virtual
  void
  ClearGeometry();

  virtual
  void
  GetSourceRange(vtkFloatingPointType theRange[2]);

  virtual 
  vtkPointSet* 
  GetMergedInput();

protected:
  //----------------------------------------------------------------------------
  VISU_GaussPointsPL();

  virtual
  ~VISU_GaussPointsPL();

  virtual
  void
  OnCreateMapperHolder();

  virtual
  void
  Build();

  virtual
  vtkDataSet* 
  InsertCustomPL();

  virtual
  void
  DoShallowCopy(VISU_PipeLine *thePipeLine,
                bool theIsCopyInput);

private:
  //----------------------------------------------------------------------------
  vtkFloatingPointType myScaleFactor;
  vtkWarpVector *myWarpVector;
  std::vector<vtkPassThroughFilter*> myPassFilter;
  vtkSmartPointer<VISU_PointSpriteMapperHolder> myPointSpriteMapperHolder;
  
  vtkGlyph3D* myGlyph;
  vtkSphereSource* mySphereSource;

  vtkFloatingPointType myMagnificationIncrement;

  int myPrimitiveType;

  vtkSmartPointer<VISU_AppendFilter>      myAppendFilter;
  vtkSmartPointer<VISU_GaussMergeFilter>  myMergeFilter;

private:
  VISU_GaussPointsPL(const VISU_GaussPointsPL&);  // Not implemented.
  void operator=(const VISU_GaussPointsPL&);  // Not implemented.
};
  
#endif
