/*
 * 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.Arrays;
import java.util.Collection;
import java.util.List;

import org.apache.commons.geometry.core.Transform;
import org.apache.commons.geometry.core.partitioning.ConvexSubHyperplane;
import org.apache.commons.geometry.core.partitioning.Hyperplane;
import org.apache.commons.geometry.core.partitioning.Split;
import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
import org.apache.commons.geometry.euclidean.threed.Plane.SubspaceTransform;
import org.apache.commons.geometry.euclidean.twod.AffineTransformMatrix2D;
import org.apache.commons.geometry.euclidean.twod.ConvexArea;
import org.apache.commons.geometry.euclidean.twod.Vector2D;

/** Class representing a convex subhyperplane in 3 dimensional Euclidean space, meaning
 * a 2D convex area embedded in a plane.
 */
public final class ConvexSubPlane extends AbstractSubPlane<ConvexArea>
    implements ConvexSubHyperplane<Vector3D>  {
    /** The embedded 2D area. */
    private final ConvexArea area;

    /** Create a new instance from its component parts.
     * @param plane plane the the convex area is embedded in
     * @param area the embedded convex area
     */
    private ConvexSubPlane(final Plane plane, final ConvexArea area) {
        super(plane);

        this.area = area;
    }

    /** {@inheritDoc} */
    @Override
    public List<ConvexSubPlane> toConvex() {
        return Arrays.asList(this);
    }

    /** {@inheritDoc} */
    @Override
    public ConvexSubPlane reverse() {
        final Plane plane = getPlane();
        final Plane rPlane = plane.reverse();

        final Vector2D rU = rPlane.toSubspace(plane.toSpace(Vector2D.Unit.PLUS_X));
        final Vector2D rV = rPlane.toSubspace(plane.toSpace(Vector2D.Unit.PLUS_Y));

        final AffineTransformMatrix2D transform =
                AffineTransformMatrix2D.fromColumnVectors(rU, rV);

        return new ConvexSubPlane(rPlane, area.transform(transform));
    }

    /** {@inheritDoc} */
    @Override
    public ConvexSubPlane transform(final Transform<Vector3D> transform) {
        final SubspaceTransform st = getPlane().subspaceTransform(transform);
        final ConvexArea tArea = area.transform(st.getTransform());

        return fromConvexArea(st.getPlane(), tArea);
    }

    /** {@inheritDoc} */
    @Override
    public ConvexArea getSubspaceRegion() {
        return area;
    }

    /** {@inheritDoc} */
    @Override
    public Split<ConvexSubPlane> split(Hyperplane<Vector3D> splitter) {
        return splitInternal(splitter, this, (p, r) -> new ConvexSubPlane(p, (ConvexArea) r));
    }

    /** Get the vertices for the subplane. The vertices lie at the intersections of the
     * 2D area bounding lines.
     * @return the vertices for the subplane
     */
    public List<Vector3D> getVertices() {
        return getPlane().toSpace(area.getVertices());
    }

    /** Create a new instance from a plane and an embedded convex subspace area.
     * @param plane embedding plane for the area
     * @param area area embedded in the plane
     * @return a new convex sub plane instance
     */
    public static ConvexSubPlane fromConvexArea(final Plane plane, final ConvexArea area) {
        return new ConvexSubPlane(plane, area);
    }

    /** Create a new instance from the given sequence of points. The points must define a unique plane, meaning that
    * at least 3 unique vertices must be given. In contrast with the
    * {@link #fromVertices(Collection, DoublePrecisionContext)} method, the first point in the sequence is included
    * at the end if needed, in order to form a closed loop.
    * @param pts collection of points defining the convex subplane
    * @param precision precision context used to compare floating point values
    * @return a new instance defined by the given sequence of vertices
    * @throws IllegalArgumentException if fewer than 3 vertices are given
    * @throws org.apache.commons.geometry.core.exception.GeometryException if the vertices do not define a
    *       unique plane
    * @see #fromVertices(Collection, DoublePrecisionContext)
    * @see #fromVertices(Collection, boolean, DoublePrecisionContext)
    * @see Plane#fromPoints(Collection, DoublePrecisionContext)
    */
    public static ConvexSubPlane fromVertexLoop(final Collection<Vector3D> pts,
            final DoublePrecisionContext precision) {
        return fromVertices(pts, true, precision);
    }

    /** Create a new instance from the given sequence of points. The points must define a unique plane, meaning that
     * at least 3 unique vertices must be given.
     * @param pts collection of points defining the convex subplane
     * @param precision precision context used to compare floating point values
     * @return a new instance defined by the given sequence of vertices
     * @throws IllegalArgumentException if fewer than 3 vertices are given
     * @throws org.apache.commons.geometry.core.exception.GeometryException if the vertices do not define a
     *      unique plane
     * @see #fromVertexLoop(Collection, DoublePrecisionContext)
     * @see #fromVertices(Collection, boolean, DoublePrecisionContext)
     * @see Plane#fromPoints(Collection, DoublePrecisionContext)
     */
    public static ConvexSubPlane fromVertices(final Collection<Vector3D> pts,
            final DoublePrecisionContext precision) {
        return fromVertices(pts, false, precision);
    }

    /** Create a new instance from the given sequence of points. The points must define a unique plane, meaning that
     * at least 3 unique vertices must be given. If {@code close} is true, the vertices are made into a closed loop
     * by including the start point at the end if needed.
     * @param pts collection of points
     * @param close if true, the point sequence will implicitly include the start point again at the end; otherwise
     *      the vertex sequence is taken as-is
     * @param precision precision context used to compare floating point values
     * @return a new convex subplane instance
     * @see #fromVertexLoop(Collection, DoublePrecisionContext)
     * @see #fromVertices(Collection, DoublePrecisionContext)
     * @see Plane#fromPoints(Collection, DoublePrecisionContext)
     */
    public static ConvexSubPlane fromVertices(final Collection<Vector3D> pts, final boolean close,
            final DoublePrecisionContext precision) {

        final Plane plane = Plane.fromPoints(pts, precision);

        final List<Vector2D> subspacePts = plane.toSubspace(pts);
        final ConvexArea area = ConvexArea.fromVertices(subspacePts, close, precision);

        return new ConvexSubPlane(plane, area);
    }
}
