#include "Resample/Processed/ReSample.h"

#include "Sample/Aggregate/Interference2DLattice.h"
#include "Sample/Aggregate/ParticleLayout.h"
#include "Sample/HardParticle/Cylinder.h"
#include "Sample/Material/MaterialFactoryFuncs.h"
#include "Sample/Multilayer/Layer.h"
#include "Sample/Multilayer/MultiLayer.h"
#include "Sample/Particle/Particle.h"
#include "Tests/GTestWrapper/google_test.h"

TEST(MultilayerAveragingTest, AverageMultilayer)
{
    const auto mat0 = RefractiveMaterial("vac", 0.0, 0.0);
    const auto mat1 = RefractiveMaterial("stone", 4e-4, 8e-7);

    // particles
    Cylinder cylinder_ff(1.0, 3.0);
    Particle particle(mat1, cylinder_ff);

    // interferences
    Interference2DLattice interf_1(BasicLattice2D(10.0, 10.0, 120.0, 0.0));
    Interference2DLattice interf_2(BasicLattice2D(10.0, 10.0, 120.0, 0.0));

    // layouts
    ParticleLayout layout_1;
    layout_1.addParticle(particle);
    layout_1.setInterference(interf_1);

    ParticleLayout layout_2;
    layout_2.addParticle(particle);
    layout_2.setInterference(interf_2);

    Layer layer_1(mat0);
    Layer layer_2(mat1);

    layer_1.addLayout(layout_1);

    MultiLayer m_layer;
    m_layer.addLayer(layer_1);
    m_layer.addLayer(layer_2);

    const auto sample_1 = ReSample::make(m_layer);

    Layer layer_21(mat0);
    Layer layer_22(mat1);

    layer_21.addLayout(layout_1);
    layer_21.addLayout(layout_2);

    MultiLayer m_layer2;
    m_layer2.addLayer(layer_21);
    m_layer2.addLayer(layer_22);

    const auto sample_2 = ReSample::make(m_layer2);

    EXPECT_EQ(sample_1.numberOfSlices(), sample_2.numberOfSlices());

    for (size_t i = 0; i < sample_1.numberOfSlices(); ++i) {
        auto mat_1 = sample_1.avgeSlice(i).material().refractiveIndex_or_SLD();
        auto mat_2 = sample_2.avgeSlice(i).material().refractiveIndex_or_SLD();
        EXPECT_DOUBLE_EQ(mat_1.real(), mat_2.real());
        EXPECT_DOUBLE_EQ(mat_1.imag(), mat_2.imag());
    }
}
