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

import java.util.EnumMap;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.parameter.InvalidParameterValueException;
import org.apache.sis.internal.referencing.Formulas;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.referencing.operation.matrix.Matrix2;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
import org.apache.sis.referencing.operation.transform.ContextualParameters;
import org.apache.sis.parameter.Parameters;
import org.apache.sis.measure.Latitude;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.Workaround;

import static java.lang.Math.*;
import static org.apache.sis.internal.referencing.provider.SatelliteTracking.*;


/**
 * <cite>Satellite-Tracking</cite> projection.
 * This projection has been developed in 1977 by Snyder and has no associated EPSG code.
 * This projection is neither conformal or equal-area, but has the property that ground tracks
 * for satellites orbiting the Earth with the same orbital parameters are shown as straight lines
 * on the map. Other properties are (Snyder 1987):
 *
 * <ul>
 *   <li>All meridians are equally spaced straight lines.
 *       They are parallel on cylindrical form and converging to a common point on conical form.</li>
 *   <li>All parallels are straight but unequally spaced.
 *       They are parallel on cylindrical form and are concentric circular arcs on conical form.</li>
 *   <li>Conformality occurs along two chosen parallels. Scale is correct along one of these parameters
 *       on the conical form and along both on the cylindrical form.</li>
 * </ul>
 *
 * <h2>Limitations</h2>
 * This map projection supports only circular orbits. The Earth is assumed spherical.
 * Areas close to poles can not be mapped.
 *
 * <h2>References</h2>
 * John P. Snyder., 1987. <u>Map Projections - A Working Manual</u>
 * chapter 28: <cite>Satellite-tracking projections</cite>.
 *
 * @author  Matthieu Bastianelli (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.1
 * @since   1.1
 * @module
 */
public class SatelliteTracking extends NormalizedProjection {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = -209787336760184649L;

    /**
     * Sines and cosines of inclination between the plane of the Earth's Equator and the plane
     * of the satellite orbit. The angle variable name is <var>i</var> in Snyder's book.
     *
     * @see org.apache.sis.internal.referencing.provider.SatelliteTracking#SATELLITE_ORBIT_INCLINATION
     */
    private final double cos_i, sin_i, cos2_i;

    /**
     * Ratio of satellite orbital period (P₂) over ascending node period (P₁).
     *
     * @see org.apache.sis.internal.referencing.provider.SatelliteTracking#SATELLITE_ORBITAL_PERIOD
     * @see org.apache.sis.internal.referencing.provider.SatelliteTracking#ASCENDING_NODE_PERIOD
     */
    private final double p2_on_p1;

    /**
     * Coefficients for the Conic Satellite-Tracking Projection.
     * Those values are {@link Double#NaN} in the cylindrical case.
     */
    private final double n, s0;

    /**
     * {@code true} if this projection is conic, or {@code false} if cylindrical or unknown.
     */
    private final boolean isConic;

    /**
     * A bound of the [−n⋅π … n⋅π] range, which is the valid range of  θ = n⋅λ  values.
     * Some (not all) θ values need to be shifted inside that range before to use them
     * in trigonometric functions.
     *
     * @see Initializer#boundOfScaledLongitude(DoubleDouble)
     */
    private final double θ_bound;

    /**
     * Work around for RFE #4093999 in Sun's bug database ("Relax constraint on
     * placement of this()/super() call in constructors").
     */
    @Workaround(library = "JDK", version = "1.8")
    static Initializer initializer(final OperationMethod method, final Parameters parameters) {
        final EnumMap<NormalizedProjection.ParameterRole, ParameterDescriptor<Double>> roles = new EnumMap<>(NormalizedProjection.ParameterRole.class);
        roles.put(NormalizedProjection.ParameterRole.CENTRAL_MERIDIAN, CENTRAL_MERIDIAN);
        roles.put(ParameterRole.LATITUDE_OF_CONFORMAL_SPHERE_RADIUS, LATITUDE_OF_ORIGIN);
        return new Initializer(method, parameters, roles, null);
    }

    /**
     * Creates a Satellite Tracking projection from the given parameters.
     *
     * @param  method      description of the projection parameters.
     * @param  parameters  the parameter values of the projection to create.
     * @throws InvalidParameterValueException if some parameters have incompatible values.
     */
    public SatelliteTracking(final OperationMethod method, final Parameters parameters) {
        this(initializer(method, parameters));
    }

    /**
     * Work around for RFE #4093999 in Sun's bug database
     * ("Relax constraint on placement of this()/super() call in constructors").
     */
    private SatelliteTracking(final Initializer initializer) {
        super(initializer, null);
        final double φ0 = toRadians(initializer.getAndStore(LATITUDE_OF_ORIGIN));
        final double φ1 = toRadians(initializer.getAndStore(STANDARD_PARALLEL_1));
        final double φ2 = toRadians(initializer.getAndStore(STANDARD_PARALLEL_2));
        final double i  = toRadians(initializer.getAndStore(SATELLITE_ORBIT_INCLINATION));
        p2_on_p1 =                  initializer.getAndStore(SATELLITE_ORBITAL_PERIOD) /
                                    initializer.getAndStore(ASCENDING_NODE_PERIOD);
        /*
         * Symbols from Snyder used in the constructor:
         *
         *   i  =  angle of inclination between the plane of Earth Equator and the plane of satellite orbit.
         *   P₁ =  length of Earth's rotation with respect to precessed ascending node.
         *   P₂ =  time required for revolution of the satellite.
         *   φ₁ =  standard parallel.
         *   φ₂ =  second standard parallel. Equals to -φ₁ in the cylindrical case.
         *   F₁ =  angle on the globe between the ground-track and the meridian at latitude φ₁.
         *   n  :  used for conic projection only.
         *   s₀ :  user for conic projection only.
         *
         * Next terms below are common to both cylindrical and conic sattelite tracking projections.
         */
        sin_i   = sin(i);
        cos_i   = cos(i);
        cos2_i  = cos_i * cos_i;
        isConic = Math.abs(φ2 + φ1) > ANGULAR_TOLERANCE;
        final double cosφ1   = cos(φ1);
        final double cos2_φ1 = cosφ1 * cosφ1;
        /*
         * Some terms will be stored as scale factor and offset applied by matrix before projection
         * (normalization) and after projection (denormalization).  Those factors will be different
         * for cylindric and conic projections.
         */
        final MatrixSIS denormalize = context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
        if (isConic) {
            final double sinφ1 = sin(φ1);
            final double L0 =  L(sin(φ0), LATITUDE_OF_ORIGIN);
            final double L1 =  L(sinφ1,   STANDARD_PARALLEL_1);
            final double F1 =  F(cos2_φ1, STANDARD_PARALLEL_1);
            /*
             * For conic projection with one standard parallel (φ₁ = φ₂), the general case implemented by
             * equation 28-10 become indeterminate. Equation 28-17 below resolves that indetermination.
             * If furthermore φ₁ is equal to the upper tracking limit π-i, that equation 28-17 could be
             * simplified by equation 28-18:
             *
             *     f = p2_on_p1 * cos_i - 1;
             *     n = sin_i / (f*f);                                       // Snyder equation 28-18.
             *
             * However since equation 28-17 still work, we keep it for avoiding discontinuity.
             */
            if (abs(φ2 - φ1) < ANGULAR_TOLERANCE) {
                n = sinφ1 * (p2_on_p1 * (2*cos2_i - cos2_φ1) - cos_i)
                          / (p2_on_p1 * (           cos2_φ1) - cos_i);      // Equation 28-17.
            } else {
                final double cosφ2 = cos(φ2);
                final double F2 = F(cosφ2*cosφ2, STANDARD_PARALLEL_2);
                final double L2 = L(sin(φ2),     STANDARD_PARALLEL_2);
                n = (F2 - F1) / (L2 - L1);                                  // Snyder equation 28-10.
            }
            s0 = F1 - n*L1;                                                 // Snyder equation 28-11.
            final double ρf = cosφ1 * sin(F1) / n;                          // Part of Snyder 28-12 fraction.
            final double ρ0 = ρf / sin(n*L0 + s0);                          // Remaining of Snyder 28-12 without R.
            if (!Double.isFinite(ρf) || ρf == 0) {
                throw invalid(STANDARD_PARALLEL_1);
            }
            final MatrixSIS normalize = context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION);
            normalize  .convertAfter (0,  n,  null);
            denormalize.convertBefore(0, +ρf, null);
            denormalize.convertBefore(1, -ρf, ρ0);
            θ_bound = initializer.boundOfScaledLongitude(n);
        } else {
            /*
             * Cylindrical projection case. The equations are (ignoring R and λ₀):
             *
             *     x   =  λ⋅cosφ₁
             *     y   =  L⋅cosφ₁/F₁′  where  L depends on φ but F₁′ is constant.
             *     F₁′ =  tan(F₁)
             *
             * The cosφ₁ (for x at dimension 0) and cosφ₁/F₁′ (for y at dimension 1) factors are computed
             * in advance and stored below. The remaining factor to compute in transform(…) method is L.
             */
            n = s0 = θ_bound = Double.NaN;
            final double cotF = sqrt(cos2_φ1 - cos2_i) / (p2_on_p1*cos2_φ1 - cos_i);    // Cotangente of F₁.
            denormalize.convertBefore(0, cosφ1,      null);
            denormalize.convertBefore(1, cosφ1*cotF, null);
            if (!Double.isFinite(cotF) || cotF == 0) {
                throw invalid(STANDARD_PARALLEL_1);
            }
        }
    }

    /**
     * Returns the names of additional internal parameters which need to be taken in account when
     * comparing two {@code SatelliteTracking} projections or formatting them in debug mode.
     */
    @Override
    final String[] getInternalParameterNames() {
        return new String[] {"i", "P₂∕P₁"};
    }

    /**
     * Returns the values of additional internal parameters which need to be taken in account when
     * comparing two {@code SatelliteTracking} projections or formatting them in debug mode.
     */
    @Override
    final double[] getInternalParameterValues() {
        return new double[] {
            (cos_i < PI/4) ? acos(cos_i) : asin(sin_i),
            p2_on_p1
        };
    }

    /**
     * Computes the F₁ or F₂ coefficient using Snyder equation 28-9. Note that this is the same equation
     * than F₁′ in above cylindrical case, but with the addition of arc-tangent. This value is constant
     * after construction time.
     *
     * @param  cos2_φ  square of cosine of φ₁ or φ₂.
     * @param  source  description of φ argument. Used for error message only.
     * @return F coefficient for the given φ latitude.
     */
    private double F(final double cos2_φ, final ParameterDescriptor<Double> source) {
        final double F = atan((p2_on_p1*cos2_φ - cos_i) / sqrt(cos2_φ - cos2_i));
        if (Double.isFinite(F)) {
            return F;
        }
        throw invalid(source);
    }

    /**
     * Computes the L₀, L₁ or L₂ coefficient using Snyder equation 28-2a to 28-4a.
     * This value is constant after construction time.
     *
     * @param  sinφ    sine of φ₀, φ₁ or φ₂.
     * @param  source  description of φ argument. Used for error message only.
     * @return L coefficient for the given φ latitude.
     */
    private double L(final double sinφ, final ParameterDescriptor<Double> source) {
        final double λp = -asin(sinφ / sin_i);                      // λ′ in Snyder equation 28-2a.
        final double L = atan(tan(λp) * cos_i) - p2_on_p1 * λp;     // Snyder equation 28-3a and 28-4a.
        if (Double.isFinite(L)) {
            return L;
        }
        throw invalid(source);
    }

    /**
     * Returns an exception for a latitude parameter out of range.
     * The range is assumed given by satellite orbit inclination.
     *
     * @param  source  description of invalid φ argument.
     */
    private InvalidParameterValueException invalid(final ParameterDescriptor<Double> source) {
        final String name  =     source.getName().getCode();
        final double value =     context.doubleValue(source);
        final double limit = abs(context.doubleValue(SATELLITE_ORBIT_INCLINATION));
        return new InvalidParameterValueException(Errors.format(Errors.Keys.ValueOutOfRange_4,
                                                  name, -limit, limit, new Latitude(value)), name, value);
    }

    /**
     * Converts the specified (λ,φ) coordinate (units in radians) and stores the result in {@code dstPts}.
     * In addition, opportunistically computes the projection derivative if {@code derivate} is {@code true}.
     * The results must be multiplied by the denormalization matrix before to get linear distances.
     *
     * <p>The <var>y</var> axis lies along the central meridian λ₀, <var>y</var> increasing northerly, and
     * <var>x</var> axis intersects perpendicularly at latitude of origin φ₀, <var>x</var> increasing easterly.</p>
     *
     * @return the matrix of the projection derivative at the given source position,
     *         or {@code null} if the {@code derivate} argument is {@code false}.
     * @throws ProjectionException if the coordinates can not be converted.
     */
    @Override
    public Matrix transform(final double[] srcPts, final int srcOff,
                            final double[] dstPts, final int dstOff,
                            final boolean derivate) throws ProjectionException
    {
        final double φ         = srcPts[srcOff + 1];
        final double sinφ_sini = sin(φ) / sin_i;
              double λpm       = -asin(sinφ_sini);          // Initialized to λ′ (Snyder equation 28-2), to be modified later.
        final double tanλp     = tan(λpm);                  // tan(λ′), saved because also used in derivative computation.
        final double λt        = atan(tanλp * cos_i);       // λₜ in Snyder equation 28-3.
        /*
         * The (x,y) coordinates below are all is needed for the cylindrical case.
         * With R and cosφ₁ omitted because multiplied outside this method:
         *
         *     x = λ
         *     y = L    with L = λₜ − (P₂/P₁)λ′     (Snyder equation 28-6)
         *
         * Only in conic case, we need to continue with some additional computation.
         * Note that λpm is NaN if latitude φ is closer to pole than tracking limit.
         */
        double x = srcPts[srcOff];
        double y = λt - p2_on_p1 * λpm;
        if (isConic) {
            x = wraparoundScaledLongitude(x, θ_bound);
            λpm = n*y + s0;                     // Use this variable for a new purpose. Needed for derivative.
            if ((Double.doubleToRawLongBits(λpm) ^ Double.doubleToRawLongBits(n)) < 0) {
                /*
                 * if λpm does not have the sign than n, the (x,y) values computed below would suddenly
                 * change their sign. The y values lower or greater (depending of n sign) than -s0/n can
                 * not be plotted. Snyder suggests to use another projection if cosmetic output is wanted.
                 * For now, we just set the results to NaN (meaning "no result", which is not the same than
                 * TransformException which means that a result exists but can not be computed).
                 */
                λpm = Double.NaN;
            }
            final double iρ = sin(λpm);         // Inverse of ρ and without the ρf = cos(φ₁)⋅sin(F₁)/n part.
            y = cos(x) / iρ;                    // x already multiplied by n (was done by normalization matrix).
            x = sin(x) / iρ;                    // Must be last.
        }
        if (dstPts != null) {
            dstPts[dstOff    ] = x;
            dstPts[dstOff + 1] = y;
        }
        if (!derivate) {
            return null;
        }
        /*
         * Create a derivative matrix initializez with ∂L/∂φ. For cylindrical case where y = L (in this method),
         * this is all we need to do. For the conic case, we need to multiply the last column ∂x/∂L and ∂y/∂L.
         */
        final Matrix2 d = new Matrix2();
        d.m11 = ((cos(φ) / sin_i) / sqrt(1 - sinφ_sini*sinφ_sini))
              * (p2_on_p1 - ((1 + tanλp*tanλp)*cos_i/(1 + λt*λt)));
        if (isConic) {
            final double dρ_dφ = -n / tan(λpm);
            d.m00  = +y;                            // ∂x/∂λ
            d.m10  = -x;                            // ∂y/∂λ
            d.m01  =  x * dρ_dφ * d.m11;            // ∂x/∂φ  =  ∂x/∂L ⋅ ∂L/∂φ
            d.m11 *=  y * dρ_dφ;                    // ∂y/∂φ  =  ∂y/∂L ⋅ ∂L/∂φ
        }
        return d;
    }

    /**
     * Transforms the specified (<var>x</var>,<var>y</var>) coordinates
     * and stores the result in {@code dstPts} (angles in radians).
     *
     * @throws ProjectionException if the coordinates can not be converted.
     */
    @Override
    protected void inverseTransform(final double[] srcPts, final int srcOff,
                                    final double[] dstPts, final int dstOff) throws ProjectionException
    {
        double x = srcPts[srcOff];
        double L = srcPts[srcOff + 1];                  // Multiplication e.g. by F₁′/(R⋅cosφ₁) already done.
        if (isConic) {
            final double ρ = copySign(hypot(x,L), n);
            x = atan(x / L);                            // Undefined if x = y = 0.
            L = (asin(1 / ρ) - s0) / n;                 // Equation 28-26 in Snyder with R=1.
        }
        /*
         * Approximation of the latitude associated with L coefficient by applying Newton-Raphson method.
         * Equations 28-24, 28-25 and then 28-22 in Snyder's book.
         */
        final double ic  = 1 / cos2_i;
        final double pc = p2_on_p1 * cos_i;
        double λp = -PI/2, Δλp;
        int iter = Formulas.MAXIMUM_ITERATIONS;
        do {
            if (--iter < 0) {
                throw new ProjectionException(Resources.format(Resources.Keys.NoConvergence));
            }
            final double A   = tan(L + p2_on_p1 * λp) / cos_i;          // Snyder equation 28-24.
            final double A2  = A*A;
            Δλp = (atan(A) - λp) / (1 - pc*((A2 + ic) / (A2 + 1)));     // Snyder equation 28-25.
            λp += Δλp;
        } while (abs(Δλp) >= ANGULAR_TOLERANCE);
        dstPts[dstOff  ] = x;
        dstPts[dstOff+1] = -asin(sin(λp) * sin_i);                      // Snyder equation 28-22.
    }
}
