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

import org.apache.commons.geometry.core.Transform;
import org.apache.commons.geometry.core.exception.GeometryException;
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.partitioning.SubHyperplane;
import org.apache.commons.geometry.euclidean.twod.ConvexArea;
import org.apache.commons.geometry.euclidean.twod.RegionBSPTree2D;

/** Class representing an arbitrary region of a plane. This class can represent
 * both convex and non-convex regions of its underlying plane.
 *
 * <p>This class is mutable and <em>not</em> thread safe.</p>
 */
public final class SubPlane extends AbstractSubPlane<RegionBSPTree2D> {
    /** The 2D region representing the area on the plane. */
    private final RegionBSPTree2D region;

    /** Construct a new, empty subplane for the given plane.
     * @param plane plane defining the subplane
     */
    public SubPlane(final Plane plane) {
        this(plane, false);
    }

    /** Construct a new subplane for the given plane. If {@code full}
     * is true, then the subplane will cover the entire plane; otherwise,
     * it will be empty.
     * @param plane plane defining the subplane
     * @param full if true, the subplane will cover the entire space;
     *      otherwise it will be empty
     */
    public SubPlane(final Plane plane, boolean full) {
        this(plane, new RegionBSPTree2D(full));
    }

    /** Construct a new instance from its defining plane and subspace region.
     * @param plane plane defining the subplane
     * @param region subspace region for the subplane
     */
    public SubPlane(final Plane plane, final RegionBSPTree2D region) {
        super(plane);

        this.region = region;
    }

    /** {@inheritDoc} */
    @Override
    public List<ConvexSubPlane> toConvex() {
        final List<ConvexArea> areas = region.toConvex();

        final Plane plane = getPlane();
        final List<ConvexSubPlane> subplanes = new ArrayList<>(areas.size());

        for (final ConvexArea area : areas) {
            subplanes.add(ConvexSubPlane.fromConvexArea(plane, area));
        }

        return subplanes;
    }

    /** {@inheritDoc}
     *
     * <p>In all cases, the current instance is not modified. However, In order to avoid
     * unnecessary copying, this method will use the current instance as the split value when
     * the instance lies entirely on the plus or minus side of the splitter. For example, if
     * this instance lies entirely on the minus side of the splitter, the subplane
     * returned by {@link Split#getMinus()} will be this instance. Similarly, {@link Split#getPlus()}
     * will return the current instance if it lies entirely on the plus side. Callers need to make
     * special note of this, since this class is mutable.</p>
     */
    @Override
    public Split<SubPlane> split(final Hyperplane<Vector3D> splitter) {
        return splitInternal(splitter, this, (p, r) -> new SubPlane(p, (RegionBSPTree2D) r));
    }

    /** {@inheritDoc} */
    @Override
    public RegionBSPTree2D getSubspaceRegion() {
        return region;
    }

    /** {@inheritDoc} */
    @Override
    public SubPlane transform(final Transform<Vector3D> transform) {
        final Plane.SubspaceTransform subTransform = getPlane().subspaceTransform(transform);

        final RegionBSPTree2D tRegion = RegionBSPTree2D.empty();
        tRegion.copy(region);
        tRegion.transform(subTransform.getTransform());

        return new SubPlane(subTransform.getPlane(), tRegion);
    }

    /** Add a convex subplane to this instance.
     * @param subplane convex subplane to add
     * @throws GeometryException if the given convex subplane is not from
     *      a plane equivalent to this instance
     */
    public void add(final ConvexSubPlane subplane) {
        validatePlane(subplane.getPlane());

        region.add(subplane.getSubspaceRegion());
    }

    /** Add a subplane to this instance.
     * @param subplane subplane to add
     * @throws GeometryException if the given convex subplane is not from
     *      a plane equivalent to this instance
     */
    public void add(final SubPlane subplane) {
        validatePlane(subplane.getPlane());

        region.union(subplane.getSubspaceRegion());
    }

    /** Validate that the given plane is equivalent to the plane
     * defining this subplane.
     * @param inputPlane plane to validate
     * @throws GeometryException if the given plane is not equivalent
     *      to the plane for this instance
     */
    private void validatePlane(final Plane inputPlane) {
        final Plane plane = getPlane();

        if (!plane.eq(inputPlane)) {
            throw new GeometryException("Argument is not on the same " +
                    "plane. Expected " + plane + " but was " +
                    inputPlane);
        }
    }

    /** {@link Builder} implementation for sublines.
     */
    public static class SubPlaneBuilder implements SubHyperplane.Builder<Vector3D> {

        /** Subplane instance created by this builder. */
        private final SubPlane subplane;

        /** Construct a new instance for building subplane region for the given plane.
         * @param plane the underlying plane for the subplane region
         */
        public SubPlaneBuilder(final Plane plane) {
            this.subplane = new SubPlane(plane);
        }

        /** {@inheritDoc} */
        @Override
        public void add(final SubHyperplane<Vector3D> sub) {
            addInternal(sub);
        }

        /** {@inheritDoc} */
        @Override
        public void add(final ConvexSubHyperplane<Vector3D> sub) {
            addInternal(sub);
        }

        /** {@inheritDoc} */
        @Override
        public SubPlane build() {
            return subplane;
        }

        /** Internal method for adding subhyperplanes to this builder.
         * @param sub the subhyperplane to add; either convex or non-convex
         */
        private void addInternal(final SubHyperplane<Vector3D> sub) {
            if (sub instanceof ConvexSubPlane) {
                subplane.add((ConvexSubPlane) sub);
            } else if (sub instanceof SubPlane) {
                subplane.add((SubPlane) sub);
            } else {
                throw new IllegalArgumentException("Unsupported subhyperplane type: " + sub.getClass().getName());
            }
        }
    }
}
