#include "Base/Axis/MakeScale.h"
#include "Device/Detector/SphericalDetector.h"
#include "Tests/GTestWrapper/google_test.h"
#include <memory>

//! Testing region of interest with reasonable area within the detector.

TEST(RegionOfInterestTest, constructor)
{
    SphericalDetector detector(std::array<std::shared_ptr<Scale>, 2>{
        sharedEquiDivision("axis0", 8, -3.0, 5.0), sharedEquiDivision("axis1", 4, 0.0, 4.0)});

    // creating region of interest
    double xlow(-1.9), ylow(1.1), xup(2.9), yup(2.85);
    detector.setRegionOfInterest(xlow, ylow, xup, yup);
    EXPECT_EQ(detector.regionOfInterestBounds(0).first, xlow);
    EXPECT_EQ(detector.regionOfInterestBounds(0).second, xup);
    EXPECT_EQ(detector.regionOfInterestBounds(1).first, ylow);
    EXPECT_EQ(detector.regionOfInterestBounds(1).second, yup);

    // checking total size of the detector and roi in it
    EXPECT_EQ(detector.totalSize(), 32u);
    EXPECT_EQ(detector.sizeOfRegionOfInterest(), 10u);

    // converting local roi index to global detector index
    EXPECT_EQ(detector.regionOfInterestIndexToDetectorIndex(0), 5u);
    EXPECT_EQ(detector.regionOfInterestIndexToDetectorIndex(1), 6u);
    EXPECT_EQ(detector.regionOfInterestIndexToDetectorIndex(2), 9u);
    EXPECT_EQ(detector.regionOfInterestIndexToDetectorIndex(9), 22u);
}

//! Testing region of interest which is larger than the detector.

TEST(RegionOfInterestTest, largeArea)
{
    SphericalDetector detector(std::array<std::shared_ptr<Scale>, 2>{
        sharedEquiDivision("axis0", 8, -3.0, 5.0), sharedEquiDivision("axis1", 4, 0.0, 4.0)});

    // creating region of interest
    double xlow(-3.9), ylow(-1.1), xup(6.9), yup(5.85);
    detector.setRegionOfInterest(xlow, ylow, xup, yup);

    // checking total size of the detector and roi in it
    EXPECT_EQ(detector.totalSize(), 32u);
    EXPECT_EQ(detector.sizeOfRegionOfInterest(), 32u);

    // converting local roi index to global detector index
    EXPECT_EQ(detector.regionOfInterestIndexToDetectorIndex(5), 5u);
    EXPECT_EQ(detector.regionOfInterestIndexToDetectorIndex(6), 6u);
    EXPECT_EQ(detector.regionOfInterestIndexToDetectorIndex(9), 9u);
    EXPECT_EQ(detector.regionOfInterestIndexToDetectorIndex(27), 27u);
}

//! Testing clone

TEST(RegionOfInterestTest, clone)
{
    SphericalDetector detector(std::array<std::shared_ptr<Scale>, 2>{
        sharedEquiDivision("axis0", 8, -3.0, 5.0), sharedEquiDivision("axis1", 4, 0.0, 4.0)});

    // creating region of interest
    double xlow(-1.9), ylow(1.1), xup(2.9), yup(2.85);
    detector.setRegionOfInterest(xlow, ylow, xup, yup);

    std::unique_ptr<SphericalDetector> clone(detector.clone());

    EXPECT_EQ(clone->regionOfInterestBounds(0).first, xlow);
    EXPECT_EQ(clone->regionOfInterestBounds(0).second, xup);
    EXPECT_EQ(clone->regionOfInterestBounds(1).first, ylow);
    EXPECT_EQ(clone->regionOfInterestBounds(1).second, yup);

    // checking total size of the detector and roi in it
    EXPECT_EQ(clone->totalSize(), 32u);
    EXPECT_EQ(clone->sizeOfRegionOfInterest(), 10u);
}
