//  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_ColoredPrs3d_i.hh
//  Author : Alexey PETROV
//  Module : VISU
//
#ifndef VISU_ColoredPrs3d_i_HeaderFile
#define VISU_ColoredPrs3d_i_HeaderFile

#include "VISU_Prs3d_i.hh"
#include "VISU_Result_i.hh"
#include "VISU_BoostSignals.h"
#include "SALOME_GenericObjPointer.hh"

#include <set>

class VISU_ColoredPL;

namespace VISU
{
  class ColoredPrs3d_i;

  //----------------------------------------------------------------------------
  struct TMinMaxController
  {
    virtual
    void
    UpdateReference(ColoredPrs3d_i* theFromPrs3, ColoredPrs3d_i* theToPrs3d);

    virtual
    vtkFloatingPointType
    GetComponentMin(vtkIdType theCompID);

    virtual
    vtkFloatingPointType
    GetComponentMax(vtkIdType theCompID);

    virtual
    void
    Register() = 0;

    virtual
    void
    Destroy() = 0;
  };
  typedef SALOME::GenericObjPtr<TMinMaxController> PMinMaxController;


  //----------------------------------------------------------------------------
  struct TVTKMinMaxController: virtual TMinMaxController,
			       virtual vtkObjectBase
  {
    virtual
    void
    Register()
    {
      vtkObjectBase::Register(NULL);
    }

    virtual
    void
    Destroy()
    {
      vtkObjectBase::Delete();
    }
  };


  //----------------------------------------------------------------------------
  PMinMaxController
  CreateDefaultMinMaxController(VISU::ColoredPrs3d_i* theColoredPrs3d);
  

  //----------------------------------------------------------------------------
  class VISU_I_EXPORT ColoredPrs3d_i : public virtual POA_VISU::ColoredPrs3d,
				       public virtual TMinMaxController,
				       public virtual TResultObserver,
				       public virtual Prs3d_i
  {
    ColoredPrs3d_i(const ColoredPrs3d_i&);

  public:
    //----------------------------------------------------------------------------
    typedef Prs3d_i TSuperClass;
    typedef VISU::ColoredPrs3d TInterface;

    /*! 
      The enumeration allow to define what mode should be used for the presentation building.
    */
    VISU_I_EXPORT enum EPublishInStudyMode {EPublishUnderTimeStamp, EPublishIndependently, ERegisterInCache, EDoNotPublish};

    explicit
    ColoredPrs3d_i(EPublishInStudyMode thePublishInStudyMode);

    virtual
    ~ColoredPrs3d_i();

    virtual
    void
    Register();

    virtual
    void
    Destroy();

    virtual
    void
    RemoveFromStudy();

    //----------------------------------------------------------------------------
    //! To update the presentation from result in automatic way
    virtual
    void
    UpdateFromResult(Result_i* theResult);

    //----------------------------------------------------------------------------
    virtual
    void
    SetEntity(Entity theEntity);

    virtual
    Entity
    GetEntity();

    TEntity
    GetTEntity() const;

    virtual
    void
    SetFieldName(const char* theFieldName);

    virtual
    char*
    GetFieldName();

    std::string
    GetCFieldName() const;

    virtual 
    VISU::PField
    GetField();

    virtual
    void 
    SetTimeStampNumber(CORBA::Long theTimeStampNumber);

    virtual
    CORBA::Long
    GetTimeStampNumber();

    virtual
    CORBA::Long
    GetTimeStampNumberByIndex( CORBA::Long theIndex );

    virtual
    CORBA::Long
    GetTimeStampIndexByNumber( CORBA::Long theNumber );

    virtual 
    VISU::PField
    GetScalarField();

    VISU::PMinMaxController
    GetMinMaxController();

    void
    SetMinMaxController( const VISU::PMinMaxController& theController );

    void
    SetMinMaxController( ColoredPrs3d_i* theOrigin );

    virtual
    CORBA::Long
    GetScalarTimeStampNumber() const;

    virtual
    VISU::ColoredPrs3dHolder::TimeStampsRange*
    GetTimeStampsRange();

    virtual 
    CORBA::Boolean 
    IsTimeStampFixed();

    virtual
    EPublishInStudyMode
    GetPublishInStudyMode();

    //----------------------------------------------------------------------------
    virtual
    CORBA::Long
    GetScalarMode();

    virtual
    void 
    SetScalarMode(CORBA::Long theScalarMode);

    virtual
    CORBA::Double 
    GetMin();

    virtual
    CORBA::Double 
    GetMax();

    virtual
    void
    SetRange(CORBA::Double theMin, CORBA::Double theMax);

    virtual
    vtkFloatingPointType
    GetComponentMin(vtkIdType theCompID) = 0;

    virtual
    vtkFloatingPointType
    GetComponentMax(vtkIdType theCompID) = 0;

    virtual
    CORBA::Double 
    GetSourceMin();

    virtual
    CORBA::Double 
    GetSourceMax();

    virtual 
    void
    SetSourceRange();

    virtual
    CORBA::Boolean
    IsRangeFixed();

    virtual 
    void 
    SetNbColors(CORBA::Long theNbColors);

    virtual
    CORBA::Long 
    GetNbColors();

    virtual
    void
    SetBarOrientation(VISU::ColoredPrs3dBase::Orientation theOrientation);

    virtual 
    VISU::ColoredPrs3dBase::Orientation 
    GetBarOrientation();

    virtual
    void
    SetPosition(CORBA::Double X, CORBA::Double Y);

    virtual
    CORBA::Double
    GetPosX();

    virtual
    CORBA::Double
    GetPosY();

    virtual 
    void
    SetSize(CORBA::Double theWidth, CORBA::Double theHeight);
    
    virtual 
    void
    SetRatios(CORBA::Long theTitleSize, CORBA::Long theLabelSize, 
	      CORBA::Long theBarWidth, CORBA::Long theBarHeight);
    
    virtual 
    CORBA::Double
    GetWidth();

    virtual
    CORBA::Double
    GetHeight();

    virtual 
    CORBA::Long
    GetTitleSize();

    virtual 
    CORBA::Long
    GetLabelSize();

    virtual 
    CORBA::Long
    GetBarWidth();

    virtual
    CORBA::Long
    GetBarHeight();

    virtual 
    void
    SetLabels(CORBA::Long theNbLabels);

    virtual
    CORBA::Long
    GetLabels();

    virtual
    void
    SetLabelsFormat(const char* theFormat);

    virtual
    char* 
    GetLabelsFormat();

    virtual
    void
    SetTitle(const char* theTitle);

    virtual
    char* 
    GetTitle();

    std::string 
    GetCTitle();

    virtual
    void
    SetUnitsVisible(CORBA::Boolean isVisible);

    virtual
    CORBA::Boolean
    IsUnitsVisible();

    /*!  
     * Set the visibility of a distribution curve.
     * \param theIs is used to switch on/off the visibility of a distribution curve.
     */
    virtual void SetIsDistributionVisible(CORBA::Boolean theIs);
    
    //! Gets current visibility of a distribution curve
    virtual CORBA::Boolean GetIsDistributionVisible();
    
    //! Gets current filtering by scalars mode
    virtual CORBA::Boolean IsScalarFilterUsed();
    
    virtual void UseScalarFiltering( CORBA::Boolean theUseScalarFilter );

    /*!
     * Sets scalar range - min and max boundaries of the scalar bar.
     * \param theMin  Min boundary of the scalar bar.
     * \param theMax  Max boundary of the scalar bar.
     * \param theIsFilter  if true then filter by scalars.
     */
    virtual
    void
    SetScalarFilterRange( CORBA::Double theMin, CORBA::Double theMax );

    //----------------------------------------------------------------------------
    virtual
    CORBA::Double
    GetScalarFilterMin();

    //----------------------------------------------------------------------------
    virtual
    CORBA::Double
    GetScalarFilterMax();

    //----------------------------------------------------------------------------
    //! Gets memory size actually used by the presentation (Mb).
    virtual
    CORBA::Float
    GetMemorySize();

    //----------------------------------------------------------------------------
    //! Returns presentation input
    VISU::ColoredPrs3dHolder::BasicInput*
    GetBasicInput();

    virtual
    void
    SetHolderEntry(const std::string& theEntry);

    virtual
    std::string
    GetHolderEntry();

    //! To keep restoring params till the explicit Restore() call
    void
    SaveRestoringState(SALOMEDS::SObject_ptr theSObject,
		       const Storable::TRestoringMap& theMap);

    //! To restore the presentation according to the saved state
    void 
    InitFromRestoringState();

    //----------------------------------------------------------------------------
    virtual 
    const char* 
    GetIconName() = 0;


    //----------------------------------------------------------------------------
    //! Sets initial source geometry
    virtual
    void
    SetSourceGeometry()=0;

    //! Add geometry of mesh as group. \retval the id of added group.
    virtual 
    void
    AddMeshOnGroup(const char* theGroupName)=0;
    
    //! Removes all geometries.
    virtual
    void
    RemoveAllGeom()=0;
    
    typedef std::string TGroupName;
    typedef std::set<TGroupName> TGroupNames;
    
    const TGroupNames&
    GetGroupNames();

    //! Gets number of geometries
    bool 
    IsGroupsUsed();

    //----------------------------------------------------------------------------
  public:
    /*!
      Initlizes the in first time presentation
    */
    virtual
    Storable* 
    Create(const std::string& theMeshName, 
	   VISU::Entity theEntity,
	   const std::string& theFieldName, 
	   CORBA::Long theTimeStampNumber);

    /*!
      Retores state of the presentation
    */
    virtual 
    Storable* 
    Restore(SALOMEDS::SObject_ptr theSObject,
	    const Storable::TRestoringMap& theMap);

    /*!
      Writes persistent params of the presentation into the given stream
    */
    virtual 
    void
    ToStream(std::ostringstream& theStr);

    /*!
      Update state of the presentation according to the input.
    */
    virtual 
    void
    SameAs(const Prs3d_i* theOrigin);

    virtual
    void
    UpdateActor(VISU_ActorBase* theActor);

    virtual 
    bool
    IsBoldTitle();

    virtual
    void
    SetBoldTitle(bool isBold);

    virtual
    bool
    IsItalicTitle();

    virtual
    void
    SetItalicTitle(bool isItalic);

    virtual 
    bool
    IsShadowTitle();

    virtual
    void
    SetShadowTitle(bool isShadow);

    virtual 
    int
    GetTitFontType();

    virtual
    void
    SetTitFontType(int theType);

    virtual 
    void
    GetTitleColor(vtkFloatingPointType& theR, 
		  vtkFloatingPointType& theG, 
		  vtkFloatingPointType& theB);
    
    virtual
    void
    SetTitleColor(vtkFloatingPointType theR, 
		  vtkFloatingPointType theG, 
		  vtkFloatingPointType theB);    

    virtual
    bool
    IsBoldLabel();

    virtual
    void
    SetBoldLabel(bool isBold);

    virtual
    bool
    IsItalicLabel();

    virtual
    void
    SetItalicLabel(bool isItalic);

    virtual
    bool
    IsShadowLabel();

    virtual
    void
    SetShadowLabel(bool isShadow);

    virtual 
    int
    GetLblFontType();

    virtual
    void
    SetLblFontType(int theType);

    virtual 
    void
    GetLabelColor(vtkFloatingPointType& theR, 
		  vtkFloatingPointType& theG, 
		  vtkFloatingPointType& theB);

    virtual
    void
    SetLabelColor(vtkFloatingPointType theR, 
		  vtkFloatingPointType theG, 
		  vtkFloatingPointType theB);

    virtual
    void
    SetMapScale(double theMapScale = 1.0);

    VISU_ColoredPL* 
    GetSpecificPL() const
    { 
      return myColoredPL; 
    }
    
        virtual 
    int
    GetValLblFontType() const;

    virtual 
    void
    SetValLblFontType( const int theType );

    virtual 
    double
    GetValLblFontSize() const;

    virtual 
    void
    SetValLblFontSize( const double theSize );

    virtual 
    bool
    IsBoldValLbl() const;

    virtual
    void
    SetBoldValLbl( const bool theVal );

    virtual 
    bool
    IsItalicValLbl() const;

    virtual
    void
    SetItalicValLbl( const bool theVal );

    virtual 
    bool
    IsShadowValLbl() const;

    virtual
    void
    SetShadowValLbl( const bool theVal );

    virtual 
    void
    GetValLblFontColor( vtkFloatingPointType& theR, 
		       vtkFloatingPointType& theG, 
		       vtkFloatingPointType& theB ) const;

    virtual
    void
    SetValLblFontColor( const vtkFloatingPointType theR, 
		        const vtkFloatingPointType theG, 
		        const vtkFloatingPointType theB );
    
    //----------------------------------------------------------------------------
  protected:
    /*!
      Applyes basic input parameters to the presentation.
      Returns true if all are right.
    */
    virtual 
    bool 
    SetInput(bool theReInit);

    //! Restore input parameters if Apply function fails (redefines Prs3d::OnRestoreInput)
    virtual 
    void 
    OnRestoreInput();

    /*!
      Checks whether it is possible to create presentation 
      with the given basic parameters or not.
    */
    virtual 
    bool 
    CheckIsPossible() = 0;

    /*!
      Creates proper instance of VTK pipeline.
    */
    virtual
    void 
    CreatePipeLine(VISU_PipeLine* thePipeLine);

    /*!
      First checks whether corresponding VTK pipeline exists and create it if not. 
      Then calls VISU_ColoredPrs3d_i::DoSetInput.
      Returns true if during the call corresponding VTK pipeline was created,
      false otherwise.
    */
    virtual 
    bool
    OnSetInput(bool theReInit);

   /*!
      Sets input data set according to basic input parameters -
      Result, MeshName, Entity, FieldName and TimeStampNumber.
    */
    virtual 
    void
    DoSetInput(bool theIsInitilizePipe, bool theReInit) = 0;

    /*! 
      The enumeration allow to define what mode should be used for the presentation building.
    */
    enum EBuildMode {ECreateNew, ESameAs, ERestore};

    /*! 
      The enumeration allow to define what mode should be used for the presentation building.
    */
    Storable* 
    Build(EBuildMode theBuildMode);

    virtual
    void
    SetField(VISU::PField theField);

    void
    UseFixedRange(bool theUseFixedRange);

    std::string 
    GetScalarBarTitle();

    //! Used in derived classes to initilize the IO for actors
    virtual
    std::string
    GetActorEntry();

    TGroupNames myGroupNames;
    
  private:
    bool myIsRestored;
    Storable::TRestoringMap myRestoringMap;
    SALOMEDS::SObject_var myRestoringSObject;

    // Decalare basic input parameters
    VISU::Entity myEntity;
    VISU::Entity myPreviousEntity;

    std::string myFieldName;
    std::string myPreviousFieldName;

    CORBA::Long myTimeStampNumber;
    CORBA::Long myPreviousTimeStampNumber;

    boost::signalslib::connection myResultConnection;

    bool myIsTimeStampFixed;

    PField myField;
    PMinMaxController myMinMaxController;
    EPublishInStudyMode myPublishInStudyMode;

    std::string myHolderEntry;

    std::string myTitle;
    std::string myScalarBarTitle;
    bool        myIsUnits;

    int myNumberOfLabels;
    std::string myLabelsFormat;

    VISU::ColoredPrs3dBase::Orientation myOrientation;
    vtkFloatingPointType myPosition[2],
                         myWidth, myHeight,
                         myTitleSize, myLabelSize,
                         myBarWidth, myBarHeight;

    //Font management
    bool myIsBoldTitle;
    bool myIsItalicTitle;
    bool myIsShadowTitle;
    int  myTitFontType;
    vtkFloatingPointType myTitleColor[3];

    bool myIsBoldLabel;
    bool myIsItalicLabel;
    bool myIsShadowLabel;
    int  myLblFontType;
    vtkFloatingPointType myLabelColor[3];

    VISU_ColoredPL* myColoredPL;
    bool myIsFixedRange;

    bool myIsDistributionVisible; // RKV

    // Result labels 
    int                  myValLblFontType;
    double               myValLblFontSize;
    bool                 myIsBoldValLbl;
    bool                 myIsItalicValLbl;
    bool                 myIsShadowValLbl;
    vtkFloatingPointType myValLblFontColor[ 3 ];
  };


  //----------------------------------------------------------------------------
  template<class TColoredPrs3d>
  Storable* 
  StorableEngine(SALOMEDS::SObject_ptr theSObject,
		 const Storable::TRestoringMap& theMap,
		 const std::string& thePrefix,
		 CORBA::Boolean theIsMultiFile)
  {
    TColoredPrs3d* aColoredPrs3d = new TColoredPrs3d(ColoredPrs3d_i::EDoNotPublish);
    return aColoredPrs3d->Restore(theSObject, theMap);
  }


  //----------------------------------------------------------------------------
}

#endif
