//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Sample/StandardSamples/CustomMorphologyBuilder.cpp
//! @brief     Implements class CustomMorphologyBuilder.
//!
//! @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/StandardSamples/CustomMorphologyBuilder.h"
#include "Base/Const/Units.h"
#include "Sample/Aggregate/ParticleLayout.h"
#include "Sample/HardParticle/Polyhedra.h"
#include "Sample/Multilayer/Layer.h"
#include "Sample/Multilayer/MultiLayer.h"
#include "Sample/Particle/Particle.h"
#include "Sample/Scattering/Rotations.h"
#include "Sample/StandardSamples/ReferenceMaterials.h"

using Units::deg;

MultiLayer* ExemplarySamples::createCustomMorphology()
{
    Material mat_vacuum = refMat::Vacuum;
    Material mat_particle = refMat::Particle;

    Layer vacuum_layer(mat_vacuum);
    ParticleLayout particle_layout;

    // add particle number 1:
    Box ff1(2.0, 2.0, 1.0);
    R3 pos1(0.0, 0.0, 0.0);
    Particle p1(mat_particle, ff1);
    p1.translate(pos1);
    particle_layout.addParticle(p1, 0.5);
    // add particle number 2:
    Box ff2(2.0, 4.0, 1.0);
    R3 pos2(5.0, 5.0, 0.0);
    RotationZ m2(10 * deg);
    Particle p2(mat_particle, ff2);
    p2.rotate(m2);
    p2.translate(pos2);
    particle_layout.addParticle(p2, 0.5);
    // add particle number 3:
    Box ff3(2.0, 6.0, 1.0);
    R3 pos3(-5.0, -5.0, 0.0);
    RotationZ m3(20 * deg);
    Particle p3(mat_particle, ff3);
    p3.rotate(m3);
    p3.translate(pos3);
    particle_layout.addParticle(p3, 0.5);
    // add particle number 4:
    Box ff4(2.0, 8.0, 1.0);
    R3 pos4(5.0, -5.0, 0.0);
    RotationZ m4(30 * deg);
    Particle p4(mat_particle, ff4);
    p4.rotate(m4);
    p4.translate(pos4);
    particle_layout.addParticle(p4, 0.5);
    // add particle number 5:
    Box ff5(2.0, 10.0, 1.0);
    R3 pos5(-5.0, 5.0, 0.0);
    RotationZ m5(40 * deg);
    Particle p5(mat_particle, ff5);
    p5.rotate(m5);
    p5.translate(pos5);
    particle_layout.addParticle(p5, 0.5);
    // add particle number 6:
    Box ff6(2.0, 2.0, 1.0);
    R3 pos6(0.0, 0.0, 0.0);
    RotationZ m6(50 * deg);
    Particle p6(mat_particle, ff6);
    p6.rotate(m6);
    p6.translate(pos6);
    particle_layout.addParticle(p6, 0.5);
    // add particle number 7:
    Box ff7(2.0, 4.0, 1.0);
    R3 pos7(5.0, 5.0, 0.0);
    RotationZ m7(60 * deg);
    Particle p7(mat_particle, ff7);
    p7.rotate(m7);
    p7.translate(pos7);
    particle_layout.addParticle(p7, 0.5);
    // add particle number 8:
    Box ff8(2.0, 6.0, 1.0);
    R3 pos8(-5.0, -5.0, 0.0);
    RotationZ m8(70 * deg);
    Particle p8(mat_particle, ff8);
    p8.rotate(m8);
    p8.translate(pos8);
    particle_layout.addParticle(p8, 0.5);
    // add particle number 9:
    Box ff9(2.0, 8.0, 1.0);
    R3 pos9(5.0, -5.0, 0.0);
    RotationZ m9(80 * deg);
    Particle p9(mat_particle, ff9);
    p9.rotate(m9);
    p9.translate(pos9);
    particle_layout.addParticle(p9, 0.5);
    // add particle number 10:
    Box ff10(2.0, 10.0, 1.0);
    R3 pos10(-5.0, 5.0, 0.0);
    RotationZ m10(90 * deg);
    Particle p10(mat_particle, ff10);
    p10.rotate(m10);
    p10.translate(pos10);
    particle_layout.addParticle(p10, 0.5);
    vacuum_layer.addLayout(particle_layout);

    auto* sample = new MultiLayer();
    sample->addLayer(vacuum_layer);
    return sample;
}
