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

import java.util.Map;
import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlTransient;
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.opengis.referencing.datum.Datum;
import org.opengis.referencing.datum.GeodeticDatum;
import org.opengis.referencing.datum.VerticalDatum;
import org.opengis.referencing.datum.TemporalDatum;
import org.opengis.referencing.datum.EngineeringDatum;
import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.crs.DerivedCRS;
import org.opengis.referencing.crs.GeodeticCRS;
import org.opengis.referencing.crs.VerticalCRS;
import org.opengis.referencing.crs.TemporalCRS;
import org.opengis.referencing.crs.ProjectedCRS;
import org.opengis.referencing.crs.EngineeringCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.cs.VerticalCS;
import org.opengis.referencing.cs.TimeCS;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.opengis.geometry.MismatchedDimensionException;
import org.apache.sis.referencing.AbstractIdentifiedObject;
import org.apache.sis.referencing.operation.DefaultConversion;
import org.apache.sis.referencing.cs.AbstractCS;
import org.apache.sis.referencing.cs.AxesConvention;
import org.apache.sis.referencing.cs.CoordinateSystems;
import org.apache.sis.xml.bind.referencing.SC_SingleCRS;
import org.apache.sis.xml.bind.referencing.SC_DerivedCRSType;
import org.apache.sis.xml.bind.referencing.CS_CoordinateSystem;
import org.apache.sis.referencing.privy.ReferencingUtilities;
import org.apache.sis.referencing.privy.WKTUtilities;
import org.apache.sis.referencing.privy.WKTKeywords;
import org.apache.sis.io.wkt.Convention;
import org.apache.sis.io.wkt.Formatter;
import org.apache.sis.util.ComparisonMode;

// Specific to the geoapi-3.1 and geoapi-4.0 branches:
import org.opengis.referencing.datum.ParametricDatum;
import org.opengis.referencing.crs.ParametricCRS;
import org.opengis.referencing.cs.ParametricCS;


/**
 * A coordinate reference system that is defined by its coordinate {@linkplain DefaultConversion conversion}
 * from another CRS (not by a {@linkplain org.apache.sis.referencing.datum.AbstractDatum datum}). {@code DerivedCRS}
 * cannot be {@linkplain DefaultProjectedCRS projected CRS} themselves, but may be derived from a projected CRS
 * (for example in order to use a {@linkplain org.apache.sis.referencing.cs.DefaultPolarCS polar coordinate system}).
 *
 * <p>A {@code DerivedCRS} instance may also implement one of the interfaces listed below,
 * provided that the conditions in the right column are met (derived from ISO 19162):</p>
 *
 * <table class="sis">
 *   <caption>Derived CRS types</caption>
 *   <tr><th>Type</th>                   <th>Conditions</th></tr>
 *   <tr><td>{@link GeodeticCRS}</td>    <td>Base CRS is also a {@code GeodeticCRS} and is associated to the same type of coordinate system.</td></tr>
 *   <tr><td>{@link VerticalCRS}</td>    <td>Base CRS is also a {@code VerticalCRS} and coordinate system is a {@code VerticalCS}.</td></tr>
 *   <tr><td>{@link TemporalCRS}</td>    <td>Base CRS is also a {@code TemporalCRS} and coordinate system is a {@code TimeCS}.</td></tr>
 *   <tr><td>{@link ParametricCRS}</td>  <td>Base CRS is also a {@code ParametricCRS} and coordinate system is a {@code ParametricCS}.</td></tr>
 *   <tr><td>{@link EngineeringCRS}</td> <td>Base CRS is a {@code GeodeticCRS}, {@code ProjectedCRS} or {@code EngineeringCRS}.</td></tr>
 * </table>
 *
 * Those specialized subclasses can be inferred automatically by the {@link #create create(…)} static method.
 * Alternatively, users can create their own {@code DefaultDerivedCRS} subclass implementing the desired interface.
 *
 * <h2>Immutability and thread safety</h2>
 * This base class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
 * given to the constructor are also immutable. Most SIS subclasses and related classes are immutable under similar
 * conditions. This means that unless otherwise noted in the javadoc, {@code GeneralDerivedCRS} instances created
 * using only SIS factories and static constants can be shared by many objects and passed between threads without
 * synchronization.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @author  Johann Sorel (Geomatys)
 * @version 1.5
 *
 * @see org.apache.sis.referencing.factory.GeodeticAuthorityFactory#createDerivedCRS(String)
 *
 * @since 0.6
 */
@XmlType(name="DerivedCRSType", propOrder = {
    "baseCRS",
    "type",
    "coordinateSystem"
})
@XmlRootElement(name = "DerivedCRS")
public class DefaultDerivedCRS extends AbstractDerivedCRS<Conversion> implements DerivedCRS {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = -8149602276542469876L;

    /**
     * Creates a derived CRS from a defining conversion.
     * The properties given in argument follow the same rules as for the
     * {@linkplain AbstractCRS#AbstractCRS(Map, CoordinateSystem) super-class constructor}.
     * The following table is a reminder of main (not all) properties:
     *
     * <table class="sis">
     *   <caption>Recognized properties (non exhaustive list)</caption>
     *   <tr>
     *     <th>Property name</th>
     *     <th>Value type</th>
     *     <th>Returned by</th>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
     *     <td>{@link org.opengis.metadata.Identifier} or {@link String}</td>
     *     <td>{@link #getName()}</td>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#ALIAS_KEY}</td>
     *     <td>{@link org.opengis.util.GenericName} or {@link CharSequence} (optionally as array)</td>
     *     <td>{@link #getAlias()}</td>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
     *     <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td>
     *     <td>{@link #getIdentifiers()}</td>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#DOMAINS_KEY}</td>
     *     <td>{@link org.opengis.referencing.ObjectDomain} (optionally as array)</td>
     *     <td>{@link #getDomains()}</td>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#REMARKS_KEY}</td>
     *     <td>{@link org.opengis.util.InternationalString} or {@link String}</td>
     *     <td>{@link #getRemarks()}</td>
     *   </tr>
     * </table>
     *
     * The supplied {@code conversion} argument shall <strong>not</strong> includes the operation steps
     * for performing {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes unit
     * conversions and change of axis order} since those operations will be inferred by this constructor.
     *
     * @param  properties  the properties to be given to the new derived CRS object.
     * @param  baseCRS     coordinate reference system to base the derived CRS on.
     * @param  conversion  the defining conversion from a {@linkplain AxesConvention#NORMALIZED normalized}
     *                     base to a normalized derived CRS.
     * @param  derivedCS   the coordinate system for the derived CRS. The number of axes must match
     *                     the target dimension of the {@code baseToDerived} transform.
     * @throws MismatchedDimensionException if the source and target dimensions of {@code baseToDerived}
     *         do not match the dimensions of {@code base} and {@code derivedCS} respectively.
     *
     * @see #create(Map, SingleCRS, Conversion, CoordinateSystem)
     */
    protected DefaultDerivedCRS(final Map<String,?>    properties,
                                final SingleCRS        baseCRS,
                                final Conversion       conversion,
                                final CoordinateSystem derivedCS)
            throws MismatchedDimensionException
    {
        super(properties, baseCRS, conversion, derivedCS);
    }

    /**
     * Creates a new CRS derived from the specified one, but with different axis order or unit.
     * This is for implementing the {@link #createSameType(AbstractCS)} method only.
     */
    DefaultDerivedCRS(final DefaultDerivedCRS original, final AbstractCS derivedCS) {
        super(original, derivedCS);
    }

    /**
     * Creates a derived CRS from a math transform. The given {@code MathTransform} shall transform coordinate
     * values specifically from the {@code baseCRS} to {@code this} CRS (optionally with an interpolation CRS);
     * there is no consideration about <q>normalized CRS</q> in this constructor.
     *
     * <h4>Conversion properties</h4>
     * The {@code properties} map given in argument can contain any entries documented in the
     * {@linkplain #DefaultDerivedCRS(Map, SingleCRS, Conversion, CoordinateSystem) above constructor},
     * together with any entries documented by the {@linkplain DefaultConversion#DefaultConversion(Map,
     * CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateReferenceSystem, OperationMethod, MathTransform)
     * conversion constructor} provided that the {@code Conversion} entry keys are prefixed by {@code "conversion."}.
     * In particular, the two first properties listed below are mandatory:
     *
     * <table class="sis">
     *   <caption>Mandatory properties and some optional properties</caption>
     *   <tr>
     *     <th>Property name</th>
     *     <th>Value type</th>
     *     <th>Returned by</th>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
     *     <td>{@link org.opengis.metadata.Identifier} or {@link String}</td>
     *     <td>{@code this.getName()}</td>
     *   </tr><tr>
     *     <td>"conversion.name"</td>
     *     <td>{@link org.opengis.metadata.Identifier} or {@link String}</td>
     *     <td>{@code conversionFromBase.getName()}</td>
     *   </tr><tr>
     *     <th colspan="3" class="hsep">Optional properties (non exhaustive list)</th>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
     *     <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td>
     *     <td>{@code this.getIdentifiers()}</td>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.operation.CoordinateOperation#DOMAIN_OF_VALIDITY_KEY}</td>
     *     <td>{@link org.opengis.metadata.extent.Extent}</td>
     *     <td>{@code conversionFromBase.getDomainOfValidity()}</td>
     *   </tr>
     * </table>
     *
     * @param  properties        the properties to be given to the {@link DefaultConversion} object
     *                           (with keys prefixed by {@code "conversion."}) and to the new derived CRS object.
     * @param  baseCRS           coordinate reference system to base the derived CRS on.
     * @param  interpolationCRS  the CRS of additional coordinates needed for the operation, or {@code null} if none.
     * @param  method            the coordinate operation method (mandatory in all cases).
     * @param  baseToDerived     transform from positions in the base CRS to positions in this target CRS.
     * @param  derivedCS         the coordinate system for the derived CRS.
     * @throws IllegalArgumentException if at least one argument has an incompatible number of dimensions.
     *
     * @see #create(Map, SingleCRS, CoordinateReferenceSystem, OperationMethod, MathTransform, CoordinateSystem)
     */
    protected DefaultDerivedCRS(final Map<String,?>             properties,
                                final SingleCRS                 baseCRS,
                                final CoordinateReferenceSystem interpolationCRS,
                                final OperationMethod           method,
                                final MathTransform             baseToDerived,
                                final CoordinateSystem          derivedCS)
    {
        super(properties, baseCRS, interpolationCRS, method, baseToDerived, derivedCS);
    }

    /**
     * Constructs a new coordinate reference system with the same values as the specified one.
     * This copy constructor provides a way to convert an arbitrary implementation into a SIS one
     * or a user-defined one (as a subclass), usually in order to leverage some implementation-specific API.
     *
     * <p>This constructor performs a shallow copy, i.e. the properties are not cloned.</p>
     *
     * @param  crs  the coordinate reference system to copy.
     *
     * @see #castOrCopy(DerivedCRS)
     */
    protected DefaultDerivedCRS(final DerivedCRS crs) {
        super(crs);
    }

    /**
     * Creates a derived CRS from a defining conversion and a type inferred from the given arguments.
     * This method expects the same arguments and performs the same work as the
     * {@linkplain #DefaultDerivedCRS(Map, SingleCRS, Conversion, CoordinateSystem) above constructor},
     * except that the {@code DerivedCRS} instance returned by this method may additionally implement
     * the {@link GeodeticCRS}, {@link VerticalCRS}, {@link TemporalCRS}, {@link ParametricCRS} or
     * {@link EngineeringCRS} interface.
     * See the class javadoc for more information.
     *
     * @param  properties  the properties to be given to the new derived CRS object.
     * @param  baseCRS     coordinate reference system to base the derived CRS on.
     * @param  conversion  the defining conversion from a normalized base to a normalized derived CRS.
     * @param  derivedCS   the coordinate system for the derived CRS. The number of axes
     *                     must match the target dimension of the {@code baseToDerived} transform.
     * @return the newly created derived CRS, potentially implementing an additional CRS interface.
     * @throws MismatchedDimensionException if the source and target dimensions of {@code baseToDerived}
     *         do not match the dimensions of {@code base} and {@code derivedCS} respectively.
     *
     * @see #DefaultDerivedCRS(Map, SingleCRS, Conversion, CoordinateSystem)
     * @see org.apache.sis.referencing.factory.GeodeticObjectFactory#createDerivedCRS(Map, CoordinateReferenceSystem, Conversion, CoordinateSystem)
     */
    public static DefaultDerivedCRS create(final Map<String,?>    properties,
                                           final SingleCRS        baseCRS,
                                           final Conversion       conversion,
                                           final CoordinateSystem derivedCS)
            throws MismatchedDimensionException
    {
        if (baseCRS != null && derivedCS != null) {
            final String type = getType(baseCRS, derivedCS);
            if (type != null) switch (type) {
                case WKTKeywords.GeodeticCRS:   return new Geodetic  (properties, (GeodeticCRS)   baseCRS, conversion,                derivedCS);
                case WKTKeywords.VerticalCRS:   return new Vertical  (properties, (VerticalCRS)   baseCRS, conversion,   (VerticalCS) derivedCS);
                case WKTKeywords.TimeCRS:       return new Temporal  (properties, (TemporalCRS)   baseCRS, conversion,       (TimeCS) derivedCS);
                case WKTKeywords.ParametricCRS: return new Parametric(properties, (ParametricCRS) baseCRS, conversion, (ParametricCS) derivedCS);
                case WKTKeywords.EngineeringCRS: {
                    /*
                     * This case may happen for baseCRS of kind GeodeticCRS, ProjectedCRS or EngineeringCRS.
                     * But only the latter is associated to EngineeringDatum; the two formers are associated
                     * to GeodeticDatum. Consequently, we can implement the EngineeringCRS.getDatum() method
                     * only if the base CRS is itself of kind EngineeringCRS.  Otherwise we will return the
                     * "type-neutral" DefaultDerivedCRS implementation.  Note that even in the latter case,
                     * the WKT format will still be able to detect that the WKT keyword is "EngineeringCRS".
                     */
                    if (baseCRS instanceof EngineeringCRS) {
                        return new Engineering(properties, (EngineeringCRS) baseCRS, conversion, derivedCS);
                    }
                    break;
                }
            }
        }
        return new DefaultDerivedCRS(properties, baseCRS, conversion, derivedCS);
    }

    /**
     * Creates a derived CRS from a math transform and a type inferred from the given arguments.
     * This method expects the same arguments and performs the same work as the
     * {@linkplain #DefaultDerivedCRS(Map, SingleCRS, CoordinateReferenceSystem, OperationMethod, MathTransform,
     * CoordinateSystem) above constructor},
     * except that the {@code DerivedCRS} instance returned by this method may additionally implement
     * the {@link GeodeticCRS}, {@link VerticalCRS}, {@link TemporalCRS}, {@link ParametricCRS} or
     * {@link EngineeringCRS} interface.
     * See the class javadoc for more information.
     *
     * @param  properties        the properties to be given to the {@link DefaultConversion} object
     *                           (with keys prefixed by {@code "conversion."}) and to the new derived CRS object.
     * @param  baseCRS           coordinate reference system to base the derived CRS on.
     * @param  interpolationCRS  the CRS of additional coordinates needed for the operation, or {@code null} if none.
     * @param  method            the coordinate operation method (mandatory in all cases).
     * @param  baseToDerived     transform from positions in the base CRS to positions in this target CRS.
     * @param  derivedCS         the coordinate system for the derived CRS.
     * @return the newly created derived CRS, potentially implementing an additional CRS interface.
     * @throws IllegalArgumentException if at least one argument has an incompatible number of dimensions.
     *
     * @see #DefaultDerivedCRS(Map, SingleCRS, CoordinateReferenceSystem, OperationMethod, MathTransform, CoordinateSystem)
     */
    public static DefaultDerivedCRS create(final Map<String,?>             properties,
                                           final SingleCRS                 baseCRS,
                                           final CoordinateReferenceSystem interpolationCRS,
                                           final OperationMethod           method,
                                           final MathTransform             baseToDerived,
                                           final CoordinateSystem          derivedCS)
    {
        if (baseCRS != null && derivedCS != null) {
            final String type = getType(baseCRS, derivedCS);
            if (type != null) switch (type) {
                case WKTKeywords.GeodeticCRS:   return new Geodetic  (properties, (GeodeticCRS)   baseCRS, interpolationCRS, method, baseToDerived,                derivedCS);
                case WKTKeywords.VerticalCRS:   return new Vertical  (properties, (VerticalCRS)   baseCRS, interpolationCRS, method, baseToDerived,  (VerticalCS)  derivedCS);
                case WKTKeywords.TimeCRS:       return new Temporal  (properties, (TemporalCRS)   baseCRS, interpolationCRS, method, baseToDerived,      (TimeCS)  derivedCS);
                case WKTKeywords.ParametricCRS: return new Parametric(properties, (ParametricCRS) baseCRS, interpolationCRS, method, baseToDerived, (ParametricCS) derivedCS);
                case WKTKeywords.EngineeringCRS: {
                    if (baseCRS instanceof EngineeringCRS) {
                        // See the comment in create(Map, SingleCRS, Conversion, CoordinateSystem)
                        return new Engineering(properties, (EngineeringCRS) baseCRS, interpolationCRS, method, baseToDerived, derivedCS);
                    }
                    break;
                }
            }
        }
        return new DefaultDerivedCRS(properties, baseCRS, interpolationCRS, method, baseToDerived, derivedCS);
    }

    /**
     * Returns a SIS coordinate reference system implementation with the same values as the given
     * arbitrary implementation. If the given object is {@code null}, then this method returns {@code null}.
     * Otherwise if the given object is already a SIS implementation, then the given object is returned unchanged.
     * Otherwise a new SIS implementation is created and initialized to the attribute values of the given object.
     *
     * @param  object  the object to get as a SIS implementation, or {@code null} if none.
     * @return a SIS implementation containing the values of the given object (may be the
     *         given object itself), or {@code null} if the argument was null.
     */
    public static DefaultDerivedCRS castOrCopy(final DerivedCRS object) {
        if (object == null || object instanceof DefaultDerivedCRS) {
            return (DefaultDerivedCRS) object;
        } else {
            final String type = getType(object.getBaseCRS(), object.getCoordinateSystem());
            if (type != null) switch (type) {
                case WKTKeywords.GeodeticCRS:    return new Geodetic   (object);
                case WKTKeywords.VerticalCRS:    return new Vertical   (object);
                case WKTKeywords.TimeCRS:        return new Temporal   (object);
                case WKTKeywords.ParametricCRS:  return new Parametric (object);
                case WKTKeywords.EngineeringCRS: return new Engineering(object);
            }
            return new DefaultDerivedCRS(object);
        }
    }

    /**
     * Returns the type of conversion associated to this {@code DefaultDerivedCRS}.
     * Must be a hard-coded, constant value (not dependent on object state).
     */
    @Override
    final Class<Conversion> getConversionType() {
        return Conversion.class;
    }

    /**
     * Returns the GeoAPI interface implemented by this class.
     * The SIS implementation returns {@code DerivedCRS.class}.
     *
     * <h4>Note for implementers</h4>
     * Subclasses usually do not need to override this method since GeoAPI does not define {@code DerivedCRS}
     * sub-interface. Overriding possibility is left mostly for implementers who wish to extend GeoAPI with
     * their own set of interfaces.
     *
     * @return {@code DerivedCRS.class} or a user-defined sub-interface.
     */
    @Override
    public Class<? extends DerivedCRS> getInterface() {
        return DerivedCRS.class;
    }

    /**
     * Returns the datum of the {@linkplain #getBaseCRS() base CRS}.
     *
     * @return the datum of the base CRS.
     */
    @Override
    public Datum getDatum() {
        return getBaseCRS().getDatum();
    }

    /**
     * Returns the CRS on which the conversion is applied.
     * This CRS defines the {@linkplain #getDatum() datum} of this CRS and (at least implicitly)
     * the {@linkplain DefaultConversion#getSourceCRS() source} of
     * the {@linkplain #getConversionFromBase() conversion from base}.
     *
     * @return the base coordinate reference system.
     */
    @Override
    @XmlElement(name = "baseCRS", required = true)
    @XmlJavaTypeAdapter(SC_SingleCRS.class)
    public SingleCRS getBaseCRS() {
        return (SingleCRS) super.getConversionFromBase().getSourceCRS();
    }

    /**
     * Returns the conversion from the {@linkplain #getBaseCRS() base CRS} to this CRS.
     * In Apache SIS, the conversion source and target CRS are set to the following values:
     *
     * <ul>
     *   <li>The conversion {@linkplain DefaultConversion#getSourceCRS() source CRS}
     *       is the {@linkplain #getBaseCRS() base CRS} of {@code this} CRS.</li>
     *   <li>The conversion {@linkplain DefaultConversion#getTargetCRS() target CRS} is {@code this} CRS.
     * </ul>
     *
     * <div class="note"><b>Note:</b>
     * This is different than ISO 19111, which allows source and target CRS to be {@code null}.</div>
     *
     * @return the conversion to this CRS.
     */
    @Override
    public Conversion getConversionFromBase() {
        return super.getConversionFromBase();
    }

    /**
     * Returns the coordinate system.
     *
     * @return the coordinate system.
     */
    @Override
    @XmlElement(name = "coordinateSystem", required = true)
    @XmlJavaTypeAdapter(CS_CoordinateSystem.class)
    public CoordinateSystem getCoordinateSystem() {
        return super.getCoordinateSystem();
    }

    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     */
    @Override
    public DefaultDerivedCRS forConvention(final AxesConvention convention) {
        return (DefaultDerivedCRS) super.forConvention(convention);
    }

    /**
     * Returns a coordinate reference system of the same type as this CRS but with different axes.
     *
     * @param  cs  the coordinate system with new axes.
     * @return new CRS of the same type and datum than this CRS, but with the given axes.
     */
    @Override
    AbstractCRS createSameType(final AbstractCS derivedCS) {
        return new DefaultDerivedCRS(this, derivedCS);
    }

    /**
     * Compares this coordinate reference system with the specified object for equality.
     * In addition to the metadata documented in the
     * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#equals(Object, ComparisonMode) parent class},
     * this method considers coordinate system axes of the {@linkplain #getBaseCRS() base CRS} as metadata.
     * This means that if the given {@code ComparisonMode} is {@code IGNORE_METADATA} or {@code APPROXIMATE},
     * then axis order of the base CRS are ignored
     * (but <strong>not</strong> axis order of <strong>this</strong> derived CRS).
     *
     * @param  object  the object to compare to {@code this}.
     * @param  mode    {@link ComparisonMode#STRICT STRICT} for performing a strict comparison, or
     *                 {@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA} for comparing only
     *                 properties relevant to coordinate transformations.
     * @return {@code true} if both objects are equal.
     */
    @Override
    public boolean equals(final Object object, final ComparisonMode mode) {
        return super.equals(object, mode);
    }

    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     */
    @Override
    protected long computeHashCode() {
        return super.computeHashCode();
    }

    /**
     * Formats the inner part of the <i>Well Known Text</i> (WKT) representation of this CRS.
     *
     * @return {@code "Fitted_CS"} (WKT 1) or a type-dependent keyword (WKT 2).
     *
     * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#93">WKT 2 specification §15</a>
     */
    @Override
    protected String formatTo(final Formatter formatter) {
        final Conversion conversion = getConversionFromBase();  // Gives to users a chance to override.
        if (conversion == null) {
            /*
             * Should never happen except temporarily at construction time, or if the user invoked the copy
             * constructor with an invalid Conversion, or if the user overrides the getConversionFromBase()
             * method. Delegates to the super-class method for avoiding a NullPointerException. That method
             * returns 'null', which will cause the WKT to be declared invalid.
             */
            return super.formatTo(formatter);
        }
        WKTUtilities.appendName(this, formatter, null);
        final Convention convention = formatter.getConvention();
        final boolean isWKT1 = (convention.majorVersion() == 1);
        /*
         * Both WKT 1 and WKT 2 format the base CRS. But WKT 1 formats the MathTransform before the base CRS,
         * while WKT 2 formats the conversion method and parameter values after the base CRS.
         */
        if (isWKT1) {
            MathTransform inverse = conversion.getMathTransform();
            try {
                inverse = inverse.inverse();
            } catch (NoninvertibleTransformException exception) {
                formatter.setInvalidWKT(this, exception);
                inverse = null;
            }
            formatter.newLine();
            formatter.append(inverse);
        }
        formatter.newLine();
        formatter.append(WKTUtilities.toFormattable(getBaseCRS()));
        if (isWKT1) {
            return WKTKeywords.Fitted_CS;
        } else {
            formatter.newLine();
            formatter.append(new ExplicitParameters(this, WKTKeywords.DerivingConversion));     // Format inside a "DefiningConversion" element.
            if (convention == Convention.INTERNAL || !isBaseCRS(formatter)) {
                final CoordinateSystem cs = getCoordinateSystem();
                formatCS(formatter, cs, ReferencingUtilities.getUnit(cs), isWKT1);
            }
            return keyword(formatter);
        }
    }

    /**
     * Return the WKT 2 keyword for this {@code DerivedCRS}, or {@code null} if unknown.
     * Inner subclasses will override this method for returning a constant value instead
     * than trying to infer it from the components.
     */
    String keyword(final Formatter formatter) {
        final String longKeyword = getType(getBaseCRS(), getCoordinateSystem());
        final String shortKeyword;
        if (longKeyword == null) {
            return null;
        }
        switch (longKeyword) {
            case WKTKeywords.GeodeticCRS:    shortKeyword = WKTKeywords.GeodCRS; break;
            case WKTKeywords.VerticalCRS:    shortKeyword = WKTKeywords.VertCRS; break;
            case WKTKeywords.EngineeringCRS: shortKeyword = WKTKeywords.EngCRS;  break;
            default: return longKeyword;
        }
        return formatter.shortOrLong(shortKeyword, longKeyword);
    }

    /**
     * Returns the WKT 2 keyword for a {@code DerivedCRS} having the given base CRS and derived coordinate system.
     * If the type cannot be identifier, then this method returns {@code null}.
     */
    static String getType(final SingleCRS baseCRS, final CoordinateSystem derivedCS) {
        final Class<?> type;
        if (baseCRS instanceof AbstractIdentifiedObject) {
            /*
             * For avoiding ambiguity if a user chooses to implement more
             * than 1 CRS interface (not recommended, but may happen).
             */
            type = ((AbstractIdentifiedObject) baseCRS).getInterface();
        } else if (baseCRS != null) {
            type = baseCRS.getClass();
        } else {
            return null;
        }
        if (GeodeticCRS.class.isAssignableFrom(type) && CoordinateSystems.isGeodetic(derivedCS)) {
            return WKTKeywords.GeodeticCRS;
        } else if (VerticalCRS.class.isAssignableFrom(type) && derivedCS instanceof VerticalCS) {
            return WKTKeywords.VerticalCRS;
        } else if (TemporalCRS.class.isAssignableFrom(type) && derivedCS instanceof TimeCS) {
            return WKTKeywords.TimeCRS;
        } else if (ParametricCRS.class.isAssignableFrom(type) && derivedCS instanceof ParametricCS) {
            return WKTKeywords.ParametricCRS;
        } else if (ProjectedCRS.class.isAssignableFrom(type) || EngineeringCRS.class.isAssignableFrom(type)) {
            return WKTKeywords.EngineeringCRS;
        } else {
            return null;
        }
    }




    /**
     * A derived geodetic CRS.  Note that base CRS of kind {@link GeodeticCRS} can be used both with this class
     * and with {@link org.apache.sis.referencing.crs.DefaultDerivedCRS.Engineering}. Consequently, an ambiguity
     * may exist when choosing the kind if {@code DerivedCRS} to create for a given {@code GeodeticCRS}.
     */
    @XmlTransient
    private static final class Geodetic extends DefaultDerivedCRS implements GeodeticCRS {
        /** For cross-version compatibility. */
        private static final long serialVersionUID = -1263243517380302846L;

        /** Creates a copy of the given CRS. */
        Geodetic(DerivedCRS other) {
            super(other);
        }

        /** Creates a new CRS derived from the specified one, but with different axis order or unit. */
        private Geodetic(final Geodetic original, final AbstractCS derivedCS) {
            super(original, derivedCS);
        }

        /** Creates a new geodetic CRS from the given properties. */
        Geodetic(Map<String,?> properties, GeodeticCRS baseCRS, Conversion conversion, CoordinateSystem derivedCS) {
            super(properties, baseCRS, conversion, derivedCS);
        }

        /** Creates a new geodetic CRS from the given properties. */
        Geodetic(Map<String,?> properties, GeodeticCRS baseCRS, CoordinateReferenceSystem interpolationCRS,
                OperationMethod method, MathTransform baseToDerived, CoordinateSystem derivedCS)
        {
            super(properties, baseCRS, interpolationCRS, method, baseToDerived, derivedCS);
        }

        /** Returns the datum of the base geodetic CRS. */
        @Override public GeodeticDatum getDatum() {
            return (GeodeticDatum) super.getDatum();
        }

        /** Returns a coordinate reference system of the same type as this CRS but with different axes. */
        @Override AbstractCRS createSameType(final AbstractCS derivedCS) {
            return new Geodetic(this, derivedCS);
        }

        /** Returns the WKT keyword for this derived CRS type. */
        @Override String keyword(final Formatter formatter) {
            return formatter.shortOrLong(WKTKeywords.GeodCRS, WKTKeywords.GeodeticCRS);
        }

        /** Returns the GML code for this derived CRS type. */
        @Override SC_DerivedCRSType getType() {
            return new SC_DerivedCRSType("geodetic");
        }
    }

    /**
     * A derived vertical CRS.
     */
    @XmlTransient
    private static final class Vertical extends DefaultDerivedCRS implements VerticalCRS {
        /** For cross-version compatibility. */
        private static final long serialVersionUID = -5599709829566076972L;

        /** Creates a copy of the given CRS. */
        Vertical(DerivedCRS other) {
            super(other);
        }

        /** Creates a new CRS derived from the specified one, but with different axis order or unit. */
        private Vertical(final Vertical original, final AbstractCS derivedCS) {
            super(original, derivedCS);
        }

        /** Creates a new vertical CRS from the given properties. */
        Vertical(Map<String,?> properties, VerticalCRS baseCRS, Conversion conversion, VerticalCS derivedCS) {
            super(properties, baseCRS, conversion, derivedCS);
        }

        /** Creates a new vertical CRS from the given properties. */
        Vertical(Map<String,?> properties, VerticalCRS baseCRS, CoordinateReferenceSystem interpolationCRS,
                OperationMethod method, MathTransform baseToDerived, VerticalCS derivedCS)
        {
            super(properties, baseCRS, interpolationCRS, method, baseToDerived, derivedCS);
        }

        /** Returns the datum of the base vertical CRS. */
        @Override public VerticalDatum getDatum() {
            return (VerticalDatum) super.getDatum();
        }

        /** Returns the coordinate system given at construction time. */
        @Override public VerticalCS getCoordinateSystem() {
            return (VerticalCS) super.getCoordinateSystem();
        }

        /** Returns a coordinate reference system of the same type as this CRS but with different axes. */
        @Override AbstractCRS createSameType(final AbstractCS derivedCS) {
            return new Vertical(this, derivedCS);
        }

        /** Returns the WKT keyword for this derived CRS type. */
        @Override String keyword(final Formatter formatter) {
            return formatter.shortOrLong(WKTKeywords.VertCRS, WKTKeywords.VerticalCRS);
        }

        /** Returns the GML code for this derived CRS type. */
        @Override SC_DerivedCRSType getType() {
            return new SC_DerivedCRSType("vertical");
        }
    }

    /**
     * A derived temporal CRS.
     */
    @XmlTransient
    private static final class Temporal extends DefaultDerivedCRS implements TemporalCRS {
        /** For cross-version compatibility. */
        private static final long serialVersionUID = -4721311735720248819L;

        /** Creates a copy of the given CRS. */
        Temporal(DerivedCRS other) {
            super(other);
        }

        /** Creates a new CRS derived from the specified one, but with different axis order or unit. */
        private Temporal(final Temporal original, final AbstractCS derivedCS) {
            super(original, derivedCS);
        }

        /** Creates a new temporal CRS from the given properties. */
        Temporal(Map<String,?> properties, TemporalCRS baseCRS, Conversion conversion, TimeCS derivedCS) {
            super(properties, baseCRS, conversion, derivedCS);
        }

        /** Creates a new temporal CRS from the given properties. */
        Temporal(Map<String,?> properties, TemporalCRS baseCRS, CoordinateReferenceSystem interpolationCRS,
                OperationMethod method, MathTransform baseToDerived, TimeCS derivedCS)
        {
            super(properties, baseCRS, interpolationCRS, method, baseToDerived, derivedCS);
        }

        /** Returns the datum of the base temporal CRS. */
        @Override public TemporalDatum getDatum() {
            return (TemporalDatum) super.getDatum();
        }

        /** Returns the coordinate system given at construction time. */
        @Override public TimeCS getCoordinateSystem() {
            return (TimeCS) super.getCoordinateSystem();
        }

        /** Returns a coordinate reference system of the same type as this CRS but with different axes. */
        @Override AbstractCRS createSameType(final AbstractCS derivedCS) {
            return new Temporal(this, derivedCS);
        }

        /** Returns the WKT keyword for this derived CRS type. */
        @Override String keyword(final Formatter formatter) {
            return WKTKeywords.TimeCRS;
        }

        /** Returns the GML code for this derived CRS type. */
        @Override SC_DerivedCRSType getType() {
            return new SC_DerivedCRSType("time");
        }
    }

    /**
     * A derived parametric CRS.
     */
    @XmlTransient
    private static final class Parametric extends DefaultDerivedCRS implements ParametricCRS {
        /** For cross-version compatibility. */
        private static final long serialVersionUID = 2344979923957294024L;

        /** Creates a copy of the given CRS. */
        Parametric(DerivedCRS other) {
            super(other);
        }

        /** Creates a new CRS derived from the specified one, but with different axis order or unit. */
        private Parametric(final Parametric original, final AbstractCS derivedCS) {
            super(original, derivedCS);
        }

        /** Creates a new parametric CRS from the given properties. */
        Parametric(Map<String,?> properties, ParametricCRS baseCRS, Conversion conversion, ParametricCS derivedCS) {
            super(properties, baseCRS, conversion, derivedCS);
        }

        /** Creates a new parametric CRS from the given properties. */
        Parametric(Map<String,?> properties, ParametricCRS baseCRS, CoordinateReferenceSystem interpolationCRS,
                OperationMethod method, MathTransform baseToDerived, ParametricCS derivedCS)
        {
            super(properties, baseCRS, interpolationCRS, method, baseToDerived, derivedCS);
        }

        /** Returns the datum of the base parametric CRS. */
        @Override public ParametricDatum getDatum() {
            return (ParametricDatum) super.getDatum();
        }

        /** Returns the coordinate system given at construction time. */
        @Override public ParametricCS getCoordinateSystem() {
            return (ParametricCS) super.getCoordinateSystem();
        }

        /** Returns a coordinate reference system of the same type as this CRS but with different axes. */
        @Override AbstractCRS createSameType(final AbstractCS derivedCS) {
            return new Parametric(this, derivedCS);
        }

        /** Returns the WKT keyword for this derived CRS type. */
        @Override String keyword(final Formatter formatter) {
            return WKTKeywords.ParametricCRS;
        }

        /** Returns the GML code for this derived CRS type. */
        @Override SC_DerivedCRSType getType() {
            return new SC_DerivedCRSType("parametric");
        }
    }

    /**
     * An derived engineering CRS. ISO 19162 restricts the base CRS to {@code EngineeringCRS}, {@code ProjectedCRS}
     * or {@code GeodeticCRS}. Note that in the latter case, an ambiguity may exist with the
     * {@link org.apache.sis.referencing.crs.DefaultDerivedCRS.Geodetic} when deciding which {@code DerivedCRS} to
     * create.
     */
    @XmlTransient
    private static final class Engineering extends DefaultDerivedCRS implements EngineeringCRS {
        /** For cross-version compatibility. */
        private static final long serialVersionUID = 42334975023270039L;

        /** Creates a copy of the given CRS. */
        Engineering(DerivedCRS other) {
            super(other);
        }

        /** Creates a new CRS derived from the specified one, but with different axis order or unit. */
        private Engineering(final Engineering original, final AbstractCS derivedCS) {
            super(original, derivedCS);
        }

        /** Creates a new engineering CRS from the given properties. */
        Engineering(Map<String,?> properties, EngineeringCRS baseCRS, Conversion conversion, CoordinateSystem derivedCS) {
            super(properties, baseCRS, conversion, derivedCS);
        }

        /** Creates a new engineering CRS from the given properties. */
        Engineering(Map<String,?> properties, EngineeringCRS baseCRS, CoordinateReferenceSystem interpolationCRS,
                OperationMethod method, MathTransform baseToDerived, CoordinateSystem derivedCS)
        {
            super(properties, baseCRS, interpolationCRS, method, baseToDerived, derivedCS);
        }

        /** Returns the datum of the base engineering CRS. */
        @Override public EngineeringDatum getDatum() {
            return (EngineeringDatum) super.getDatum();
        }

        /** Returns a coordinate reference system of the same type as this CRS but with different axes. */
        @Override AbstractCRS createSameType(final AbstractCS derivedCS) {
            return new Engineering(this, derivedCS);
        }

        /** Returns the WKT keyword for this derived CRS type. */
        @Override String keyword(final Formatter formatter) {
            return formatter.shortOrLong(WKTKeywords.EngCRS, WKTKeywords.EngineeringCRS);
        }

        /** Returns the GML code for this derived CRS type. */
        @Override SC_DerivedCRSType getType() {
            return new SC_DerivedCRSType("engineering");
        }
    }



    /*
     ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
     ┃                                                                                  ┃
     ┃                               XML support with JAXB                              ┃
     ┃                                                                                  ┃
     ┃        The following methods are invoked by JAXB using reflection (even if       ┃
     ┃        they are private) or are helpers for other methods invoked by JAXB.       ┃
     ┃        Those methods can be safely removed if Geographic Markup Language         ┃
     ┃        (GML) support is not needed.                                              ┃
     ┃                                                                                  ┃
     ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
     */

    /**
     * Constructs a new object in which every attributes are set to a default value.
     * <strong>This is not a valid object.</strong> This constructor is strictly
     * reserved to JAXB, which will assign values to the fields using reflection.
     */
    private DefaultDerivedCRS() {
    }

    /**
     * Returns the {@code <gml:derivedCRSType>} element to marshal. The default implementation tries to infer this
     * information from the {@code DefaultDerivedCRS} properties, but subclasses will override for more determinism.
     *
     * <h4>API note</h4>
     * There is no setter at this time because SIS does not store this information in a {@code DefaultDerivedCRS}
     * field. Instead, we rely on the interface that we implement. For example, a {@code DefaultDerivedCRS} of type
     * {@code SC_DerivedCRSType.vertical} will implement the {@link VerticalCRS} interface.
     */
    @XmlElement(name = "derivedCRSType", required = true)
    SC_DerivedCRSType getType() {
        return SC_DerivedCRSType.fromWKT(getType(getBaseCRS(), getCoordinateSystem()));
    }

    /**
     * Used by JAXB only (invoked by reflection).
     *
     * @see #getBaseCRS()
     */
    private void setBaseCRS(final SingleCRS crs) {
        setBaseCRS("baseCRS", crs);
    }

    /**
     * Used by JAXB only (invoked by reflection).
     *
     * @see #getCoordinateSystem()
     */
    private void setCoordinateSystem(final CoordinateSystem cs) {
        setCoordinateSystem("coordinateSystem", cs);
    }
}
