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

#include "Sample/Multilayer/LayerStack.h"
#include "Base/Util/Assert.h"
#include "Base/Util/StringUtil.h"
#include "Sample/Multilayer/Layer.h"
#include <limits>
#include <utility>

LayerStack::LayerStack(size_t num_periods)
    : m_n_periods(num_periods)
{
}

LayerStack::~LayerStack() = default;

void LayerStack::addLayer(const Layer& layer)
{
    addSublayer(layer);
}

void LayerStack::addStack(const LayerStack& substack)
{
    addSublayer(substack);
}

LayerStack* LayerStack::clone() const
{
    auto* result = new LayerStack(m_n_periods);
    for (const auto& layer : m_sublayers)
        result->addSublayer(std::as_const(*layer));
    return result;
}

void LayerStack::addSublayer(const ILayer& sublayer)
{
    ASSERT(!m_validated);
    m_sublayers.emplace_back(std::unique_ptr<ILayer>(sublayer.clone()));
}

std::vector<std::unique_ptr<Layer>> LayerStack::flatClones() const
{
    std::vector<std::unique_ptr<Layer>> result;
    for (size_t i = 0; i < m_n_periods; i++) {
        for (const auto& layer : m_sublayers) {
            auto layer_clones = layer->flatClones();
            result.insert(result.end(), std::make_move_iterator(layer_clones.begin()),
                          std::make_move_iterator(layer_clones.end()));
        }
    }
    return result;
}
