/*
 * 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.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
import java.io.Serializable;
import org.opengis.geometry.Envelope;
import org.opengis.geometry.DirectPosition;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.geometry.MismatchedReferenceSystemException;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.apache.sis.internal.referencing.DirectPositionView;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.geometry.GeneralEnvelope;
import org.apache.sis.io.wkt.Formatter;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.Utilities;


/**
 * A transform having sub-areas where more accurate transforms can be used.
 * The global transform must be a reasonable approximation of the specialized transforms.
 * The lower and upper values of given envelopes are inclusive.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 *
 * @see MathTransforms#specialize(MathTransform, Map)
 *
 * @since 1.0
 * @module
 */
class SpecializableTransform extends AbstractMathTransform implements Serializable {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = -7379277748632094312L;

    /**
     * The global transform to use if there is no suitable specialization.
     */
    private final MathTransform global;

    /**
     * The region where a transform is valid, together with the transform.
     * Contains also a chain of {@code SubArea}s fully included in this area.
     * Shall be unmodified after {@link SpecializableTransform} construction.
     */
    @SuppressWarnings("CloneableClassWithoutClone")                             // We will not use clone().
    private static final class SubArea extends GeneralEnvelope {
        /**
         * For cross-version compatibility.
         */
        private static final long serialVersionUID = 4197316795428796526L;

        /**
         * The transform to apply in this area.
         */
        final MathTransform transform;

        /**
         * The inverse of the transform, computed when first needed.
         * Synchronization for multi-threading is done (indirectly) in {@link SpecializableTransform#inverse()}.
         *
         * @see #createInverse(SubArea)
         */
        MathTransform inverse;

        /**
         * Specialization, or {@code null} if none. If non-null, that sub-area shall be fully included
         * in this {@code SubArea}. The specialization may itself contain another specialization. This
         * form a chain from this wider area to smallest area, where each step is a smaller area.
         *
         * <p>Note that this is note a substitute for an R-Tree. This is an optimization for the common
         * case where coordinates are close to each other (e.g. when iterating in a geometry), in which
         * case we can check immediately for inclusion in smaller areas before to check the wider area.</p>
         */
        private SubArea specialization;

        /**
         * Creates a new area where a transform is valid.
         */
        SubArea(final Envelope area, final MathTransform transform) {
            super(area);
            this.transform = transform;
        }

        /**
         * Tries to add a nested sub-area (a specialization of a specialization).
         *
         * @return whether the given area has been added.
         */
        boolean addSpecialization(final SubArea candidate) {
            if (specialization == null) {
                if (!contains(candidate)) {
                    return false;
                }
            } else if (!candidate.addSpecialization(specialization)) {
                return specialization.addSpecialization(candidate);
            }
            specialization = candidate;
            return true;
        }

        /**
         * Sets the CRS of all given ares to a common value. An exception is thrown if incompatible CRS are found.
         * This method does not verify the number of dimensions; this check should have been done by the caller.
         */
        static void uniformize(final SubArea[] domains) {
            CoordinateReferenceSystem common = null;
            for (SubArea area : domains) {
                do {
                    final CoordinateReferenceSystem crs = area.getCoordinateReferenceSystem();
                    if (common == null) {
                        common = crs;
                    } else if (crs != null && !Utilities.equalsIgnoreMetadata(common, crs)) {
                        throw new MismatchedReferenceSystemException(Errors.format(Errors.Keys.MismatchedCRS));
                    }
                } while ((area = area.specialization) != null);
            }
            for (SubArea area : domains) {
                do area.setCoordinateReferenceSystem(common);
                while ((area = area.specialization) != null);
            }
        }

        /**
         * Creates the inverse transforms. This method should be invoked only once when first needed
         * in a block synchronized (indirectly) by {@link SpecializableTransform#inverse()}.
         */
        static void createInverse(SubArea area) throws NoninvertibleTransformException {
            do {
                area.inverse = area.transform.inverse();
                area = area.specialization;
            } while (area != null);
        }

        /**
         * Returns the area that contains the given position, or {@code null} if none.
         * This method may be replaced by an R-Tree in a future Apache SIS version.
         */
        static SubArea find(final SubArea[] domains, final DirectPosition pos) {
            for (SubArea area : domains) {
                if (area.contains(pos)) {
                    SubArea next = area.specialization;
                    while (next != null && next.contains(pos)) {
                        area = next;
                        next = next.specialization;
                    }
                    return area;
                }
            }
            return null;
        }

        /**
         * Returns the area that contains the given position, looking only in the given area or its specializations.
         * Returns {@code null} if no area has been found.
         */
        static SubArea find(SubArea area, final DirectPosition pos) {
            SubArea found = null;
            while (area.contains(pos)) {
                found = area;
                area = area.specialization;
                if (area == null) break;
            }
            return found;
        }

        /**
         * Formats the given area and its transform as a pseudo-WKT.
         * For {@link SpecializableTransform#formatTo(Formatter)} implementation only.
         */
        static void format(SubArea area, final Formatter formatter) {
            while (area != null) {
                formatter.newLine(); formatter.append(area);
                formatter.newLine(); formatter.append(area.transform);
                area = area.specialization;
            }
        }

        /**
         * For {@link SpecializableTransform#computeHashCode()} implementation.
         */
        @Override
        public int hashCode() {
            int code = super.hashCode() ^ transform.hashCode();
            if (specialization != null) {
                code += 37 * specialization.hashCode();
            }
            return code;
        }

        /**
         * For {@link SpecializableTransform#equals(Object)} implementation.
         */
        @Override
        public boolean equals(final Object obj) {
            if (super.equals(obj)) {
                final SubArea other = (SubArea) obj;
                return transform.equals(other.transform) && Objects.equals(specialization, other.specialization);
            }
            return false;
        }

        /**
         * Formats this envelope as a "{@code DOMAIN}" element (non-standard).
         * This is used by {@link SpecializableTransform#formatTo(Formatter)}.
         */
        @Override
        protected String formatTo(final Formatter formatter) {
            super.formatTo(formatter);
            return "Domain";
        }
    }

    /**
     * Domains where specialized transforms are valid. The array should be very small.
     * In current implementation, elements in this array shall not overlap.
     * This array may be replaced by an R-Tree in a future Apache SIS version.
     */
    private final SubArea[] domains;

    /**
     * The inverse of this transform, computed when first needed.
     * Part of serialization for avoiding rounding error issues.
     *
     * @see #inverse()
     */
    private MathTransform inverse;

    /**
     * Creates a new transform with the given global transform and some amount of specializations.
     *
     * @param  global  the transform to use globally where there is no suitable specialization.
     * @param  specializations  more accurate transforms available in sub-areas.
     */
    SpecializableTransform(final MathTransform global, final Map<Envelope,MathTransform> specializations) {
        this.global = global;
        final int sourceDim = global.getSourceDimensions();
        final int targetDim = global.getTargetDimensions();
        final List<SubArea> areas = new ArrayList<>(specializations.size());
        for (final Map.Entry<Envelope,MathTransform> entry : specializations.entrySet()) {
            MathTransform tr = entry.getValue();
            ensureDimensionMatches(0, sourceDim, tr.getSourceDimensions());
            ensureDimensionMatches(1, targetDim, tr.getTargetDimensions());
            SubArea[] inherited = null;
            if (tr instanceof SpecializableTransform) {
                inherited = ((SpecializableTransform) tr).domains;
                tr = ((SpecializableTransform) tr).global;
            }
            final SubArea area = new SubArea(entry.getKey(), tr);
            addSpecialization(area, areas, sourceDim);
            /*
             * At this point we are usually done for the current SubArea. But if the given MathTransform
             * is another SpecializableTransform, then instead of storing nested SpecializableTransforms
             * we will store directly the specializations that it contains.  This will reduce the amount
             * of steps when transforming coordinates.
             */
            if (inherited != null) {
                for (final SubArea other : inherited) {
                    final SubArea e = new SubArea(other, other.transform);
                    e.intersect(area);
                    addSpecialization(e, areas, sourceDim);
                }
            }
        }
        domains = areas.toArray(new SubArea[areas.size()]);
        SubArea.uniformize(domains);
    }

    /**
     * Helper method for verifying transform dimension consistency.
     *
     * @param  type  0 if verifying source dimension, or 1 if verifying target dimension.
     */
    private static void ensureDimensionMatches(final int type, final int expected, final int actual) {
        if (expected != actual) {
            throw new MismatchedDimensionException(Resources.format(
                    Resources.Keys.MismatchedTransformDimension_3, type, expected, actual));
        }
    }

    /**
     * Verifies if the given {@code area} has the expected number of dimensions,
     * then adds it to {@code domains} list (eventually as a child of an existing node).
     *
     * @param  area     the new sub-area to add.
     * @param  domains  where to add the sub-area (not necessarily directly; maybe as a child of an existing node).
     * @param  dim      expected number of dimensions, for verification purpose.
     */
    private static void addSpecialization(final SubArea area, final List<SubArea> domains, final int dim) {
        if (!area.isEmpty()) {
            if (area.getDimension() != dim) {
                throw new MismatchedDimensionException(Errors.format(Errors.Keys.MismatchedDimension_3,
                            "envelope", dim, area.getDimension()));
            }
            for (final SubArea previous : domains) {
                if (previous.addSpecialization(area)) {
                    return;
                }
            }
            for (final SubArea previous : domains) {
                if (area.intersects(previous)) {
                    // Pending implementation of R-Tree in Apache SIS.
                    throw new IllegalArgumentException("Current implementation does not accept overlapping envelopes.");
                }
            }
            domains.add(area);
        }
    }

    /**
     * Gets the dimension of input points.
     */
    @Override
    public final int getSourceDimensions() {
        return global.getSourceDimensions();
    }

    /**
     * Gets the dimension of output points.
     */
    @Override
    public final int getTargetDimensions() {
        return global.getTargetDimensions();
    }

    /**
     * Returns the transform to use for the given domain.
     */
    private MathTransform forDomain(final SubArea domain) {
        return (domain != null) ? domain.transform : global;
    }

    /**
     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
     * This method delegates to the most specialized transform.
     */
    @Override
    public final DirectPosition transform(final DirectPosition ptSrc, DirectPosition ptDst) throws TransformException {
        return forDomain(SubArea.find(domains, ptSrc)).transform(ptSrc, ptDst);
    }

    /**
     * Gets the derivative of this transform at a point.
     * This method delegates to the most specialized transform.
     */
    @Override
    public final Matrix derivative(final DirectPosition point) throws TransformException {
        return forDomain(SubArea.find(domains, point)).derivative(point);
    }

    /**
     * Transforms a single coordinate point in an array, and optionally computes the transform
     * derivative at that location. This method delegates to the most specialized transform.
     */
    @Override
    public final Matrix transform(final double[] srcPts, final int srcOff,
                                  final double[] dstPts, final int dstOff,
                                  boolean derivate) throws TransformException
    {
        final DirectPositionView pos = new DirectPositionView.Double(srcPts, srcOff, global.getSourceDimensions());
        final MathTransform tr = forDomain(SubArea.find(domains, pos));
        if (tr instanceof AbstractMathTransform) {
            return ((AbstractMathTransform) tr).transform(srcPts, srcOff, dstPts, dstOff, derivate);
        } else {
            Matrix derivative = derivate ? tr.derivative(pos) : null;       // Must be before transform(srcPts, …).
            if (dstPts != null) {
                tr.transform(srcPts, srcOff, dstPts, dstOff, 1);
            }
            return derivative;
        }
    }

    /**
     * Call of a {@code MathTransform.transform(…)} method with source and target arrays fixed at
     * {@code TransformCall} creation time. This is used for allowing the same implementation to
     * be shared by most {@code transform(…)} methods in {@link SpecializableTransform}.
     */
    @FunctionalInterface
    private interface TransformCall {
        /** Performs the transform at the given offsets. */
        void apply(MathTransform tr, int srcOff, int dstOff, int numPts) throws TransformException;
    }

    /**
     * Transforms a list of coordinate points. This method delegates to the most specialized transform,
     * with single {@code transform(…)} calls for coordinate sequences as long as possible.
     *
     * @param  transform  caller for a {@code MathTransform.transform(…)} method.
     * @param  src        a window over the source points. May be backed by a {@code float[]} or {@code double[]} array.
     * @param  dstOff     where to write the first coordinate in the target array.
     * @param  srcInc     the source dimension, negative if we must iterate backward.
     * @param  dstInc     the target dimension, negative if we must iterate backward.
     * @param  numPts     number of points to transform.
     */
    private void transform(final TransformCall transform, final DirectPositionView src,
            int dstOff, int srcInc, int dstInc, int numPts) throws TransformException
    {
        final boolean downard = (srcInc < 0);
        SubArea domain = SubArea.find(domains, src);
        while (numPts > 0) {
            int srcOff = src.offset;
            final MathTransform tr;
            if (domain == null) {
                tr = global;                               // The transform to apply when no specialization is found.
                do {                                        // Count how many points will use that transform.
                    src.offset += srcInc;
                    if (--numPts <= 0) break;
                    domain = SubArea.find(domains, src);    // More expansive check than the case where domain is non-null.
                } while (domain == null);
            } else {
                final SubArea previous = domain;
                tr = domain.transform;                      // The specialized transform to apply.
                do {                                        // Count how many points will use that transform.
                    src.offset += srcInc;
                    if (--numPts <= 0) break;
                    domain = SubArea.find(domain, src);     // Cheaper check compared to the case where domain is null.
                } while (domain == previous);
                if (domain == null) {
                    domain = SubArea.find(domains, src);    // Need to update with the more expansive check.
                }
            }
            final int num = (src.offset - srcOff) / srcInc;
            int dstLow = dstOff;
            dstOff += dstInc * num;
            if (downard) {
                srcOff = src.offset - srcInc;
                dstLow = dstOff     - dstInc;
            }
            transform.apply(tr, srcOff, dstLow, num);
        }
    }

    /**
     * Transforms a list of coordinate points.
     * This method delegates to the most specialized transform.
     */
    @Override
    public final void transform(double[] srcPts, int srcOff, final double[] dstPts, int dstOff, final int numPts)
            throws TransformException
    {
        int srcInc = getSourceDimensions();
        int dstInc = getTargetDimensions();
        if (srcPts == dstPts) {
            switch (IterationStrategy.suggest(srcOff, srcInc, dstOff, dstInc, numPts)) {
                case ASCENDING: {
                    break;
                }
                case DESCENDING: {
                    srcOff += (numPts-1) * srcInc; srcInc = -srcInc;
                    dstOff += (numPts-1) * dstInc; dstInc = -dstInc;
                    break;
                }
                default: {
                    srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*srcInc);
                    srcOff = 0;
                    break;
                }
            }
        }
        final double[] refPts = srcPts;
        transform((tr, src, dst, num) -> tr.transform(refPts, src, dstPts, dst, num),
                  new DirectPositionView.Double(srcPts, srcOff, Math.abs(srcInc)),
                  dstOff, srcInc, dstInc, numPts);
    }

    /**
     * Transforms a list of coordinate points.
     * This method delegates to the most specialized transform.
     */
    @Override
    public final void transform(float[] srcPts, int srcOff, final float[] dstPts, int dstOff, final int numPts)
            throws TransformException
    {
        int srcInc = getSourceDimensions();
        int dstInc = getTargetDimensions();
        if (srcPts == dstPts) {
            switch (IterationStrategy.suggest(srcOff, srcInc, dstOff, dstInc, numPts)) {
                case ASCENDING: {
                    break;
                }
                case DESCENDING: {
                    srcOff += (numPts-1) * srcInc; srcInc = -srcInc;
                    dstOff += (numPts-1) * dstInc; dstInc = -dstInc;
                    break;
                }
                default: {
                    srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*srcInc);
                    srcOff = 0;
                    break;
                }
            }
        }
        final float[] refPts = srcPts;
        transform((tr, src, dst, num) -> tr.transform(refPts, src, dstPts, dst, num),
                  new DirectPositionView.Float(srcPts, srcOff, Math.abs(srcInc)),
                  dstOff, srcInc, dstInc, numPts);
    }

    /**
     * Transforms a list of coordinate points. This method delegates to the most specialized transform,
     * with single {@code transform(…)} calls for coordinate sequences as long as possible.
     */
    @Override
    public final void transform(final double[] srcPts, final int srcOff,
                                final float [] dstPts, final int dstOff,
                                final int numPts) throws TransformException
    {
        final int srcDim = getSourceDimensions();
        final int dstDim = getTargetDimensions();
        transform((tr, src, dst, num) -> tr.transform(srcPts, src, dstPts, dst, num),
                  new DirectPositionView.Double(srcPts, srcOff, srcDim),
                  dstOff, srcDim, dstDim, numPts);
    }

    /**
     * Transforms a list of coordinate points. This method delegates to the most specialized transform,
     * with single {@code transform(…)} calls for coordinate sequences as long as possible.
     */
    @Override
    public final void transform(final float [] srcPts, final int srcOff,
                                final double[] dstPts, final int dstOff,
                                final int numPts) throws TransformException
    {
        final int srcDim = getSourceDimensions();
        final int dstDim = getTargetDimensions();
        transform((tr, src, dst, num) -> tr.transform(srcPts, src, dstPts, dst, num),
                  new DirectPositionView.Float(srcPts, srcOff, srcDim),
                  dstOff, srcDim, dstDim, numPts);
    }

    /**
     * Computes a hash value for this transform.
     * This method is invoked by {@link #hashCode()} when first needed.
     */
    @Override
    protected final int computeHashCode() {
        return super.computeHashCode() + 7*global.hashCode() ^ Arrays.hashCode(domains);
    }

    /**
     * Compares the specified object with this math transform for equality.
     */
    @Override
    public final boolean equals(final Object object, final ComparisonMode mode) {
        if (super.equals(object, mode)) {
            final SpecializableTransform other = (SpecializableTransform) object;
            return Utilities.deepEquals(global, other.global, mode) &&
                   Utilities.deepEquals(domains, other.domains, mode);
        }
        return false;
    }

    /**
     * Formats the inner part of a <cite>Well Known Text</cite> version 1 (WKT 1) element.
     *
     * <div class="note"><b>Compatibility note:</b>
     * The {@code SPECIALIZABLE_MT} element formatted here is an Apache SIS-specific extension.</div>
     *
     * @param  formatter  the formatter to use.
     * @return the WKT element name, which is {@code "Specializable_MT"}.
     */
    @Override
    protected final String formatTo(final Formatter formatter) {
        formatter.newLine();
        formatter.append(global);
        for (SubArea domain : domains) {
            SubArea.format(domain, formatter);
        }
        formatter.setInvalidWKT(SpecializableTransform.class, null);
        return "Specializable_MT";
    }

    /**
     * Returns the inverse of this transform.
     */
    @Override
    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
        if (inverse == null) {
            inverse = createInverse();
        }
        return inverse;
    }

    /**
     * Invoked at construction time for creating the inverse transform.
     * Overridden by {@link SpecializableTransform2D} for the two-dimensional variant.
     */
    Inverse createInverse() throws NoninvertibleTransformException {
        return new Inverse(this);
    }

    /**
     * The inverse of {@link SpecializableTransform}.
     */
    static class Inverse extends AbstractMathTransform.Inverse implements Serializable {
        /**
         * For cross-version compatibility.
         */
        private static final long serialVersionUID = 1060617594604917167L;

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

        /**
         * The inverse of {@link SpecializableTransform#global}.
         */
        private final MathTransform global;

        /**
         * Creates the inverse of a specialized transform having the given properties.
         */
        Inverse(final SpecializableTransform forward) throws NoninvertibleTransformException {
            this.forward = forward;
            this.global = forward.global.inverse();
            for (final SubArea domain : forward.domains) {
                SubArea.createInverse(domain);
            }
        }

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

        /**
         * Inverse transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
         */
        @Override
        public final DirectPosition transform(final DirectPosition ptSrc, DirectPosition ptDst) throws TransformException {
            final double[] source = ptSrc.getCoordinate();      // Needs to be first in case ptDst overwrites ptSrc.
            ptDst = global.transform(ptSrc, ptDst);
            final SubArea domain = SubArea.find(forward.domains, ptDst);
            if (domain != null) {
                ptDst = domain.inverse.transform(new DirectPositionView.Double(source), ptDst);
            }
            return ptDst;
        }

        /**
         * Gets the inverse derivative of this transform at a point.
         * This method is overridden for consistency.
         */
        @Override
        public final Matrix derivative(final DirectPosition point) throws TransformException {
            return transform(point.getCoordinate(), 0, null, 0, true);
        }

        /**
         * Inverse transforms a single coordinate point in an array, and optionally computes the transform
         * derivative at that location.
         */
        @Override
        public final Matrix transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, final boolean derivate)
                throws TransformException
        {
            final int srcInc = global.getSourceDimensions();
            final int dstInc = global.getTargetDimensions();
            if (dstPts == null) {
                dstPts = new double[dstInc];                    // Needed for checking if inside a sub-area.
                dstOff = 0;
            } else if (srcPts == dstPts && srcOff + srcInc > dstOff && srcOff < dstOff + dstInc) {
                srcPts = Arrays.copyOfRange(srcPts, srcOff, srcInc);
                srcOff = 0;
            }
            /*
             * Above 'srcPts' dhould keep the source coordinates unchanged even if the source and destination
             * given in arguments overlap.  We need this stability because the source coordinates may be used
             * twice, if 'secondTry' become true.
             */
            MathTransform tr = global;
            boolean secondTry = false;
            Matrix derivative;
            do {
                if (tr instanceof AbstractMathTransform) {
                    derivative = ((AbstractMathTransform) tr).transform(srcPts, srcOff, dstPts, dstOff, derivate);
                } else {
                    tr.transform(srcPts, srcOff, dstPts, dstOff, 1);
                    derivative = derivate ? tr.derivative(new DirectPositionView.Double(srcPts, srcOff, srcInc)) : null;
                }
                if (secondTry) break;
                final SubArea domain = SubArea.find(forward.domains, new DirectPositionView.Double(dstPts, dstOff, dstInc));
                if (domain != null) {
                    tr = domain.inverse;
                    secondTry = true;
                }
            } while (secondTry);
            return derivative;
        }

        /**
         * Invoked for transforming, then verifying if more appropriate transform exists for the result.
         * This implementation is similar to the algorithm applied by {@link SpecializableTransform} parent
         * class, except that {@link SubArea} is verified <em>after</em> transformations instead than before.
         */
        private void transform(final TransformCall transform, final double[] dstPts,
                int srcOff, int dstOff, int srcInc, int dstInc, int numPts) throws TransformException
        {
            final SubArea[] domains = forward.domains;
            transform.apply(global, srcOff, dstOff, numPts);
            final DirectPositionView dst = new DirectPositionView.Double(dstPts, dstOff, dstInc);
            while (numPts > 0) {
                SubArea domain = SubArea.find(domains, dst);
                if (domain == null) {
                    dst.offset += dstInc;
                    numPts--;
                    continue;
                }
                do {
                    final SubArea specialized = domain;             // Contains the specialized transform to use.
                    int num = (dst.offset - dstOff) / dstInc;       // Number of points that are not retransformeD.
                    srcOff += num * srcInc;                         // Skip the source coordinates that are not retransformed.
                    dstOff = dst.offset;                            // Destination index of the first coordinate to retransform.
                    do {
                        dst.offset += dstInc;                       // Destination index after the last coordinate to transform.
                        if (--numPts <= 0) {
                            domain = null;
                            break;
                        }
                        domain = SubArea.find(domain, dst);
                    } while (domain == specialized);
                    num = (dst.offset - dstOff) / dstInc;           // Number of points to retransform.
                    transform.apply(specialized.inverse, srcOff, dstOff, num);
                    srcOff += srcInc * num;
                    dstOff = dst.offset;
                } while (domain != null);
            }
        }

        /**
         * Inverse transforms a list of coordinate points.
         * The transformed points are written directly in the destination array.
         */
        @Override
        public void transform(double[] srcPts, int srcOff, final double[] dstPts, final int dstOff, final int numPts)
                throws TransformException
        {
            if (numPts <= 0) return;
            final int srcInc = global.getSourceDimensions();
            final int dstInc = global.getTargetDimensions();
            if (srcPts == dstPts) {
                final int srcEnd = srcOff + numPts*srcInc;
                if (srcEnd > dstOff || dstOff + numPts*dstInc > srcOff) {
                    srcPts = Arrays.copyOfRange(srcPts, srcOff, srcEnd);
                    srcOff = 0;
                }
            }
            final double[] refPts = srcPts;
            transform((tr, src, dst, num) -> tr.transform(refPts, src, dstPts, dst, num),
                      dstPts, srcOff, dstOff, srcInc, dstInc, numPts);
        }

        /**
         * Inverse transforms a list of coordinate points. This method uses an temporary {@code double[]} buffer
         * for testing {@code SubArea} inclusion with full precision before to cast to {@code float} values.
         */
        @Override
        public void transform(final float[] srcPts, int srcOff,
                              final float[] dstPts, int dstOff, int numPts)
                throws TransformException
        {
            if (numPts <= 0) return;
            final int srcInc = global.getSourceDimensions();
            final int dstInc = global.getTargetDimensions();
            final double[] buffer = new double[numPts * dstInc];
            transform((tr, src, dst, num) -> tr.transform(srcPts, src, buffer, dst, num),
                      buffer, srcOff, 0, srcInc, dstInc, numPts);

            numPts *= dstInc;
            for (int i=0; i<numPts; i++) {
                dstPts[dstOff++] = (float) buffer[i];
            }
        }

        /**
         * Inverse transforms a list of coordinate points. This method uses an temporary {@code double[]} buffer
         * for testing {@code SubArea} inclusion with full precision before to cast to {@code float} values.
         */
        @Override
        public void transform(final double[] srcPts, int srcOff,
                              final float [] dstPts, int dstOff, int numPts) throws TransformException
        {
            if (numPts <= 0) return;
            final int srcInc = global.getSourceDimensions();
            final int dstInc = global.getTargetDimensions();
            final double[] buffer = new double[numPts * dstInc];
            transform((tr, src, dst, num) -> tr.transform(srcPts, src, buffer, dst, num),
                      buffer, srcOff, 0, srcInc, dstInc, numPts);

            numPts *= dstInc;
            for (int i=0; i<numPts; i++) {
                dstPts[dstOff++] = (float) buffer[i];
            }
        }

        /**
         * Inverse transforms a list of coordinate points.
         * The transformed points are written directly in the destination array.
         */
        @Override
        public void transform(final float [] srcPts, int srcOff,
                              final double[] dstPts, int dstOff, int numPts) throws TransformException
        {
            if (numPts <= 0) return;
            final int srcInc = global.getSourceDimensions();
            final int dstInc = global.getTargetDimensions();
            transform((tr, src, dst, num) -> tr.transform(srcPts, src, dstPts, dst, num),
                      dstPts, srcOff, dstOff, srcInc, dstInc, numPts);
        }
    }
}
