// ---------------------------------------------------------------------
//
// Copyright (C) 2000 - 2023 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, 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, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE.md at
// the top level directory of deal.II.
//
// ---------------------------------------------------------------------

#ifndef dealii_grid_reordering_h
#define dealii_grid_reordering_h


#include <deal.II/base/config.h>

#include <deal.II/grid/tria.h>

#include <vector>

DEAL_II_NAMESPACE_OPEN

/**
 * A class implementing various grid reordering algorithms. For more information
 * see the
 * @ref reordering "reordering module".
 *
 * @deprecated Use GridTools::invert_all_negative_measure_cells() or
 * GridTools::consistently_order_cells() instead of the functions provided by
 * this class. Usage of the old-style numbering is deprecated.
 */
template <int dim, int spacedim = dim>
class GridReordering
{
public:
  /**
   * This is the main function, doing what is announced in the general
   * documentation of this class for dim=2 and 3 and doing nothing for dim=1.
   *
   * If a consistent reordering is not possible in dim=3, the original
   * connectivity data is restored.
   *
   * @param original_cells An object that contains the data that describes the
   * mesh.
   * @param use_new_style_ordering If true, then use the standard ordering of
   * vertices within a cell. If false (the default), then use the "old-style"
   * ordering of vertices within cells used by deal.II before version 5.2 and
   * as explained in the documentation of this class.
   *
   * @deprecated Use GridTools::consistently_order_cells() instead.
   */
  DEAL_II_DEPRECATED
  static void
  reorder_cells(std::vector<CellData<dim>> &original_cells,
                const bool                  use_new_style_ordering = false);

  /**
   * Grids generated by grid generators may have an orientation of cells which
   * is the inverse of the orientation required by deal.II.
   *
   * In 2d and 3d this function checks whether all cells have negative or
   * positive measure/volume. In the former case, all cells are inverted. It
   * does nothing in 1d.
   *
   * The inversion of cells might also work when only a subset of all cells
   * have negative volume. However, grids consisting of a mixture of negative
   * and positively oriented cells are very likely to be broken. Therefore, an
   * exception is thrown, in case cells are not uniformly oriented.
   *
   * Note, that this function should be called before reorder_cells().
   *
   * @param all_vertices The vertices of the mesh.
   * @param original_cells An object that contains the data that describes the
   * mesh.
   * @param use_new_style_ordering If true, then use the standard ordering of
   * vertices within a cell. If false (the default), then use the "old-style"
   * ordering of vertices within cells used by deal.II before version 5.2 and
   * as explained in the documentation of this class.
   *
   * @deprecated Use GridTools::invert_all_negative_measure_cells() instead.
   */
  DEAL_II_DEPRECATED
  static void
  invert_all_cells_of_negative_grid(
    const std::vector<Point<spacedim>> &all_vertices,
    std::vector<CellData<dim>> &        original_cells,
    const bool                          use_new_style_ordering = false);
};


// declaration of explicit specializations
template <>
void
GridReordering<2>::invert_all_cells_of_negative_grid(
  const std::vector<Point<2>> &all_vertices,
  std::vector<CellData<2>> &   cells,
  const bool                   use_new_style_ordering);

template <>
void
GridReordering<2, 3>::invert_all_cells_of_negative_grid(
  const std::vector<Point<3>> &all_vertices,
  std::vector<CellData<2>> &   cells,
  const bool                   use_new_style_ordering);

template <>
void
GridReordering<3>::invert_all_cells_of_negative_grid(
  const std::vector<Point<3>> &all_vertices,
  std::vector<CellData<3>> &   cells,
  const bool                   use_new_style_ordering);

DEAL_II_NAMESPACE_CLOSE

#endif
