//  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 CONVERTOR :
//  File   : VISU_Convertor.hxx
//  Author : Alexey PETROV
//  Module : VISU
//
#ifndef VISU_IDMapper_HeaderFile
#define VISU_IDMapper_HeaderFile

/*! 
  \file VISU_IDMapper.hxx
  \brief The file contains declarations for basic interfaces that defines mapping of mesh elements
*/

#include "VISUConvertor.hxx"

#include "MED_SharedPtr.hxx"
#include "MED_Vector.hxx"
#include "VTKViewer.h"

#include <string>
#include <map>

class vtkUnstructuredGrid;
class vtkPolyData;
class vtkDataSet;
class vtkCell;

namespace VISU
{
  using MED::SharedPtr;
  using MED::TVector;


  //---------------------------------------------------------------
  class VISU_CONVERTOR_EXPORT TStructuredId
  {
    vtkIdType myData[3];

  public:
    TStructuredId();

    vtkIdType&
    operator [] ( size_t theId );

    const vtkIdType&
    operator [] ( size_t theId ) const;

    bool
    operator == ( const TStructuredId& theId ) const;
  };

  typedef std::map<vtkIdType, TStructuredId> TObj2StructuredId;
  typedef MED::SharedPtr<TObj2StructuredId> PObj2StructuredId;
  
  struct TStructured;
  typedef MED::SharedPtr<TStructured> PStructured;
  
  struct VISU_CONVERTOR_EXPORT TStructured
  {
    TStructured():
      myIsStructured(false),
      myIsPolarType(true)
    {}

    //! Copys all information which should be sinchronized between two instances
    virtual
    void
    CopyStructure(PStructured theStructured);

    bool
    IsStructured() const;

    /*!
     * Get structure of grille
     * see also MED::TGrilleInfo::GetGrilleStructure
     * see also MED::TGrilleInfo::GetNbIndexes
     */
    TStructuredId
    GetStructure();
    
    vtkIdType
    GetStructureDim();
    
    /*!
     * Gets i,j,k by object id
     * return -1, if not found
     */
    TStructuredId
    GetIndexesOfNode(vtkIdType theNodeId);

    /*!
     * Gets object id by i,j,k
     * return -1, if not found
     */
    vtkIdType
    GetObjectIDByIndexes(TStructuredId theVec);

    bool myIsStructured; //!< To define mesh type (structured - true, non structured - false)
    bool myIsPolarType; //!< To define structured mesh is polair

    /*!provides grille structure for structured grid.
     * Example: {3,4,5}, 3 nodes in X axe, 4 nodes in Y axe, ...
     */
    TStructuredId myGrilleStructure;
    
    TObj2StructuredId myObj2StructuredId;//!< map of object id to i,j,k ids of structured grid nodes    
  };
  
  //---------------------------------------------------------------
  //! Defines a basic class for intemediate data structures
  struct VISU_CONVERTOR_EXPORT TBaseStructure: virtual TStructured
  {
    //! Just to provide possibility of dynamic navigation through the class hierarchy
    virtual ~TBaseStructure()
    {}

    std::string myEntry; //!< To simplify publication of the object tree
  };
  typedef MED::SharedPtr<TBaseStructure> PBaseStructure;

  //---------------------------------------------------------------
  //! Defines a basic abstract interface for VTK to object ID's and backward mapping
  /*!
    Where object ID means ID which attached to corresponding MED entity.
    For example, each MED node can have its own ID as well as any other mesh cell
  */
  struct VISU_CONVERTOR_EXPORT TIDMapper: virtual TBaseStructure
  {
    //! Get node object ID for corresponding VTK ID
    virtual 
    vtkIdType 
    GetNodeObjID(vtkIdType theID) const;

    //! Get node VTK ID for corresponding object ID
    virtual 
    vtkIdType 
    GetNodeVTKID(vtkIdType theID) const;

    //! Get coordinates of node for corresponding object ID
    virtual
    vtkFloatingPointType* 
    GetNodeCoord(vtkIdType theObjID);

    //! Get cell object ID for corresponding VTK ID
    virtual 
    vtkIdType 
    GetElemObjID(vtkIdType theID) const;

    //! Get cell VTK ID for corresponding object ID
    virtual 
    vtkIdType 
    GetElemVTKID(vtkIdType theID) const;

    //! Get VTK representation of mesh cell for corresponding object ID
    virtual
    vtkCell* 
    GetElemCell(vtkIdType theObjID);

    //! Get VTK representation of mesh for corresponding MED entity
    virtual
    vtkDataSet*
    GetOutput() = 0;

    //! Gets memory size used by the instance (bytes).
    virtual
    unsigned long int
    GetMemorySize() = 0;
  };
  typedef MED::SharedPtr<TIDMapper> PIDMapper;
  

  //---------------------------------------------------------------
  struct VISU_CONVERTOR_EXPORT TUnstructuredGridIDMapper: virtual TIDMapper
  {
    //! Get VTK representation of mesh for corresponding MED entity
    virtual
    vtkUnstructuredGrid*
    GetUnstructuredGridOutput() = 0;

    //! Reimplement the TIDMapper::GetOutput
    virtual
    vtkDataSet*
    GetOutput();
  };
  typedef MED::SharedPtr<TUnstructuredGridIDMapper> PUnstructuredGridIDMapper;
  

  //---------------------------------------------------------------
  //! Defines an abstract interface for VTK to object ID's and backward mapping
  /*!
    This class defines some additional methods that allow get names for corresponding mesh elements
  */
  struct TNamedIDMapper: virtual TUnstructuredGridIDMapper
  {
    //! Get name of mesh node for corresponding object ID
    virtual
    std::string 
    GetNodeName(vtkIdType theObjID) const = 0;

    //! Get name of mesh cell for corresponding object ID
    virtual
    std::string 
    GetElemName(vtkIdType theObjID) const = 0;
  };
  typedef MED::SharedPtr<TNamedIDMapper> PNamedIDMapper;
  

  //---------------------------------------------------------------
  struct TPolyDataIDMapper: virtual TIDMapper
  {
    //! Get VTK representation of mesh for corresponding MED entity
    virtual
    vtkPolyData*
    GetPolyDataOutput() = 0;

    //! Reimplement the TIDMapper::GetOutput
    virtual
    vtkDataSet*
    GetOutput();
  };
  typedef MED::SharedPtr<TPolyDataIDMapper> PPolyDataIDMapper;
  

  //---------------------------------------------------------------
  typedef vtkIdType TCellID; 
  typedef vtkIdType TLocalPntID;
  //! Defines a type that represent complex ID for defined Gauss Point
  typedef std::pair<TCellID,TLocalPntID> TGaussPointID;

  struct TGaussPtsIDMapper: virtual TPolyDataIDMapper
  {
    //! Gets complex Gauss Point ID by its VTK ID
    virtual 
    TGaussPointID 
    GetObjID(vtkIdType theID) const = 0;

    //! Gets VTK ID by its complex Gauss Point ID 
    virtual 
    vtkIdType 
    GetVTKID(const TGaussPointID& theID) const = 0;

    //! Gets parent TNamedIDMapper, which contains reference mesh cells
    virtual 
    TNamedIDMapper*
    GetParent() const = 0;
  };
  typedef MED::SharedPtr<TGaussPtsIDMapper> PGaussPtsIDMapper;

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

#endif
