/***************************************************************************
                          NDMetaGrid.h  -  description
                             -------------------
    begin                : Dec 09, 2021
    copyright            : (C) 2021 by Tomas Oberhuber et al.
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

// Implemented by: Jakub Klinkovský

#pragma once

#include <TNL/Containers/StaticVector.h>

namespace TNL {
namespace Meshes {

/**
 * \brief Minimal class usable as \e Mesh in the \ref VTIWriter.
 *
 * It does not have a \e Device template argument, because it does not describe
 * a data structure - it contains only the information describing the domain of
 * the grid (i.e., the metadata of the \e ImageData tag in the VTI file
 * format). Note that VTK supports only 1, 2, or 3-dimensional grids.
 */
template< int Dimension, typename Real, typename Index >
class NDMetaGrid
{
public:
   using RealType = Real;
   using GlobalIndexType = Index;
   using PointType = Containers::StaticVector< Dimension, Real >;
   using CoordinatesType = Containers::StaticVector< Dimension, Index >;

   //! \brief Returns the spatial dimension of the grid.
   static constexpr int getMeshDimension()
   {
      return Dimension;
   }

   //! \brief Sets the grid dimensions/size.
   void setDimensions( const CoordinatesType& dimensions )
   {
      this->dimensions = dimensions;
   }

   //! \brief Returns the grid dimensions/size.
   const CoordinatesType& getDimensions() const
   {
      return dimensions;
   }

   //! \brief Sets the origin of the grid (coordinates of the left bottom front
   //! corner).
   void setOrigin( const PointType& origin )
   {
      this->origin = origin;
   }

   //! \brief Returns the origin of the grid (coordinates of the left bottom
   //! front corner).
   const PointType& getOrigin() const
   {
      return origin;
   }

   //! \brief Sets the domain of the grid (i.e., the origin and
   //! proportions/length). Note that space steps are computed using the
   //! current grid dimensions.
   void setDomain( const PointType& origin,
                   const PointType& proportions )
   {
      this->origin = origin;
      this->spaceSteps = proportions / dimensions;
   }

   //! \brief Sets the space steps of the grid, i.e. the parameters usually
   //! denoted as \e hx, \e hy, \e hz.
   void setSpaceSteps( const PointType& spaceSteps )
   {
      this->spaceSteps = spaceSteps;
   }

   //! \brief Returns the space steps of the grid.
   const PointType& getSpaceSteps() const
   {
      return spaceSteps;
   }

protected:
   CoordinatesType dimensions = 0;

   PointType origin = 0;

   PointType spaceSteps = 0;
};

} // namespace Meshes
} // namespace TNL
