#include <Rcpp.h>
// Copyright (c) 2004-2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL: https://github.com/CGAL/cgal/blob/v5.6.1/Mesher_level/include/CGAL/Meshes/Double_map_container.h $
// $Id: Double_map_container.h 3674c93 2022-11-15T15:21:01+01:00 albert-github
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s)     : Laurent RINEAU

#ifndef CGAL_MESHES_DOUBLE_MAP_CONTAINER_H
#define CGAL_MESHES_DOUBLE_MAP_CONTAINER_H

#include <set>
#include <iostream>
#include <CGAL/Double_map.h>

// backward compatibility
#ifdef CGAL_MESH_3_DEBUG_DOUBLE_MAP
#  define CGAL_MESHES_DEBUG_DOUBLE_MAP CGAL_MESH_3_DEBUG_DOUBLE_MAP
#endif

namespace CGAL {

  namespace Meshes {

    template <typename Elt, class Quality>
    class Double_map_container
    {
    public:
      typedef Elt Element;

    protected:
      // --- protected data ---
      Double_map<Element, Quality> m;

    public:
      bool no_longer_element_to_refine_impl() const
      {
        return m.empty();
      }

#if CGAL_MESHES_DEBUG_DOUBLE_MAP
      template <typename Element_type>
      std::ostream& debug_element(std::ostream& os, const Element_type& e) {
        return os << (void*)(e.operator->());
      }

      template <typename Cell_handle>
      std::ostream& debug_element(std::ostream& os, const std::pair<Cell_handle, int>& e) {
        return os << "Facet{" << (void*)(e.first.operator->()) << ", " << e.second << "}";
      }
#endif

      Element get_next_element_impl()
      {
        CGAL_assertion(!m.empty());
#if CGAL_MESHES_DEBUG_DOUBLE_MAP
        Rcpp::Rcerr << "get_next_element_impl(";
        debug_element(Rcpp::Rcerr, m.front()->second);
        Rcpp::Rcerr << ")\n";
#endif
        return m.front()->second;

      }

      void add_bad_element(const Element& e, const Quality& q)
      {
#if CGAL_MESHES_DEBUG_DOUBLE_MAP
        Rcpp::Rcerr << "add_bad_element(";
        debug_element(Rcpp::Rcerr, e);
        Rcpp::Rcerr << ")\n";
#endif
        m.insert(e, q);
      }

      void pop_next_element_impl()
      {
        m.pop_front();
      }

      void remove_element(const Element& e)
      {
#if CGAL_MESHES_DEBUG_DOUBLE_MAP
        Rcpp::Rcerr << "remove_element(";
        debug_element(Rcpp::Rcerr, e);
        Rcpp::Rcerr << ")\n";
#endif
        m.erase(e);
      }

      typename Double_map<Element, Quality>::size_type
      size() const
      {
        return m.size();
      }
    }; // end Double_map_container

  } // end namespace Meshes
} // end namespace CGAL

#endif // CGAL_MESHES_DOUBLE_MAP_CONTAINER_H

