package presenter.algorithms;


import model.Interval;
import model.Line;
import model.Point;
import org.junit.Before;
import org.junit.Test;
import presenter.algorithms.advanced.LeastMedianOfSquaresEstimator;
import presenter.algorithms.util.IntersectionCounter;

import java.util.ArrayList;
import java.util.LinkedList;

import static org.junit.Assert.*;

/**
 * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
 *
 * @Author: Armin Wolf
 * @Email: a_wolf28@uni-muenster.de
 * @Date: 12.06.2017.
 */
public class LeastMedianOfSquaresEstimatorTest {

    private LeastMedianOfSquaresEstimator lms;

    @Before
    public void setUp() throws Exception {

        Double[] x = {18d, 24d, 30d, 34d, 38d};
        Double[] y = {18d, 26d, 30d, 40d, 70d};

        LinkedList<Line> lines = new LinkedList<>();
        ArrayList<Point> intersections = new ArrayList<>();

        for (int i = 0; i < 5; i++) {
            lines.add(new Line(x[i], y[i]));
        }

        lms = new LeastMedianOfSquaresEstimator(lines, intersections);
    }

    @Test
    public void approximateLMS() throws Exception {

    }


    @Test
    public void mergeSort() throws Exception {
//        double[] umin = {6,3,4,1,2,5};
//        double[] umax = {3,5,2,6,1,4};
        double[] umin = {1, 2, 3, 4};
        double[] umax = {2, 3, 4, 1};
        ArrayList<Integer> a = new ArrayList<>();
        ArrayList<Integer> b = new ArrayList<>();

        for (double d : umin) {
            a.add((int) d);
        }

        for (double d : umax) {
            b.add((int) d);
        }
        IntersectionCounter invCounter = new IntersectionCounter();
        int ret = invCounter.run(a, b);
        assertEquals(3d, ret, 0.001);

    }

    @Test
    public void geEjValues() throws Exception {

        Double[] expected = {36d, 50d, 60d, 74d, 108d};
        ArrayList<Double> actual = lms.getEjValues(1d);
        assertArrayEquals(expected, actual.toArray());
    }

    @Test
    public void calcKMinusBracelet() throws Exception {

        Point point = new Point(1d, 1d);
        Double[] expected = {24d, 36d, 60d};
        Double[] actual = lms.calcKMinusBracelet(point, 3);

        assertArrayEquals(expected, actual);

    }

    @Test
    public void upperBound() throws Exception {
        lms.setkMinus(3);
        lms.setHeightsigmaMin(500);
        lms.setSigmaMin(new Line(0, 0, 0, 0));
        lms.setN(5);
        Line expected = new Line(5, 5, 146, 210);
        lms.upperBound(5d);

        assertEquals(expected.getX1(), lms.getSigmaMin().getX1(), 0.01);
        assertEquals(expected.getX2(), lms.getSigmaMin().getX2(), 0.01);
        assertEquals(expected.getY1(), lms.getSigmaMin().getY1(), 0.01);
        assertEquals(expected.getY2(), lms.getSigmaMin().getY2(), 0.01);
    }

    @Test
    public void lowerBound() throws Exception {
        //kann nur über sout geprüft werden test passt aber
        Double[] expectedAlpha = {0d, 0d, 0d, 2d, 4d};
        Double[] expectedBeta = {2d, 4d, 4d, 2d, 1d};
        lms.setHeightsigmaMin(500);

        Interval interval = new Interval(-2, 0);
        lms.lowerBound(interval);
        assertTrue(interval.getActivity());
    }


}