# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md

"""
    Pyramid{N} <: AbstractTopology{N}

Pyramidal topology with N nodes.

# Node Count Variants
- `Pyramid{5}` (alias `Pyr5`): Linear pyramid (P1)

Higher-order pyramid variants (e.g. quadratic Pyramid{13}) are not implemented yet.
"""
struct Pyramid{N} <: AbstractTopology{N} end

const Pyr5 = Pyramid{5}

dim(::Pyramid{N}) where {N} = 3

function reference_coordinates(::Pyramid{5})
    return SVector(Vec{3,Float64}.((
        (-1.0, -1.0, 0.0),
        (1.0, -1.0, 0.0),
        (1.0, 1.0, 0.0),
        (-1.0, 1.0, 0.0),
        (0.0, 0.0, 1.0)
    )))
end

function edges(::T) where {T<:Pyramid}
    return SVector(Edge.((
        (1, 2), (2, 3), (3, 4), (4, 1),  # Base edges
        (1, 5), (2, 5), (3, 5), (4, 5)   # Edges to apex
    )))
end

function faces(::T) where {T<:Pyramid}
    return SVector(Face.((
        (1, 4, 3, 2),  # Quad base
        (1, 2, 5),     # Triangle face 1
        (2, 3, 5),     # Triangle face 2
        (3, 4, 5),     # Triangle face 3
        (4, 1, 5)      # Triangle face 4
    )))
end

function vertices(::T) where {T<:Pyramid}
    return SVector(Vertex(), Vertex(), Vertex(), Vertex(), Vertex())
end

function cells(::T) where {T<:Pyramid}
    return SVector(Cell())
end

nvertices(::Pyramid) = 5
nedges(::Pyramid) = 8
nfaces(::Pyramid) = 5

