/*
 * 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.transform;

import java.util.Arrays;
import java.io.Serializable;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.MathTransform1D;
import org.opengis.referencing.operation.TransformException;
import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.apache.sis.referencing.operation.matrix.Matrix1;
import org.apache.sis.internal.referencing.provider.Interpolation1D;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.internal.util.Numerics;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.resources.Errors;


/**
 * A transform that performs linear interpolation between values.
 * The transform is invertible if, and only if, the values are in increasing order.
 *
 * <p>If desired values in decreasing order can be supported by inverting the sign of all values,
 * then concatenating this transform with a transform that multiply all output values by -1.</p>
 *
 * <div class="section">Extrapolation</div>
 * If an input value is outside the expected range of values, this class extrapolates using the
 * slope defined by the two first points if the requested value is before, or the slope defined
 * by the two last points if the requested value is after.   In other words, extrapolations are
 * computed using only values at the extremum where extrapolation happen. This rule causes less
 * surprising behavior when computing a data cube envelope, which may need extrapolation by 0.5
 * pixel before the first value or after the last value.
 *
 * <div class="note"><b>Example:</b>
 * if a vertical dimension is made of slices at y₀=5, y₁=10, y₂=100 and y₃=250 meters, then linear
 * interpolation at 0.5 is 7.5 meters and extrapolation at -0.5 is expected to give 2.5 meters.</div>
 *
 * @author  Johann Sorel (Geomatys)
 * @author  Rémi Maréchal (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 *
 * @see MathTransforms#interpolate(double[], double[])
 *
 * @since 0.7
 * @module
 */
final class LinearInterpolator1D extends AbstractMathTransform1D implements Serializable {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = -5025693608589996896L;

    /**
     * The sequence values specified at construction time.
     * Must contain at least 2 values.
     */
    private final double[] values;

    /**
     * If the transform is invertible, the inverse. Otherwise {@code null}.
     * The transform is invertible only if values are in increasing order.
     */
    private final MathTransform1D inverse;

    /**
     * Creates a new transform which will interpolate in the given table of values.
     * The inputs are {0, 1, … , <var>N</var>} where <var>N</var> is length of output values.
     *
     * <p>This constructor assumes that the {@code values} array has already been cloned,
     * so it will not clone it again. That array shall contain at least two values.</p>
     *
     * @param values  the <var>y</var> values in <var>y=f(x)</var> where <var>x</var> = {0, 1, … , {@code values.length-1}}.
     */
    private LinearInterpolator1D(final double[] values) {
        this.values = values;                           // Cloning this array is caller's responsibility.
        double last = values[0];
        for (int i=1; i<values.length; i++) {
            if (!(last <= (last = values[i]))) {        // Use '!' for catching NaN values.
                inverse = null;                         // Transform is not reversible.
                return;
            }
        }
        inverse = new Inverse(this);
    }

    /**
     * Creates a transform for the given values. This method returns an affine transform instead than an
     * interpolator if the given values form a series with a constant increment. The given array shall
     * contain at least two values.
     *
     * @param  values  a <strong>copy</strong> of the user-provided values. This array may be modified.
     */
    private static MathTransform1D create(final double[] values) {
        final int n = values.length - 1;
        final double offset = values[0];
        final double slope = (values[n] - offset) / n;
        final double as = Math.abs(slope);
        /*
         * If the increment between values is constant (with a small tolerance factor),
         * return a one-dimensional affine transform instead than an interpolator.
         * We need to perform this check before the sign reversal applied after this loop.
         */
        double value;
        int i = 0;
        do {
            if (++i >= n) {
                return LinearTransform1D.create(slope, offset);
            }
            value = values[i];
        } while (Numerics.epsilonEqual(value, offset + slope*i,     // TODO: use Math.fma with JDK9.
                        Math.max(Math.abs(value), as) * Numerics.COMPARISON_THRESHOLD));
        /*
         * If the values are in decreasing order, reverse their sign so we get increasing order.
         * We will multiply the results by -1 after the transformation.
         */
        final boolean isReverted = (slope < 0);
        if (isReverted) {
            for (i=0; i <= n; i++) {
                values[i] = -values[i];
            }
        }
        MathTransform1D tr = new LinearInterpolator1D(values);
        if (isReverted) {
            tr = new ConcatenatedTransformDirect1D(tr, LinearTransform1D.NEGATE);
        }
        return tr;
    }

    /**
     * Creates a <i>y=f(x)</i> transform for the given preimage (<var>x</var>) and values (<var>y</var>).
     * See {@link MathTransforms#interpolate(double[], double[])} javadoc for more information.
     */
    static MathTransform1D create(final double[] preimage, final double[] values) {
        final int length;
        if (preimage == null) {
            if (values == null) {
                return IdentityTransform1D.INSTANCE;
            }
            length = values.length;
        } else {
            length = preimage.length;
            if (values != null && values.length != length) {
                throw new IllegalArgumentException(Errors.format(Errors.Keys.MismatchedArrayLengths));
            }
        }
        switch (length) {
            case 0: throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1, (preimage != null) ? "preimage" : "values"));
            case 1: return LinearTransform1D.constant((preimage != null) ? preimage[0] : Double.NaN, (values != null) ? values[0] : Double.NaN);
        }
        /*
         * A common usage of this 'create' method is for creating a "gridToCRS" transform from grid coordinates
         * to something else, in which case the preimage array is null. In the less frequent case where preimage
         * is non-null, we first convert from preimage to indices, then from indices to y values.
         */
        MathTransform1D tr = null;
        if (values != null) {
            tr = create(values.clone());
        }
        if (preimage != null) {
            final MathTransform1D indexToValues = tr;
            try {
                tr = create(preimage.clone()).inverse();                                // preimageToIndex transform.
            } catch (NoninvertibleTransformException e) {
                throw new IllegalArgumentException(Resources.format(Resources.Keys.NonMonotonicSequence_1, "preimage"), e);
            }
            if (indexToValues != null) {
                tr = MathTransforms.concatenate(tr, indexToValues);
            }
        }
        return tr;
    }

    /**
     * Returns the parameter descriptors for this math transform.
     */
    @Override
    public ParameterDescriptorGroup getParameterDescriptors() {
        return Interpolation1D.PARAMETERS;
    }

    /**
     * Returns the parameter values for this math transform.
     */
    @Override
    public ParameterValueGroup getParameterValues() {
        final ParameterValueGroup p = getParameterDescriptors().createValue();
        p.parameter("values").setValue(values);
        return p;
    }

    /**
     * Returns {@code true} if this transform is the identity transform. This method should never returns {@code true}
     * since we verified the inputs in the {@code create(…)} method. We nevertheless verify as a paranoiac safety.
     */
    @Override
    public boolean isIdentity() {
        for (int i=0; i<values.length; i++) {
            if (values[i] != i) return false;
        }
        return true;
    }

    /**
     * Combines {@link #transform(double)}, {@link #derivative(double)} in a single method call.
     */
    @Override
    public Matrix transform(final double[] srcPts, final int srcOff,
                            final double[] dstPts, final int dstOff,
                            final boolean derivate) throws TransformException
    {
        double x = srcPts[srcOff];
        final double y, d;
        if (x >= 0) {
            final int i = (int) x;
            final int n = values.length - 1;
            if (i < n) {
                x -= i;
                final double y0 = values[i  ];
                final double y1 = values[i+1];
                y = y0 * (1-x) + y1 * x;
                d = y1 - y0;
            } else {
                // x is after the last available value.
                final double y1 = values[n];
                d = y1 - values[n-1];
                y = (x - n) * d + y1;
            }
        } else {
            // x is before the first available value.
            final double y0 = values[0];
            d = values[1] - y0;
            y = x * d + y0;
        }
        if (dstPts != null) {
            dstPts[dstOff] = y;
        }
        return derivate ? new Matrix1(d) : null;
    }

    /**
     * Interpolates a <var>y</var> values for the given <var>x</var>.
     * The given <var>x</var> value should be between 0 to {@code values.length - 1} inclusive.
     * If the given input value is outside that range, then the output value will be extrapolated.
     */
    @Override
    public double transform(double x) {
        if (x >= 0) {
            final int i = (int) x;
            final int n = values.length - 1;
            if (i < n) {
                x -= i;
                return values[i] * (1-x) + values[i+1] * x;
            } else {
                // x is after the last available value.
                final double y1 = values[n];
                return (x - n) * (y1 - values[n-1]) + y1;
            }
        } else {
            // x is before the first available value.
            final double y0 = values[0];
            return x * (values[1] - y0) + y0;
        }
    }

    /**
     * Returns the derivative of <var>y</var> for the given <var>x</var>.
     * Note: for each segment, the derivative is considered constant between
     * <var>x</var> inclusive and <var>x+1</var> exclusive.
     */
    @Override
    public double derivative(final double x) {
        final int i = Math.max(0, Math.min(values.length - 2, (int) x));
        return values[i+1] - values[i];
    }

    /**
     * Returns the inverse of this transform, or throw an exception if there is no inverse.
     */
    @Override
    public MathTransform1D inverse() throws NoninvertibleTransformException {
        return (inverse != null) ? inverse : super.inverse();
    }

    /**
     * The inverse of the enclosing {@link LinearInterpolator1D}. Given a <var>y</var> value, this class performs
     * a bilinear search for locating the lower and upper <var>x</var> values as integers, then interpolates the
     * <var>x</var> real value.
     */
    private static final class Inverse extends AbstractMathTransform1D.Inverse implements MathTransform1D, Serializable {
        /**
         * For cross-version compatibility.
         */
        private static final long serialVersionUID = -5112948223332095009L;

        /**
         * The enclosing transform.
         */
        private final LinearInterpolator1D forward;

        /**
         * Creates a new inverse transform.
         */
        Inverse(final LinearInterpolator1D forward) {
            this.forward = forward;
        }

        /**
         * Returns the inverse of this math transform.
         */
        @Override
        public MathTransform1D inverse() {
            return forward;
        }

        /**
         * Combines {@link #transform(double)}, {@link #derivative(double)} in a single method call.
         * The intent is to avoid to call {@link Arrays#binarySearch(double[], double)} twice for the
         * same value.
         */
        @Override
        public Matrix transform(final double[] srcPts, final int srcOff,
                                final double[] dstPts, final int dstOff,
                                final boolean derivate) throws TransformException
        {
            final double d, x, y = srcPts[srcOff];
            final double[] values = forward.values;
            int i = Arrays.binarySearch(values, y);
            if (i >= 0) {
                x = i;
                i = Math.max(1, Math.min(values.length - 1, i));
                d = values[i] - values[i-1];
            } else {
                i = ~i;
                if (i >= 1) {
                    if (i < values.length) {
                        final double y0 = values[i-1];
                        x = (y - y0) / (d = values[i] - y0) + (i-1);
                    } else {
                        // y is after the last available value.
                        final int n = values.length - 1;
                        final double y1 = values[n];
                        x = (y - y1) / (d = y1 - values[n-1]) + n;
                    }
                } else {
                    // y is before the first available value.
                    final double y0 = values[0];
                    x = (y - y0) / (d = values[1] - y0);
                }
            }
            if (dstPts != null) {
                dstPts[dstOff] = x;
            }
            return derivate ? new Matrix1(1/d) : null;
        }

        /**
         * Locates by bilinear search and interpolates the <var>x</var> value for the given <var>y</var>.
         */
        @Override
        public double transform(final double y) {
            final double[] values = forward.values;
            int i = Arrays.binarySearch(values, y);
            if (i >= 0) {
                return i;
            } else {
                i = ~i;
                if (i >= 1) {
                    if (i < values.length) {
                        final double y0 = values[i-1];
                        return (y - y0) / (values[i] - y0) + (i-1);
                    } else {
                        // y is after the last available value.
                        final int n = values.length - 1;
                        final double y1 = values[n];
                        return (y - y1) / (y1 - values[n-1]) + n;
                    }
                } else {
                    // y is before the first available value.
                    final double y0 = values[0];
                    return (y - y0) / (values[1] - y0);
                }
            }
        }

        /**
         * Returns the derivative at the given <var>y</var> value.
         */
        @Override
        public double derivative(final double y) {
            final double[] values = forward.values;
            int i = Arrays.binarySearch(values, y);
            if (i < 0) {
                i = ~i;
            }
            i = Math.max(1, Math.min(values.length - 1, i));
            return 1 / (values[i] - values[i-1]);
        }
    }

    /**
     * Computes a hash code value for this transform.
     */
    @Override
    protected int computeHashCode() {
        return super.computeHashCode() ^ Arrays.hashCode(values);
    }

    /**
     * Compares this transform with the given object for equality.
     */
    @Override
    public boolean equals(final Object object, final ComparisonMode mode) {
        if (super.equals(object, mode)) {
            // No need to compare 'slope' because it is computed from 'values'.
            return Arrays.equals(values, ((LinearInterpolator1D) object).values);
        }
        return false;
    }
}
