/*
 * 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.commons.geometry.spherical.twod;

import java.io.Serializable;

import org.apache.commons.geometry.core.Transform;
import org.apache.commons.geometry.euclidean.threed.AffineTransformMatrix3D;
import org.apache.commons.geometry.euclidean.threed.Vector3D;
import org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;

/** Implementation of the {@link Transform} interface for spherical 2D points.
 *
 * <p>This class uses an {@link AffineTransformMatrix3D} to perform spherical point transforms
 * in Euclidean 3D space.</p>
 *
 * <p>Instances of this class are guaranteed to be immutable.</p>
 */
public final class Transform2S implements Transform<Point2S>, Serializable {

    /** Serializable UID. */
    private static final long serialVersionUID = 1L;

    /** Static instance representing the identity transform. */
    private static final Transform2S IDENTITY = new Transform2S(AffineTransformMatrix3D.identity());

    /** Static transform instance that reflects across the x-y plane. */
    private static final AffineTransformMatrix3D XY_PLANE_REFLECTION = AffineTransformMatrix3D.createScale(1, 1, -1);

    /** Euclidean transform matrix underlying the spherical transform. */
    private final AffineTransformMatrix3D euclideanTransform;

    /** Construct a new instance from its underlying Euclidean transform.
     * @param euclideanTransform underlying Euclidean transform
     */
    private Transform2S(final AffineTransformMatrix3D euclideanTransform) {
        this.euclideanTransform = euclideanTransform;
    }

    /** Get the Euclidean transform matrix underlying the spherical transform.
     * @return the Euclidean transform matrix underlying the spherical transform
     */
    public AffineTransformMatrix3D getEuclideanTransform() {
        return euclideanTransform;
    }

    /** {@inheritDoc} */
    @Override
    public Point2S apply(final Point2S pt) {
        final Vector3D vec = pt.getVector();
        return Point2S.from(euclideanTransform.apply(vec));
    }

    /** {@inheritDoc} */
    @Override
    public boolean preservesOrientation() {
        return euclideanTransform.preservesOrientation();
    }

    /** Return a new instance representing the inverse transform operation
     * of this instance.
     * @return a transform representing the inverse of this instance
     */
    public Transform2S inverse() {
        return new Transform2S(euclideanTransform.inverse());
    }

    /** Apply a rotation of {@code angle} radians around the given point to this instance.
     * @param pt point to rotate around
     * @param angle rotation angle in radians
     * @return transform resulting from applying the specified rotation to this instance
     */
    public Transform2S rotate(final Point2S pt, final double angle) {
        return premultiply(createRotation(pt, angle));
    }

    /** Apply a rotation of {@code angle} radians around the given 3D axis to this instance.
     * @param axis 3D axis of rotation
     * @param angle rotation angle in radians
     * @return transform resulting from applying the specified rotation to this instance
     */
    public Transform2S rotate(final Vector3D axis, final double angle) {
        return premultiply(createRotation(axis, angle));
    }

    /** Apply the given quaternion rotation to this instance.
     * @param quaternion quaternion rotation to apply
     * @return transform resulting from applying the specified rotation to this instance
     */
    public Transform2S rotate(final QuaternionRotation quaternion) {
        return premultiply(createRotation(quaternion));
    }

    /** Apply a reflection across the equatorial plane defined by the given pole point
     * to this instance.
     * @param pole pole point defining the equatorial reflection plane
     * @return transform resulting from applying the specified reflection to this instance
     */
    public Transform2S reflect(final Point2S pole) {
        return premultiply(createReflection(pole));
    }

    /** Apply a reflection across the equatorial plane defined by the given pole vector
     * to this instance.
     * @param poleVector pole vector defining the equatorial reflection plane
     * @return transform resulting from applying the specified reflection to this instance
     */
    public Transform2S reflect(final Vector3D poleVector) {
        return premultiply(createReflection(poleVector));
    }

    /** Multiply the underlying Euclidean transform of this instance by that of the argument, eg,
     * {@code other * this}. The returned transform performs the equivalent of
     * {@code other} followed by {@code this}.
     * @param other transform to multiply with
     * @return a new transform computed by multiplying the matrix of this
     *      instance by that of the argument
     * @see AffineTransformMatrix3D#multiply(AffineTransformMatrix3D)
     */
    public Transform2S multiply(final Transform2S other) {
        return multiply(this, other);
    }

    /** Multiply the underlying Euclidean transform matrix of the argument by that of this instance, eg,
     * {@code this * other}. The returned transform performs the equivalent of {@code this}
     * followed by {@code other}.
     * @param other transform to multiply with
     * @return a new transform computed by multiplying the matrix of the
     *      argument by that of this instance
     * @see AffineTransformMatrix3D#premultiply(AffineTransformMatrix3D)
     */
    public Transform2S premultiply(final Transform2S other) {
        return multiply(other, this);
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return euclideanTransform.hashCode();
    }

    /**
     * Return true if the given object is an instance of {@link Transform2S}
     * and the underlying Euclidean transform matrices are exactly equal.
     * @param obj object to test for equality with the current instance
     * @return true if the underlying transform matrices are exactly equal
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Transform2S)) {
            return false;
        }
        final Transform2S other = (Transform2S) obj;

        return euclideanTransform.equals(other.euclideanTransform);
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();

        sb.append(this.getClass().getSimpleName())
            .append("[euclideanTransform= ")
            .append(getEuclideanTransform())
            .append("]");

        return sb.toString();
    }

    /** Return an instance representing the identity transform. This transform is guaranteed
     * to return an <em>equivalent</em> (ie, co-located) point for any input point. However, the
     * points are not guaranteed to contain exactly equal coordinates. For example, at the poles, an
     * infinite number of points exist that vary only in the azimuth coordinate. When one of these
     * points is transformed by this identity transform, the returned point may contain a different
     * azimuth value from the input, but it will still represent the same location in space.
     * @return an instance representing the identity transform
     */
    public static Transform2S identity() {
        return IDENTITY;
    }

    /** Create a transform that rotates the given angle around {@code pt}.
     * @param pt point to rotate around
     * @param angle angle of rotation in radians
     * @return a transform that rotates the given angle around {@code pt}
     */
    public static Transform2S createRotation(final Point2S pt, final double angle) {
        return createRotation(pt.getVector(), angle);
    }

    /** Create a transform that rotates the given angle around {@code axis}.
     * @param axis 3D axis of rotation
     * @param angle angle of rotation in radians
     * @return a transform that rotates the given angle {@code axis}
     */
    public static Transform2S createRotation(final Vector3D axis, final double angle) {
        return createRotation(QuaternionRotation.fromAxisAngle(axis, angle));
    }

    /** Create a transform that performs the given 3D rotation.
     * @param quaternion quaternion instance representing the 3D rotation
     * @return a transform that performs the given 3D rotation
     */
    public static Transform2S createRotation(final QuaternionRotation quaternion) {
        return new Transform2S(quaternion.toMatrix());
    }

    /** Create a transform that performs a reflection across the equatorial plane
     * defined by the given pole point.
     * @param pole pole point defining the equatorial reflection plane
     * @return a transform that performs a reflection across the equatorial plane
     *      defined by the given pole point
     */
    public static Transform2S createReflection(final Point2S pole) {
        return createReflection(pole.getVector());
    }

    /** Create a transform that performs a reflection across the equatorial plane
     * defined by the given pole point.
     * @param poleVector pole vector defining the equatorial reflection plane
     * @return a transform that performs a reflection across the equatorial plane
     *      defined by the given pole point
     */
    public static Transform2S createReflection(final Vector3D poleVector) {
        final QuaternionRotation quat = QuaternionRotation.createVectorRotation(poleVector, Vector3D.Unit.PLUS_Z);

        final AffineTransformMatrix3D matrix = quat.toMatrix()
                .premultiply(XY_PLANE_REFLECTION)
                .premultiply(quat.inverse().toMatrix());

        return new Transform2S(matrix);
    }

    /** Multiply the Euclidean transform matrices of the arguments together.
     * @param a first transform
     * @param b second transform
     * @return the transform computed as {@code a x b}
     */
    private static Transform2S multiply(final Transform2S a, final Transform2S b) {

        final AffineTransformMatrix3D aMat = a.euclideanTransform;
        final AffineTransformMatrix3D bMat = b.euclideanTransform;

        return new Transform2S(aMat.multiply(bMat));
    }
}
