namespace CGAL {

/*!
\ingroup PkgStraightSkeleton2Classes

The class `Polygon_offset_builder_2` encapsulates the construction of
inward offset contours of a 2D simple polygon with holes. The
construction is based on the straight skeleton of the interior of the
polygon.

\tparam StraightSkeleton_ must be a model of the `StraightSkeleton_2`.
\tparam Traits_ must be a model of the `StraightSkeletonBuilderTraits_2`.
\tparam Container_ must be a model of the `SequenceContainer`.

\sa `PolygonOffsetBuilderTraits_2`
\sa `Polygon_offset_builder_traits_2`
*/
template< typename StraightSkeleton_, typename Traits_, typename Container_ >
class Polygon_offset_builder_2
{
public:

/// \name Types
/// @{

/*!
The straight skeleton (first template parameter)
*/
typedef StraightSkeleton_ Ss;

/*!
The geometric traits (second template parameter)
*/
typedef Traits_ Traits;

/*!
The container of 2D vertices that represents each offset contour generated by the algorithm (third template parameter)
*/
typedef Container_ Container;

/*!
The model of `FieldWithSqrt` used to specify the desired offset distance, provided by the geometric traits `Traits`.
*/
  typedef Traits::FT FT;

/// @}

/// \name Creation
/// @{

/*!
Constructs the builder class using the given Straight Skeleton instance.
*/
Polygon_offset_builder_2( const Ss& ss, const Traits& traits = Traits() );

/// @}

/// \name Methods
/// @{

/*!
Given the straight skeleton passed in the constructor which corresponds to the interior
of a non-degenerate strictly-simple polygon with holes <I>P</I>, returns <I>all</I>
the offset contours of <I>P</I> at the Euclidean distance `t`.

Such offset contours are polygons in the interior of `P`. Provided exact constructions are used,
these polygons are strictly simple. For any offset distance `t` there are `0`, `1`, or more offset contours.

For any given input polygon, its offset polygons at a certain distance are composed of several contours.
This method returns all such contours in an unspecified order and with no parental relationship
between them (that is why it is called `construct_offset_contours()` and not `construct_offset_polygons()`).

Those offset contours in the resulting sequence which are oriented counterclockwise are outer contours
and those oriented clockwise are holes. It is up to the user to match each hole to its parent in order
to reconstruct the parent-hole relationship of the conceptual output. It is sufficient to test each hole
against each parent as there won't be a hole inside a hole, a parent inside any other contour,
or a hole inside more than one parent. The recommended insideness test is to perform
a regularized Boolean set operation. The function `do_intersect()`
from Chapter \ref Chapter_2D_Regularized_Boolean_Set-Operations "2D Regularized Boolean Set-Operations"
will work fine in our case since it is guaranteed that no hole would cross halfway outside any parent
(in the presence of such cases, subtracting the parent from the hole works better
as it correctly rejects halfway holes).

You can call `construct_offset_contours()` with different offset distances (there is no need
to construct the builder again). If you call it with an offset distance so large
that there are no offset contours at that distance, no contour is inserted into the output sequence
and the returned iterator will be equal to `out`.

If there are degenerate, or nearly degenerate vertices; that is, vertices whose internal
or external angle approaches `0`, numerical overflow may prevent some of the polygon contours to be constructed.
If that happens, the failed contour just won't be added into the resulting sequence.

\tparam OutputIterator must be a model of the <I>OutputIterator</I> category whose `value_type`
                       is a `std::shared_ptr` holding the dynamically allocated instances of type `Container`.

\param t the offset value
\param out an output iterator. For each resulting offset contour, a default constructed instance
           of `Container` type, is dynamically allocated and each offset vertex is added to it.
           A `std::shared_ptr` holding onto the dynamically allocated container is inserted
           into the output sequence via the OutputIterator `out`.

\returns an `OutputIterator` past-the-end of the resulting sequence, which contains each offset contour generated.

\pre `t > 0`
*/
template<class OutputIterator>
OutputIterator construct_offset_contours( FT t, OutputIterator out );

/// @}

}; /* end Polygon_offset_builder_2 */

} /* end namespace CGAL */
