// Copyright (c) 2005-2008 Max-Planck-Institute Saarbruecken (Germany).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL: https://github.com/CGAL/cgal/blob/v6.1.1/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/YVertical_wall_builder.h $
// $Id: include/CGAL/Convex_decomposition_3/YVertical_wall_builder.h 08b27d3db14 $
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s)     :  Peter Hachenberger <hachenberger@mpi-sb.mpg.de>
#ifndef CGAL_CD3_YVERTICAL_WALL_BUILDER_H
#define CGAL_CD3_YVERTICAL_WALL_BUILDER_H

#include <CGAL/license/Convex_decomposition_3.h>

#include <CGAL/Modifier_base.h>
#include <CGAL/Nef_3/SNC_decorator.h>
#include <CGAL/Convex_decomposition_3/is_reflex_sedge.h>
#include <CGAL/Convex_decomposition_3/Single_wall_creator3.h>
#include <CGAL/Convex_decomposition_3/External_structure_builder.h>

namespace CGAL {

template<typename Nef_>
class YVertical_wall_builder : public Modifier_base<typename Nef_::SNC_and_PL> {

  typedef Nef_                                            Nef_polyhedron;
  typedef typename Nef_polyhedron::SNC_and_PL             SNC_and_PL;
  typedef typename Nef_polyhedron::SNC_structure          SNC_structure;
  typedef CGAL::SNC_decorator<SNC_structure>              SNC_decorator;
  typedef CGAL::SNC_decorator<SNC_structure>     Base;
  typedef typename CGAL::Single_wall_creator3<Nef_polyhedron> Single_wall3;
  typedef typename CGAL::External_structure_builder<Nef_polyhedron> External_structure_builder;

  typedef typename SNC_structure::Vertex_handle           Vertex_handle;
  typedef typename SNC_structure::Halfedge_handle         Halfedge_handle;
  typedef typename SNC_structure::Halffacet_handle        Halffacet_handle;
  typedef typename SNC_structure::SHalfedge_handle        SHalfedge_handle;
  typedef typename SNC_structure::SHalfloop_handle        SHalfloop_handle;
  typedef typename SNC_structure::SFace_handle            SFace_handle;

  typedef typename SNC_structure::Volume_iterator         Volume_iterator;
  typedef typename SNC_structure::Halfedge_iterator       Halfedge_iterator;
  typedef typename SNC_structure::SFace_iterator       SFace_iterator;
  typedef typename SNC_structure::SHalfedge_around_svertex_circulator
    SHalfedge_around_svertex_circulator;

  typedef typename SNC_structure::Vector_3                Vector_3;
  typedef typename SNC_structure::Point_3                 Point_3;

  typedef typename SNC_structure::Sphere_point            Sphere_point;
  typedef typename SNC_structure::Sphere_circle           Sphere_circle;
  typedef typename SNC_structure::Sphere_segment          Sphere_segment;

  typedef typename std::list<Halfedge_handle>             Edge_list;
 public:
  typedef typename std::list<Halfedge_handle>::iterator   Vertical_redge_iterator;

  Edge_list redges;

 public:
  YVertical_wall_builder() {}

  void operator()(SNC_and_PL& sncpl) {
    SNC_structure* sncp(sncpl.sncp);

    SFace_iterator sfi;
    CGAL_forall_sfaces(sfi, *sncp)
      if(sncp->is_boundary_object(sfi))
        sncp->undef_boundary_item(sfi);

    Halfedge_iterator ei;
    CGAL_forall_halfedges(ei, *sncp) {
      if(ei->point() != Sphere_point(1,0,0)) continue;
      SHalfedge_around_svertex_circulator
        svc(ei->out_sedge()), send(svc);
      CGAL_For_all(svc, send) {
        if(!svc->incident_sface()->mark()) continue;
        if(!CGAL::is_reflex_sedge_in_any_direction<SNC_structure>(svc))
          continue;
        redges.push_back(ei);
        break;
      }
    }

    Vertical_redge_iterator vri;
    for(vri = redges_begin(); vri != redges_end(); ++vri) {
      Halfedge_handle ei(*vri);
      SHalfedge_around_svertex_circulator
        svc(ei->out_sedge()), send(svc);
      CGAL_For_all(svc, send) {
        if(!svc->incident_sface()->mark()) continue;
        if(!CGAL::is_reflex_sedge_in_any_direction<SNC_structure>(svc))
          continue;
        Single_wall3 W(svc);
        W(sncpl);
        break;
      }
    }

  }

  Vertical_redge_iterator redges_begin() { return redges.begin(); }
  Vertical_redge_iterator redges_end()   { return redges.end(); }
};

} //namespace CGAL
#endif // CGAL_CD3_YVERTICAL_WALL_BUILDER_H
