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


/**
 * Interfaces of classes for which instances can be compared for equality using different levels of strictness.
 * For example {@link org.opengis.referencing.operation.MathTransform} implementations can be
 * compared ignoring some properties (remarks, <i>etc.</i>) that are not relevant to the
 * coordinates calculation.
 *
 * <h2>Conditions for equality</h2>
 * <ul>
 *   <li>{@link org.apache.sis.metadata.iso.ISOMetadata} subclasses
 *     <ol>
 *       <li>{@link ComparisonMode#STRICT STRICT} – Objects must be of the same class
 *           and all attributes must be equal, including {@code xlink} and others
 *           {@linkplain org.apache.sis.metadata.iso.ISOMetadata#getIdentifiers() identifiers}.</li>
 *       <li>{@link ComparisonMode#BY_CONTRACT BY_CONTRACT} – The same attributes than the above
 *           {@code STRICT} mode must be equal, but the metadata object don't need to be implemented
 *           by the same class provided that they implement the same GeoAPI interface.</li>
 *       <li>{@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA} – Only the attributes defined
 *           in the GeoAPI interfaces are compared. The above-cited identifiers and {@code xlinks}
 *           attributes are ignored.</li>
 *       <li>{@link ComparisonMode#APPROXIMATE APPROXIMATE} – The same attributes than the above
 *           {@code IGNORE_METADATA} mode are compared, but a slight (implementation dependant)
 *           difference is tolerated in floating point numbers.</li>
 *     </ol>
 *   </li>
 *   <li>{@link org.apache.sis.referencing.AbstractIdentifiedObject} subclasses
 *     <ol>
 *       <li>{@link ComparisonMode#STRICT STRICT} – Objects must be of the same class
 *           and all attributes must be equal.</li>
 *       <li>{@link ComparisonMode#BY_CONTRACT BY_CONTRACT} – The same attributes than the above
 *           {@code STRICT} mode must be equal, but the referencing object don't need to be
 *           implemented by the same class provided that they implement the same GeoAPI interface.</li>
 *       <li>{@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA} – The
 *           {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getIdentifiers() identifiers},
 *           {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getAlias() aliases},
 *           {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getScope() scope},
 *           {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getDomainOfValidity() domain of validity} and
 *           {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getRemarks() remarks}
 *           are ignored because they have no incidence on the coordinate values to be computed by
 *           {@linkplain org.opengis.referencing.operation.ConcatenatedOperation coordinate operations}.
 *           All other attributes that are relevant to coordinate calculations, must be equal.</li>
 *       <li>{@link ComparisonMode#APPROXIMATE APPROXIMATE} – The same attributes than the above
 *           {@code IGNORE_METADATA} mode are compared, but a slight (implementation dependant)
 *           difference is tolerated in floating point numbers.</li>
 *     </ol>
 *   </li>
 *   <li>{@link org.apache.sis.referencing.operation.transform.AbstractMathTransform} subclasses
 *       except {@link org.apache.sis.referencing.operation.transform.LinearTransform}
 *     <ol>
 *       <li>{@link ComparisonMode#STRICT STRICT} – Objects must be of the same class and all
 *           attributes must be equal, including the
 *           {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform#getParameterValues() parameter values}.</li>
 *       <li>{@link ComparisonMode#BY_CONTRACT BY_CONTRACT} – Synonymous to the {@code STRICT} mode,
 *            because there is no GeoAPI interfaces for the various kind of math transforms.</li>
 *       <li>{@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA} – Objects must be of the same class,
 *           but the parameter values can be different if they are different way to formulate the same transform.
 *           For example a <cite>"Mercator (2SP)"</cite> projection on a sphere with a <cite>standard parallel</cite>
 *           value of 60° produces the same results than a <cite>"Mercator (1SP)"</cite> projection on the same sphere
 *           with a <cite>scale factor</cite> value of 0.5.</li>
 *       <li>{@link ComparisonMode#APPROXIMATE APPROXIMATE} – The same attributes than the above
 *           {@code IGNORE_METADATA} mode are compared, but a slight (implementation dependant)
 *           difference is tolerated in floating point numbers.</li>
 *     </ol>
 *   </li>
 *   <li>{@link org.apache.sis.referencing.operation.matrix.MatrixSIS} and
 *       {@link org.apache.sis.referencing.operation.transform.LinearTransform} implementations
 *     <ol>
 *       <li>{@link ComparisonMode#STRICT STRICT} – Objects must be of the same class, matrixes
 *           must have the same size and all matrix elements must be equal.</li>
 *       <li>{@link ComparisonMode#BY_CONTRACT BY_CONTRACT} – Matrixes must have the same size
 *           and all matrix elements must be equal, but the matrixes are not required to be the
 *           same implementation class (any {@link org.opengis.referencing.operation.Matrix} is okay).</li>
 *       <li>{@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA} – Synonymous to the
 *           {@code BY_CONTRACT} mode, because matrixes don't have metadata.</li>
 *       <li>{@link ComparisonMode#APPROXIMATE APPROXIMATE} – The same attributes than the above
 *           {@code BY_CONTRACT} mode are compared, but a slight (implementation dependant)
 *           difference is tolerated in floating point numbers.</li>
 *     </ol>
 *   </li>
 * </ul>
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.3
 * @since   0.3
 * @module
 */
public interface LenientComparable {
    /**
     * Compares this object with the given object for equality.
     * The strictness level is controlled by the second argument,
     * from stricter to more permissive values:
     *
     * <table class="compact">
     *   <caption>Description of comparison modes</caption>
     *   <tr><td>{@link ComparisonMode#STRICT STRICT}:</td>
     *        <td>All attributes of the compared objects shall be strictly equal.</td></tr>
     *   <tr><td>{@link ComparisonMode#BY_CONTRACT BY_CONTRACT}:</td>
     *       <td>Only the attributes published in the interface contract need to be compared.</td></tr>
     *   <tr><td>{@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA}:</td>
     *       <td>Only the attributes relevant to the object functionality are compared.</td></tr>
     *   <tr><td>{@link ComparisonMode#APPROXIMATE APPROXIMATE}:</td>
     *       <td>Only the attributes relevant to the object functionality are compared,
     *           with some tolerance threshold on numerical values.</td></tr>
     *   <tr><td>{@link ComparisonMode#DEBUG DEBUG}:</td>
     *        <td>Special mode for figuring out why two objects expected to be equal are not.</td></tr>
     * </table>
     *
     * <h4>Conformance to the {@code equals(Object)} method contract</h4>
     * {@link ComparisonMode#STRICT} is the only mode compliant with the {@link Object#equals(Object)} contract.
     * For all other modes <var>m</var>, the comparison is not guaranteed to be <cite>symmetric</cite> neither
     * <cite>transitive</cite>:
     *
     * <ul>
     *   <li>{@code x.equals(y,m)} is <strong>not</strong> guaranteed to be equal to {@code y.equals(x,m)}.
     *       In particular, the {@code BY_CONTRACT} mode and all modes below it will typically compare only the
     *       properties known to {@code this} instance, ignoring any properties that may be known only by the other
     *       instance.</li>
     *   <li>{@code x.equals(y,m)} and {@code y.equals(z,m)} does <strong>not</strong> implies
     *       {@code x.equals(z,m)}. In particular, the use of a comparison threshold for the
     *       {@code APPROXIMATE} mode is incompatible with the transitivity contract.</li>
     * </ul>
     *
     * @param  other  the object to compare to {@code this}.
     * @param  mode   the strictness level of the comparison.
     * @return {@code true} if both objects are equal according the given comparison mode.
     *
     * @see Utilities#deepEquals(Object, Object, ComparisonMode)
     */
    boolean equals(Object other, ComparisonMode mode);

    /**
     * Returns {@code true} if this object is strictly equals to the given object.
     * This method is usually implemented as below:
     *
     * {@preformat java
     *     public boolean equals(Object other) {
     *         return equals(other, ComparisonMode.STRICT);
     *     }
     * }
     *
     * Implementers shall ensure that the following conditions hold. Unless the {@code equals}
     * behavior is clearly documented in the interface javadoc (as for example in the Java
     * collection framework), {@link ComparisonMode#STRICT} is the only reliable mode for
     * this method implementation.
     *
     * <ul>
     *   <li>{@code A.equals(B)} implies {@code B.equals(A)};</li>
     *   <li>{@code A.equals(B)} and {@code B.equals(C)} implies {@code A.equals(C)};</li>
     *   <li>{@code A.equals(B)} implies {@code A.hashCode() == B.hashCode()};</li>
     * </ul>
     *
     * This method is declared {@code final} in most SIS implementations for ensuring that
     * subclasses override the above {@link #equals(Object, ComparisonMode)} method instead
     * than this one.
     *
     * @param  other  the object to compare to {@code this}.
     * @return {@code true} if both objects are strictly equal.
     *
     * @see ComparisonMode#STRICT
     */
    @Override
    boolean equals(Object other);
}
