//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Sample/HardParticle/Polyhedra.cpp
//! @brief     Implements class Box.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "Sample/HardParticle/Polyhedra.h"
#include <ff/Make.h>

//  ************************************************************************************************
//  Prisms
//  ************************************************************************************************

Box::Box(const std::vector<double> P)
    : IFormFactorPrism(P)
    , m_length(m_P[0])
    , m_width(m_P[1])
    , m_height(m_P[2])
{
    pimpl.reset(ff::make::Box(m_length, m_width, m_height));
    m_validated = true;
}

Box::Box(double length, double width, double height)
    : Box(std::vector<double>{length, width, height})
{
}


Prism3::Prism3(const std::vector<double> P)
    : IFormFactorPrism(P)
    , m_base_edge(m_P[0])
    , m_height(m_P[1])
{
    pimpl.reset(ff::make::Prism3(m_base_edge, m_height));
    m_validated = true;
}

Prism3::Prism3(double base_edge, double height)
    : Prism3(std::vector<double>{base_edge, height})
{
}


Prism6::Prism6(const std::vector<double> P)
    : IFormFactorPrism(P)
    , m_base_edge(m_P[0])
    , m_height(m_P[1])
{
    pimpl.reset(ff::make::Prism6(m_base_edge, m_height));
    m_validated = true;
}

Prism6::Prism6(double base_edge, double height)
    : Prism6(std::vector<double>{base_edge, height})
{
}

//  ************************************************************************************************
//  Platonic solids
//  ************************************************************************************************

PlatonicTetrahedron::PlatonicTetrahedron(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_edge(m_P[0])
{
    pimpl.reset(ff::make::Tetrahedron(m_edge));
    m_validated = true;
}

PlatonicTetrahedron::PlatonicTetrahedron(double edge)
    : PlatonicTetrahedron(std::vector<double>{edge})
{
}


PlatonicOctahedron::PlatonicOctahedron(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_edge(m_P[0])
{
    pimpl.reset(ff::make::Octahedron(m_edge));
    m_validated = true;
}

PlatonicOctahedron::PlatonicOctahedron(double edge)
    : PlatonicOctahedron(std::vector<double>{edge})
{
}


Dodecahedron::Dodecahedron(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_edge(m_P[0])
{
    pimpl.reset(ff::make::Dodecahedron(m_edge));
    m_validated = true;
}

Dodecahedron::Dodecahedron(double edge)
    : Dodecahedron(std::vector<double>{edge})
{
}


Icosahedron::Icosahedron(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_edge(m_P[0])
{
    pimpl.reset(ff::make::Icosahedron(m_edge));
    m_validated = true;
}

Icosahedron::Icosahedron(double edge)
    : Icosahedron(std::vector<double>{edge})
{
}

//  ************************************************************************************************
//  Pyramids
//  ************************************************************************************************

Pyramid2::Pyramid2(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_length(m_P[0])
    , m_width(m_P[1])
    , m_height(m_P[2])
    , m_alpha(m_P[3])
{
    pimpl.reset(ff::make::Pyramid2(m_length, m_width, m_height, m_alpha));
    m_validated = true;
}

Pyramid2::Pyramid2(double length, double width, double height, double alpha)
    : Pyramid2(std::vector<double>{length, width, height, alpha})
{
}


Pyramid3::Pyramid3(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_base_edge(m_P[0])
    , m_height(m_P[1])
    , m_alpha(m_P[2])
{
    pimpl.reset(ff::make::Pyramid3(m_base_edge, m_height, m_alpha));
    m_validated = true;
}

Pyramid3::Pyramid3(double base_edge, double height, double alpha)
    : Pyramid3(std::vector<double>{base_edge, height, alpha})
{
}


Pyramid4::Pyramid4(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_base_edge(m_P[0])
    , m_height(m_P[1])
    , m_alpha(m_P[2])
{
    pimpl.reset(ff::make::Pyramid4(m_base_edge, m_height, m_alpha));
    m_validated = true;
}

Pyramid4::Pyramid4(double base_edge, double height, double alpha)
    : Pyramid4(std::vector<double>{base_edge, height, alpha})
{
}


Pyramid6::Pyramid6(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_base_edge(m_P[0])
    , m_height(m_P[1])
    , m_alpha(m_P[2])
{
    pimpl.reset(ff::make::Pyramid6(m_base_edge, m_height, m_alpha));
    m_validated = true;
}

Pyramid6::Pyramid6(double base_edge, double height, double alpha)
    : Pyramid6(std::vector<double>{base_edge, height, alpha})
{
}


Bipyramid4::Bipyramid4(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_length(m_P[0])
    , m_base_height(m_P[1])
    , m_height_ratio(m_P[2])
    , m_alpha(m_P[3])
{
    pimpl.reset(ff::make::Bipyramid4(m_length, m_base_height, m_height_ratio, m_alpha));
    m_validated = true;
}

Bipyramid4::Bipyramid4(double length, double base_height, double height_ratio, double alpha)
    : Bipyramid4(std::vector<double>{length, base_height, height_ratio, alpha})
{
}

//  ************************************************************************************************
//  Others
//  ************************************************************************************************

CantellatedCube::CantellatedCube(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_length(m_P[0])
    , m_removed_length(m_P[1])
{
    pimpl.reset(ff::make::CantellatedCube(m_length, m_removed_length));
    m_validated = true;
}

CantellatedCube::CantellatedCube(double length, double removed_length)
    : CantellatedCube(std::vector<double>{length, removed_length})
{
}


TruncatedCube::TruncatedCube(const std::vector<double> P)
    : IFormFactorPolyhedron(P)
    , m_length(m_P[0])
    , m_removed_length(m_P[1])
{
    pimpl.reset(ff::make::TruncatedCube(m_length, m_removed_length));
    m_validated = true;
}

TruncatedCube::TruncatedCube(double length, double removed_length)
    : TruncatedCube(std::vector<double>{length, removed_length})
{
}
