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

import java.util.Objects;

import org.apache.commons.geometry.core.Embedding;
import org.apache.commons.geometry.core.Transform;
import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
import org.apache.commons.geometry.euclidean.oned.AffineTransformMatrix1D;
import org.apache.commons.geometry.euclidean.oned.Interval;
import org.apache.commons.geometry.euclidean.oned.Vector1D;

/** Class representing a line in 3D space.
 *
 * <p>Instances of this class are guaranteed to be immutable.</p>
 */
public final class Line3D implements Embedding<Vector3D, Vector1D> {
    /** Line point closest to the origin. */
    private final Vector3D origin;

    /** Line direction. */
    private final Vector3D direction;

    /** Precision context used to compare floating point numbers. */
    private final DoublePrecisionContext precision;

    /** Simple constructor.
     * @param origin the origin of the line, meaning the point on the line closest to the origin of the
     *      3D space
     * @param direction the direction of the line
     * @param precision precision context used to compare floating point numbers
     */
    private Line3D(final Vector3D origin, final Vector3D direction, final DoublePrecisionContext precision) {
        this.origin = origin;
        this.direction = direction;
        this.precision = precision;
    }

    /** Get the line point closest to the origin.
     * @return line point closest to the origin
     */
    public Vector3D getOrigin() {
        return origin;
    }

    /** Get the normalized direction vector.
     * @return normalized direction vector
     */
    public Vector3D getDirection() {
        return direction;
    }

    /** Get the object used to determine floating point equality for this instance.
     * @return the floating point precision context for the instance
     */
    public DoublePrecisionContext getPrecision() {
        return precision;
    }

    /** Return a line containing the same points as this instance but pointing
     * in the opposite direction.
     * @return an instance containing the same points but pointing in the opposite
     *      direction
     */
    public Line3D reverse() {
        return new Line3D(origin, direction.negate(), precision);
    }

    /** Transform this instance.
     * @param transform object used to transform the instance
     * @return a transformed instance
     */
    public Line3D transform(final Transform<Vector3D> transform) {
        final Vector3D p1 = transform.apply(origin);
        final Vector3D p2 = transform.apply(origin.add(direction));

        return fromPoints(p1, p2, precision);
    }

    /** Get an object containing the current line transformed by the argument along with a
     * 1D transform that can be applied to subspace points. The subspace transform transforms
     * subspace points such that their 3D location in the transformed line is the same as their
     * 3D location in the original line after the 3D transform is applied. For example, consider
     * the code below:
     * <pre>
     *      SubspaceTransform st = line.subspaceTransform(transform);
     *
     *      Vector1D subPt = Vector1D.of(1);
     *
     *      Vector3D a = transform.apply(line.toSpace(subPt)); // transform in 3D space
     *      Vector3D b = st.getLine().toSpace(st.getTransform().apply(subPt)); // transform in 1D space
     * </pre>
     * At the end of execution, the points {@code a} (which was transformed using the original
     * 3D transform) and {@code b} (which was transformed in 1D using the subspace transform)
     * are equivalent.
     *
     * @param transform the transform to apply to this instance
     * @return an object containing the transformed line along with a transform that can be applied
     *      to subspace points
     * @see #transform(Transform)
     */
    public SubspaceTransform subspaceTransform(final Transform<Vector3D> transform) {
        final Vector3D p1 = transform.apply(origin);
        final Vector3D p2 = transform.apply(origin.add(direction));

        final Line3D tLine = fromPoints(p1, p2, precision);

        final Vector1D tSubspaceOrigin = tLine.toSubspace(p1);
        final Vector1D tSubspaceDirection = tSubspaceOrigin.vectorTo(tLine.toSubspace(p2));

        final double translation = tSubspaceOrigin.getX();
        final double scale = tSubspaceDirection.getX();

        final AffineTransformMatrix1D subspaceTransform = AffineTransformMatrix1D.of(scale, translation);

        return new SubspaceTransform(tLine, subspaceTransform);
    }

    /** Get the abscissa of the given point on the line. The abscissa represents
     * the distance the projection of the point on the line is from the line's
     * origin point (the point on the line closest to the origin of the
     * 2D space). Abscissa values increase in the direction of the line. This method
     * is exactly equivalent to {@link #toSubspace(Vector3D)} except that this method
     * returns a double instead of a {@link Vector1D}.
     * @param point point to compute the abscissa for
     * @return abscissa value of the point
     * @see #toSubspace(Vector3D)
     */
    public double abscissa(final Vector3D point) {
        return point.subtract(origin).dot(direction);
    }

    /** Get one point from the line.
     * @param abscissa desired abscissa for the point
     * @return one point belonging to the line, at specified abscissa
     */
    public Vector3D pointAt(final double abscissa) {
        return Vector3D.linearCombination(1.0, origin, abscissa, direction);
    }

    /** {@inheritDoc} */
    @Override
    public Vector1D toSubspace(Vector3D pt) {
        return Vector1D.of(abscissa(pt));
    }

    /** {@inheritDoc} */
    @Override
    public Vector3D toSpace(Vector1D pt) {
        return toSpace(pt.getX());
    }

    /** Get the 3 dimensional point at the given abscissa position
     * on the line.
     * @param abscissa location on the line
     * @return the 3 dimensional point at the given abscissa position
     *      on the line
     */
    public Vector3D toSpace(final double abscissa) {
        return pointAt(abscissa);
    }

    /** Check if the instance is similar to another line.
     * <p>Lines are considered similar if they contain the same
     * points. This does not mean they are equal since they can have
     * opposite directions.</p>
     * @param line line to which instance should be compared
     * @return true if the lines are similar
     */
    public boolean isSimilarTo(final Line3D line) {
        final double angle = direction.angle(line.direction);
        return (precision.eqZero(angle) || precision.eq(Math.abs(angle), Math.PI)) &&
                contains(line.origin);
    }

    /** Check if the instance contains a point.
     * @param pt point to check
     * @return true if p belongs to the line
     */
    public boolean contains(final Vector3D pt) {
        return precision.eqZero(distance(pt));
    }

    /** Compute the distance between the instance and a point.
     * @param pt to check
     * @return distance between the instance and the point
     */
    public double distance(final Vector3D pt) {
        final Vector3D delta = pt.subtract(origin);
        final Vector3D orthogonal = delta.reject(direction);

        return orthogonal.norm();
    }

    /** Compute the shortest distance between the instance and another line.
     * @param line line to check against the instance
     * @return shortest distance between the instance and the line
     */
    public double distance(final Line3D line) {

        final Vector3D normal = direction.cross(line.direction);
        final double norm = normal.norm();

        if (precision.eqZero(norm)) {
            // the lines are parallel
            return distance(line.origin);
        }

        // signed separation of the two parallel planes that contains the lines
        final double offset = line.origin.subtract(origin).dot(normal) / norm;

        return Math.abs(offset);
    }

    /** Compute the point of the instance closest to another line.
     * @param line line to check against the instance
     * @return point of the instance closest to another line
     */
    public Vector3D closest(final Line3D line) {

        final double cos = direction.dot(line.direction);
        final double n = 1 - cos * cos;

        if (precision.eqZero(n)) {
            // the lines are parallel
            return origin;
        }

        final Vector3D delta = line.origin.subtract(origin);
        final double a = delta.dot(direction);
        final double b = delta.dot(line.direction);

        return Vector3D.linearCombination(1, origin, (a - (b * cos)) / n, direction);
    }

    /** Get the intersection point of the instance and another line.
     * @param line other line
     * @return intersection point of the instance and the other line
     * or null if there are no intersection points
     */
    public Vector3D intersection(final Line3D line) {
        final Vector3D closestPt = closest(line);
        return line.contains(closestPt) ? closestPt : null;
    }

    /** Return a new infinite segment representing the entire line.
     * @return a new infinite segment representing the entire line
     */
    public Segment3D span() {
        return Segment3D.fromInterval(this, Interval.full());
    }

    /** Create a new line segment from the given interval.
     * @param interval interval representing the 1D region for the line segment
     * @return a new line segment on this line
     */
    public Segment3D segment(final Interval interval) {
        return Segment3D.fromInterval(this, interval);
    }

    /** Create a new line segment from the given interval.
     * @param a first 1D location for the interval
     * @param b second 1D location for the interval
     * @return a new line segment on this line
     */
    public Segment3D segment(final double a, final double b) {
        return Segment3D.fromInterval(this, a, b);
    }

    /** Create a new line segment between the projections of the two
     * given points onto this line.
     * @param a first point
     * @param b second point
     * @return a new line segment on this line
     */
    public Segment3D segment(final Vector3D a, final Vector3D b) {
        return Segment3D.fromInterval(this, toSubspace(a), toSubspace(b));
    }

    /** Create a new line segment that starts at infinity and continues along
     * the line up to the projection of the given point.
     * @param pt point defining the end point of the line segment; the end point
     *      is equal to the projection of this point onto the line
     * @return a new, half-open line segment
     */
    public Segment3D segmentTo(final Vector3D pt) {
        return segment(Double.NEGATIVE_INFINITY, toSubspace(pt).getX());
    }

    /** Create a new line segment that starts at the projection of the given point
     * and continues in the direction of the line to infinity, similar to a ray.
     * @param pt point defining the start point of the line segment; the start point
     *      is equal to the projection of this point onto the line
     * @return a new, half-open line segment
     */
    public Segment3D segmentFrom(final Vector3D pt) {
        return segment(toSubspace(pt).getX(), Double.POSITIVE_INFINITY);
    }

    /** Create a new, empty subline based on this line.
     * @return a new, empty subline based on this line
     */
    public SubLine3D subline() {
        return new SubLine3D(this);
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return Objects.hash(origin, direction, precision);
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Line3D)) {
            return false;
        }
        Line3D other = (Line3D) obj;
        return this.origin.equals(other.origin) &&
                this.direction.equals(other.direction) &&
                this.precision.equals(other.precision);
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName())
            .append("[origin= ")
            .append(origin)
            .append(", direction= ")
            .append(direction)
            .append("]");

        return sb.toString();
    }

    /** Create a new line instance from two points that lie on the line. The line
     * direction points from the first point to the second point.
     * @param p1 first point on the line
     * @param p2 second point on the line
     * @param precision floating point precision context
     * @return a new line instance that contains both of the given point and that has
     *      a direction going from the first point to the second point
     * @throws org.apache.commons.geometry.core.exception.IllegalNormException if the points lie too close to
     *      create a non-zero direction vector
     */
    public static Line3D fromPoints(final Vector3D p1, final Vector3D p2,
            final DoublePrecisionContext precision) {
        return fromPointAndDirection(p1, p1.directionTo(p2), precision);
    }

    /** Create a new line instance from a point and a direction.
     * @param pt a point lying on the line
     * @param direction the direction of the line
     * @param precision floating point precision context
     * @return a new line instance that contains the given point and points in the
     *      given direction
     * @throws org.apache.commons.geometry.core.exception.IllegalNormException if the direction cannot be normalized
     */
    public static Line3D fromPointAndDirection(final Vector3D pt, final Vector3D direction,
            final DoublePrecisionContext precision) {

        final Vector3D normDirection = direction.normalize();
        final Vector3D origin = pt.reject(normDirection);

        return new Line3D(origin, normDirection, precision);
    }

    /** Class containing a transformed line instance along with a subspace (1D) transform. The subspace
     * transform produces the equivalent of the 3D transform in 1D.
     */
    public static final class SubspaceTransform {
        /** The transformed line. */
        private final Line3D line;

        /** The subspace transform instance. */
        private final AffineTransformMatrix1D transform;

        /** Simple constructor.
         * @param line the transformed line
         * @param transform 1D transform that can be applied to subspace points
         */
        public SubspaceTransform(final Line3D line, final AffineTransformMatrix1D transform) {
            this.line = line;
            this.transform = transform;
        }

        /** Get the transformed line instance.
         * @return the transformed line instance
         */
        public Line3D getLine() {
            return line;
        }

        /** Get the 1D transform that can be applied to subspace points. This transform can be used
         * to perform the equivalent of the 3D transform in 1D space.
         * @return the subspace transform instance
         */
        public AffineTransformMatrix1D getTransform() {
            return transform;
        }
    }
}
