/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK 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 version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/

#ifndef VTKUTIL_H
#define VTKUTIL_H

#include "VtkMeshComponentAPI.h"

#include <Geometry.h>

class vtkPointSet;
class vtkUnstructuredGrid;
class vtkPolyData;
class vtkStructuredGrid;
/**
 *  @ingroup group_sdk_components_vtkmesh
 *
 *  @brief
 *  This class helps to transform, export and import vtk point sets.
 *  @note
 *  As it is a pure transformer, all the methods are static.
 *
 **/
class VTK_COMPONENT_API VtkMeshUtil  {

public:

    /// constant for the vtk point set type
    enum VtkPointSetType {
        UNKNOWN,
        UNSTRUCTURED_GRID,
        STRUCTURED_GRID,
        POLY_DATA
    };

    /** Static method that could be used from anywhere to translate a vtk file to a Geometry instance.
      *  convenient method (it is based on buildVtkPointSet).
      *  @param vtkFileName the name of the vtk file to use as input
      *  @return the new Geometry instance
      */
    static camitk::Geometry* vtkToGeometry(std::string vtkFileName);

    /** Static method that could be used from anywhere to build a vtkPointSet from a vtk file.
    *  Currently only vtkUnstructuredGrid, vtkPolyData and vtkStructuredGrid are supported.
    *  To support more file format build a specific component extension!
    *  @param vtkFileName the name of the vtk file to use as input
    *  @param whatIsIt (optional) if you already know the file type, it is quicker to give it here
    *  @return the new vtkPointSet
    */
    static vtkSmartPointer<vtkPointSet> buildVtkPointSet(std::string vtkFileName, VtkPointSetType whatIsIt = UNKNOWN);

    /** Static method that could be use to store any Geometry instance in a vtk file.
      * @param g the Geometry instance to save
      * @param vtkFileName the name of the vtk file to use as output
      * @param oname the mesh name as it will be saved in the header
      * @return true if everything was saved ok.
      */
    static bool saveGeometryToFile(camitk::Geometry* g, std::string vtkFileName, std::string oname);

    /** save a vtkDataset into a given file.
          * @param ps the vtkPointSet to save
          * @param fname the file name to save to
          * @param oname the name of the object to save (wrote in the header)
          */
    static bool savePointSetToFile(vtkSmartPointer<vtkPointSet> ps, std::string fname, std::string oname = "");

    /** save a given vtkUnstructuredGrid into a given file
        * @param uGrid the vtkUnstructuredGrid to save
        * @param fname the file name to save to
        * @param oname the name of the object to save (wrote in the header)
        */
    static void saveUnstructuredGridToFile(vtkSmartPointer<vtkUnstructuredGrid> uGrid, std::string fname, std::string oname = "");

    /** save a given vtkStructuredGrid into a given file
    * @param sGrid the vtkStructuredGrid to save
    * @param fname the file name to save to
    * @param oname the name of the object to save (wrote in the header)
    */
    static void saveStructuredGridToFile(vtkSmartPointer<vtkStructuredGrid> sGrid, std::string fname, std::string oname = "");

    /** save a given vtkPolyData into a given file
      * @param pData the vtkPolyData to save
      * @param fname the file name to save to
      * @param oname the name of the object to save (wrote in the header)
      */
    static void savePolyDataToFile(vtkSmartPointer<vtkPolyData> pData, std::string fname, std::string oname = "");

    /** static method to get the vtk header string from a vtk file
    *  @param vtkFileName the name of the vtk file to get the header from
    *  @param whatIsIt (optional) if you already know the file type, it is quicker to give it here
    *  @return the header string
    */
    static std::string getVtkPointSetHeaderString(std::string vtkFileName, VtkPointSetType whatIsIt = UNKNOWN);

    /** static method that tells you what kind of vtk file it is.
      * If it returns VtkManager::UNKNOWN, it means the vtk data are not supported.
      * @param vtkFileName the name of the vtk file to check
      * @return the VtkPointSetType of the file given in parameter
      */
    static VtkPointSetType typeOf(std::string vtkFileName);

    /** static method that tells you what kind of vtkPointSet it is.
      * If it returns VtkManager::UNKNOWN, this is an unsupported type of vtkPointSet.
      * @param aPointSet the pointset data to analyze
      * @return the VtkPointSetType of the file given in parameter
      */
    static VtkMeshUtil::VtkPointSetType typeOf(vtkSmartPointer<vtkPointSet> aPointSet);

    /** static method that transform any vtkPointSet to a vtkPolyData.
     *
     * - If the vtkPointSet is already a vtkPolyData, nothing is done.
     * - If the vtkPointSet is a vtkUnstructuredGrid or vtkStructuredGrid, then it uses a vtkDataSetSurfaceFilter
     *   to extract the surface
     * @param aPointSet the vtkPointSet to transform
     * @return the vtkPolyData corresponding
     */
    static vtkSmartPointer<vtkPolyData> vtkPointSetToVtkPolyData(vtkSmartPointer<vtkPointSet> aPointSet);
};


#endif //VTKUTIL_H
