/*---------------------------------------------------------------------------*\

    geophase: A C++ template library for geometrical operations on non-convex
    polyhedra with non-planar faces
     
    Copyright (C) 2019 Tomislav Maric, TU Darmstadt 

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Description
    Polyhedron described as a sequence of Tetrahedrons.

Author
    Tomislav Maric maric@mma.tu-darmstadt.de

\*---------------------------------------------------------------------------*/

#ifndef TetrahedronSequence_H
#define TetrahedronSequence_H

#include <memory>
#include <vector>
#include "tag.H"
#include <type_traits>

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam { namespace GeometricalTransport { 

/*---------------------------------------------------------------------------*\
                         Class TetrahedronSequence Declaration
\*---------------------------------------------------------------------------*/

template
<
    typename Tetrahedron,    
    template<typename, typename> class SequenceContainer,
    template <typename T> class Allocator = std::allocator
>
class TetrahedronSequence 
:
    public SequenceContainer
    <
        typename std::enable_if
        <
            Traits::tag_enabled<Tetrahedron, tetrahedron_tag>::value, 
            Tetrahedron
        >::type,
        Allocator<Tetrahedron>
    >
{
    typedef SequenceContainer<Tetrahedron, Allocator<Tetrahedron>> base_type;

    public: 

        using base_type::base_type; 
};

namespace Traits {

    template
    <
        typename Tetrahedron,    
        template<typename, typename> class Sequence,
        template <typename T> class Allocator 
    >
    struct tag 
    <
        TetrahedronSequence<Tetrahedron, Sequence, Allocator>
    >
    {
        typedef tetrahedron_sequence_tag type;
    };

    template <typename Tetrahedron>
    struct tag 
    <
        TetrahedronSequence<Tetrahedron, std::vector>
    >
    {
        typedef tetrahedron_sequence_direct_tag type;
    };


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // end namespace Geometry::Traits 

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

}} // end namespace Foam::GeometricalTransport

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#endif

// ************************************************************************* //
