package CH.ifa.draw.util;

import java.awt.Point;
import java.util.Vector;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

/**
 * DoublePointTest tests non-trivial methods of the class {@link DoublePoint}
 */
class DoublePointTest {
    /**
     * Tests whether a Vector of Points is correctly converted into a Vector of DoublePoints.
     * And whether the edge case of converting an empty Vector of Points is correctly handled.
     */
    @Test
    public void testConvertPointVector() {
        //given
        Vector<Point> points = new Vector<>();
        points.add(new Point(10, 20));
        points.add(new Point(-30, 40));
        points.add(new Point(50, 60));

        Vector<Point> emptyPoints = new Vector<>();

        //when
        Vector<DoublePoint> doublePoints = DoublePoint.convertPointVector(points);
        Vector<DoublePoint> emptyDoublePoints = DoublePoint.convertPointVector(emptyPoints);
        //then
        assertThat(doublePoints).hasSameSizeAs(points);
        assertThat(emptyDoublePoints).hasSameSizeAs(emptyPoints);

        // Assert that the values have stayed the same
        for (DoublePoint dP : doublePoints) {
            assertThat(dP.x).isEqualTo(new DoublePoint(dP).x);
            assertThat(dP.y).isEqualTo(new DoublePoint(dP).y);
        }
    }

    /**
     * Tests whether a NullPointerException is thrown when Vector contains null
     */
    @Test
    public void testConvertPointVectorThrowsExceptionWhenNullInVector() {
        //given
        Vector<Point> points = new Vector<>();
        points.add(new Point(10, 20));
        points.add(null);
        points.add(new Point(50, 60));

        //when/then
        assertThatThrownBy(() -> DoublePoint.convertPointVector(points))
            .isInstanceOf(NullPointerException.class);
    }

    /**
     * Tests whether a Vector of DoublePoints is correctly converted into a Vector of Points.
     * And whether the edge case of converting an empty Vector of DoublePoints is correctly handled.
     */
    @Test
    public void testConvertDoublePointVector() {
        //given
        Vector<DoublePoint> doublePoints = new Vector<>();
        doublePoints.add(new DoublePoint(1.2, 2.3));
        doublePoints.add(new DoublePoint(-4.5, 6.7));
        doublePoints.add(new DoublePoint(8.9, 0.1));

        Vector<DoublePoint> emptyDoublePoints = new Vector<>();

        //when
        Vector<Point> points = DoublePoint.convertDoublePointVector(doublePoints);
        Vector<Point> emptyPoints = DoublePoint.convertDoublePointVector(emptyDoublePoints);

        //then
        assertThat(points).hasSameSizeAs(doublePoints);
        assertThat(emptyPoints).hasSameSizeAs(emptyDoublePoints);

        // Assert that the values have been cast correctly
        for (int i = 0; i < points.size(); i++) {
            assertThat(points.get(i).x).isEqualTo((int) doublePoints.get(i).x);
            assertThat(points.get(i).y).isEqualTo((int) doublePoints.get(i).y);
        }
    }

    /**
     * Tests whether a NullPointerException is thrown when Vector contains null
     */
    @Test
    public void testConvertDoublePointVectorThrowsExceptionWhenNullInVector() {
        //given
        Vector<DoublePoint> doublePoints = new Vector<>();
        doublePoints.add(new DoublePoint(1.2, 2.3));
        doublePoints.add(null);
        doublePoints.add(new DoublePoint(8.9, 0.1));

        //when/then
        assertThatThrownBy(() -> DoublePoint.convertDoublePointVector(doublePoints))
            .isInstanceOf(NullPointerException.class);
    }

}
