//  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 VISUGUI : GUI of VISU component
//  File   : VisuGUI_Tools.h
//  Author : Sergey Anikin
//  Module : VISU
//
#ifndef VisuGUI_Tools_HeaderFile
#define VisuGUI_Tools_HeaderFile

#include "SALOME_InteractiveObject.hxx"

#include "VISUConfig.hh"
#include "VISU_ColoredPrs3d_i.hh"

#include "SALOMEDSClient_Study.hxx"

#include "SALOMEconfig.h"
#include CORBA_SERVER_HEADER(MED_Gen)

class QWidget;
class QDialog;
class QSpinBox;
class QDoubleSpinBox;

class SUIT_Desktop;
class SUIT_ViewWindow;
class VISU_Actor;
class SVTK_ViewWindow;
class SPlot2d_Viewer;
class SPlot2d_Curve;
class Plot2d_ViewFrame;
class CAM_Module;
class LightApp_SelectionMgr;
class SalomeApp_DoubleSpinBox;
class SalomeApp_IntSpinBox;
class SalomeApp_Module;
class SalomeApp_Study;
class VisuGUI;

#include <vector>
#include <utility>
#include "VISU_Mesh_i.hh"

namespace VISU 
{
  class Base_i;
  class Prs3d_i;
  class Result_i;
  class Table_i;
  class Curve_i;
  class Container_i;

  typedef std::vector<SVTK_ViewWindow*> TViewWindows;

  //----------------------------------------------------------------------------
  SUIT_Desktop*                        GetDesktop(const CAM_Module* theModule);
  SalomeApp_Study*                     GetAppStudy(const CAM_Module* theModule);
  _PTR(Study)                          GetCStudy(const SalomeApp_Study* theStudy);

  bool                                 IsStudyLocked( _PTR(Study) theStudy );
  bool                                 CheckLock( _PTR(Study) theStudy,
                                                  QWidget* theWidget );

  //----------------------------------------------------------------------------
  int                                  runAndWait( QDialog* dlg, const bool modal );

  void                                 UpdateObjBrowser(SalomeApp_Module* theModule,
                                                        bool theIsUpdateDataModel = true,
                                                        _PTR(SObject) theSObject = _PTR(SObject)());

  //----------------------------------------------------------------------------
  VISU_Gen_i*                          GetVisuGen(const CAM_Module* theModule);
  SALOME_MED::MED_Gen_var              GetMEDEngine();

  // Selection
  LightApp_SelectionMgr*               GetSelectionMgr(const SalomeApp_Module* theModule);

  //----------------------------------------------------------------------------
  struct TObjectInfo
  {
    Base_i* myBase;
    _PTR(SObject) mySObject;
    TObjectInfo():
      myBase(NULL)
    {}
  };

  struct TSelectionItem
  {
    TObjectInfo myObjectInfo;
    Handle(SALOME_InteractiveObject) myIO;
  };

  typedef std::vector<TSelectionItem>  TSelectionInfo;

  TSelectionInfo                       GetSelectedObjects(const SalomeApp_Module* theModule);

  TObjectInfo                          GetObjectByEntry(const SalomeApp_Study* theStudy,
                                                        const std::string& theEntry);
  
  VISU::Prs3d_i*                       GetPrs3dToModify(const SalomeApp_Module* theModule,
                                                        Base_i* theBase);

  VISU::Prs3d_i*                       GetPrs3dFromBase(Base_i* theBase);

  bool                                 GetPrs3dSelectionInfo( const SalomeApp_Module* theModule,
                                                              VISU::Prs3d_i*& thePrs3d,
                                                              SVTK_ViewWindow*& theViewWindow,
                                                              VISU_Actor*& thenActor );

  //----------------------------------------------------------------------------
  void                                 Add(LightApp_SelectionMgr* theSelectionMgr,
                                           const Handle(SALOME_InteractiveObject)& theIO);
  void                                 Remove(LightApp_SelectionMgr* theSelectionMgr,
                                              const Handle(SALOME_InteractiveObject)& theIO);

  bool                                 IsRemovable        (const std::string theEntry,
                                                           const SalomeApp_Module* theModule);
  bool                                 IsRemovableSelected(const SalomeApp_Module* theModule);

  void                                 DeleteSObject(VisuGUI* theModule,
                                                     _PTR(Study)       theStudy,
                                                     _PTR(SObject)     theSObject);
  void                                 DeletePrs3d(VisuGUI* theModule,
                                                   VISU::Prs3d_i* thePrs);

  // Presentation management
  void ChangeRepresentation (const SalomeApp_Module* theModule,
                             VISU::PresentationType  theType);


  void ChangeQuadratic2DRepresentation (const SalomeApp_Module* theModule,
                                        VISU::Quadratic2DPresentationType  theType);
  


  void SetShading ( const SalomeApp_Module* theModule, bool theOn = true );

  // SObject type
  bool                                 CheckTimeStamp(const SalomeApp_Module* theModule,
                                                      _PTR(SObject)&          theSObject,
                                                      Handle(SALOME_InteractiveObject)& theIO,
                                                      ColoredPrs3d_i::EPublishInStudyMode& thePublishInStudyMode);
  VISU::Result_i*                      CheckResult(const SalomeApp_Module* theModule,
                                                   _PTR(SObject) theSource,
                                                   VISU::Result_var& theResult);
  bool                                 IsSObjectTable(_PTR(SObject) theSObject);

  /*! Display mesh presentation in given VTK view window
   */
  VISU_Actor*                          PublishMeshInView(const SalomeApp_Module* theModule,
                                                         VISU::Prs3d_i* thePrs,
                                                         SVTK_ViewWindow* theViewWindow);

  /*!
   * \brief Repaint all SVTK view windows, where the given object is displayed.
   * \param theModule  - is used to access application.
   * \param theIObject - is supposed to be selected (is highlighted in this method).
   */
  void                                 RepaintViewWindows(const SalomeApp_Module* theModule,
                                                          const Handle(SALOME_InteractiveObject)& theIObject);

  VISU_Actor*                          FindActor(const SalomeApp_Study* theStudy,
                                                 SVTK_ViewWindow* theViewWindow,
                                                 const QString& theEntry);
  VISU_ActorBase*                      FindActorBase(const SalomeApp_Study* theStudy,
                                                     SVTK_ViewWindow* theViewWindow,
                                                     const QString& theEntry);
  void                                 RecreateActor(const SalomeApp_Module* theModule,
                                                     VISU::Prs3d_i* thePrs);

  bool                                 ComputeVisiblePropBounds(SVTK_ViewWindow* theViewWindow,
                                                                vtkFloatingPointType allBounds[6], 
                                                                const char* theActorClassName = "VISU_Actor");

  /*!
   * \brief Advanced FitAll, sets view projection in accordance with current view contents
   *
   * If common bounding box of all actors in \a theViewWindow has
   * at least one small side, then corresponding projection will be set
   * (Top, Left or Front), else 3D projection will be used.
   *
   * \param theViewWindow - the view to perform FitAll in.
   */
  void                                 SetFitAll(SVTK_ViewWindow* theViewWindow);

  // Plot2d View
  SPlot2d_Viewer*                      GetPlot2dViewer(const SalomeApp_Module* theModule,
                                                       const bool theCreate = false);
  void                                 PlotTable( const SalomeApp_Module* theModule,
                                                  VISU::Table_i* table,
                                                  int theDisplaying );
  void                                 PlotCurve( const SalomeApp_Module* theModule,
                                                  VISU::Curve_i* curve,
                                                  int theDisplaying );
  void                                 PlotRemoveCurve(const SalomeApp_Module* theModule,
                                                       VISU::Curve_i* curve);
  void                                 PlotContainer( const SalomeApp_Module* theModule,
                                                      VISU::Container_i* container,
                                                      int theDisplaying );
  void                                 CreatePlot( SalomeApp_Module* theModule,
                                                   _PTR(SObject) theSobj );

  /*! Create mesh presentation and display it in \a theViewWindow.
   *  If \a theViewWindow is NULL, no displaying will be done.
   */
  VISU::Mesh_i* CreateMesh(VisuGUI* theModule,
                           const Handle(SALOME_InteractiveObject)& theIO,
                           SVTK_ViewWindow* theViewWindow);
  
  // Others
  std::vector<VISU::Prs3d_i*> GetPrs3dList (const SalomeApp_Module* theModule,
                                            const Handle(SALOME_InteractiveObject)& theIO,
                                            bool theGP = false);
  std::vector<VISU::Prs3d_i*> GetPrs3dList (const SalomeApp_Module* theModule,
                                            _PTR(SObject) theObject,
                                            bool theGP = false);
  
  int GetFreePositionOfDefaultScalarBar(VisuGUI* theModule, SVTK_ViewWindow* theViewWindow);
  void AddScalarBarPosition(VisuGUI* theModule, SVTK_ViewWindow* theViewWindow,
                            VISU::Prs3d_i* thePrs3d, int pos);
  void RemoveScalarBarPosition(VisuGUI* theModule, SVTK_ViewWindow* theViewWindow,
                               VISU::Prs3d_i* thePrs3d);

#define CLIP_PLANES_FOLDER "Clipping Planes"

  bool getClippingPlanesFolder(_PTR(Study) theStudy, _PTR(SObject)& theSObject);

  void initSpinBox( SalomeApp_IntSpinBox*, const int, const int, const int );
  void initSpinBox( SalomeApp_DoubleSpinBox*, const double&, const double&, const double&, const char* );
}

#endif
