"""
Test of rotation/position of box in the middle layer of 3 layers system.
Box(50, 20, 10), is rotated around Z, then around Y, then shifted up and then
compared with Box(10, 50, 20)
"""

import unittest
import bornagain as ba
from bornagain import deg, R3
import PyFuTestInfrastructure as infrastruct

layer_thickness = 100


class BoxTransformationsTest(unittest.TestCase):

    def get_sample(self, particle):
        mAmbience = ba.RefractiveMaterial("Vacuum", 0, 0)
        mMiddle = ba.RefractiveMaterial("Teflon", 2.900e-6, 6.019e-9)
        mSubstrate = ba.RefractiveMaterial("Substrate", 3.212e-6, 3.244e-8)

        layout = ba.ParticleLayout()
        layout.addParticle(particle)

        vacuum_layer = ba.Layer(mAmbience)
        middle_layer = ba.Layer(mMiddle, layer_thickness)
        middle_layer.addLayout(layout)
        substrate = ba.Layer(mSubstrate)

        sample = ba.MultiLayer()
        sample.addLayer(vacuum_layer)
        sample.addLayer(middle_layer)
        sample.addLayer(substrate)
        return sample

    def get_result(self, particle):
        sample = self.get_sample(particle)
        simulation = infrastruct.get_simulation_MiniGISAS(sample)
        return simulation.simulate()

    def testBoxTransform(self):
        """
        Reference box of (10,50,20) size is compared against the box (50,20,10)
        with two rotations applied to get reference one
        """
        mParticle = ba.RefractiveMaterial("Ag", 1.245e-5, 5.419e-7)

        # reference box
        length = 10
        width = 50
        height = 20

        box = ba.Particle(mParticle, ba.Box(length, width, height))
        box.translate(R3(0, 0, -layer_thickness / 2 - height / 2))
        reference_data = self.get_result(box)

        # second box
        length = 50
        width = 20
        height = 10
        box = ba.Particle(mParticle, ba.Box(length, width, height))
        box.rotate(ba.RotationZ(90 * deg))
        box.rotate(ba.RotationY(90 * deg))
        box.translate(R3(0, 0, -layer_thickness / 2))

        data = self.get_result(box)

        diff = ba.meanRelativeDifference(data, reference_data)
        self.assertLess(diff, 4e-13)


if __name__ == '__main__':
    unittest.main()
