/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.sis.referencing.operation.matrix;

import org.apache.sis.test.DependsOn;
import org.junit.Test;

import static java.lang.Double.NaN;
import static org.opengis.test.Assert.*;
import static org.apache.sis.referencing.operation.matrix.Matrix4.SIZE;


/**
 * Tests the {@link Matrix4} implementation.
 * This class inherits all tests defined in {@link MatrixTestCase}.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 * @since   0.4
 * @module
 */
@DependsOn(SolverTest.class)
public final strictfp class Matrix4Test extends MatrixTestCase {
    /**
     * Returns the size of the matrix of interest for this test class.
     */
    @Override int getNumRow() {return SIZE;}
    @Override int getNumCol() {return SIZE;}

    /**
     * Ensures that the given matrix is an instance of the expected type.
     */
    @Override
    void validate(final MatrixSIS matrix) {
        super.validate(matrix);
        assertEquals(Matrix4.class, matrix.getClass());
    }

    /**
     * Tests the {@link Matrix4#Matrix4(double, double, double, double, double, double, double,
     * double, double, double, double, double, double, double, double, double)} constructor.
     * This constructor is specific to the implementation class.
     */
    @Test
    public void testConstructor() {
        initialize(-7053945420932915425L);
        final double[] elements = createRandomPositiveValues(SIZE * SIZE);
        final Matrix4 matrix = new Matrix4(
                elements[ 0],
                elements[ 1],
                elements[ 2],
                elements[ 3],
                elements[ 4],
                elements[ 5],
                elements[ 6],
                elements[ 7],
                elements[ 8],
                elements[ 9],
                elements[10],
                elements[11],
                elements[12],
                elements[13],
                elements[14],
                elements[15]);
        validate(matrix);
        assertArrayEquals(elements, matrix.getElements(), STRICT);
    }

    /**
     * Tests multiplication of a matrix that contains NaN numbers.
     * We want to avoid having NaNs of a full row or full column.
     *
     * Note that a NaN may appear in the translation column, depending on the matrix order in multiplication.
     * So handling of NaN during multiplication does not eliminate completely the need to write some NaN-safe
     * code in the Apache SIS modules.
     */
    @Test
    public void testMultiplyWithNaN() {
        final Matrix4 m1 = new Matrix4(
                0.5,  0,    0,   -179.5,
                0,    0.25, 0,    -89.5,
                0,    0,  NaN,  20989.0,
                0,    0,    0,      1);

        final Matrix4 m2 = new Matrix4(
                4,  0,  0,      0,
                0,  6,  0,      0,
                0,  0,  1,  18262.5,
                0,  0,  0,      1);

        assertMatrixEquals("Multiplication with NaN", new Matrix4(
                2.0,  0,      0,   -718.0,
                0,    1.5,    0,   -537.0,
                0,    0,    NaN,  39251.5,
                0,    0,      0,      1), m2.multiply(m1), STRICT);

        assertMatrixEquals("Multiplication with NaN", new Matrix4(
                2.0,  0,      0,  -179.5,
                0,    1.5,    0,   -89.5,
                0,    0,    NaN,     NaN,
                0,    0,      0,     1), m1.multiply(m2), STRICT);
    }

    /**
     * Tests the accuracy of a chain of matrix operations.
     *
     * @throws NoninvertibleMatrixException should never happen.
     */
    @Test
    public void testAccuracy() throws NoninvertibleMatrixException {
        final double parisMeridian = 2 + (20 + 13.82/60)/60;            // Paris meridian: 2°20'13.82"
        final double toRadians = StrictMath.PI / 180;
        /*
         * Grads to degrees with a Prime Meridian shift
         * and a random conversion factor for z values.
         */
        final Matrix4 step1 = new Matrix4(
                0.9,  0,    0,    parisMeridian,
                0,    0.9,  0,    0,
                0,    0,    0.8,  0,                                    // Random conversion factor for z values.
                0,    0,    0,    1);
        /*
         * Degrees to radians with swapping of (longitude, latitude) axes
         * and a conversion factor of z values from feet to metres.
         */
        final Matrix4 step2 = new Matrix4(
                0, toRadians, 0, 0,
                toRadians, 0, 0, 0,
                0, 0, 0.3048, 0,
                0, 0, 0, 1);
        /*
         * Converse of the above operations.
         */
        final MatrixSIS step3 = step2.multiply(step1).inverse();
        /*
         * Concatenate everything, which should go back to the identity transform.
         * Note that the 'isIdentity()' test fail if the double-double arithmetic is
         * disabled, because some scale factors will be 0.9999999999999999 instead of 1.
         */
        final MatrixSIS result = step3.multiply(step2).multiply(step1);
        assertTrue("isIdentity()", result.isIdentity());
    }
}
