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

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.SplitLocation;
import org.apache.commons.geometry.core.partitioning.SubHyperplane;
import org.apache.commons.geometry.spherical.oned.CutAngle;
import org.apache.commons.geometry.spherical.oned.RegionBSPTree1S;

/** Class representing an arbitrary region of a great circle.
 */
public final class SubGreatCircle extends AbstractSubGreatCircle {

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

    /** The 1D region on the great circle. */
    private final RegionBSPTree1S region;

    /** Construct a new, empty subhyperplane for the given great circle.
     * @param greatCircle great circle defining this instance
     */
    public SubGreatCircle(final GreatCircle greatCircle) {
        this(greatCircle, false);
    }

    /** Construct a new sub-region for the given great circle. If {@code full}
     * is true, then the region will cover the entire circle; otherwise,
     * it will be empty.
     * @param circle great circle that the sub-region will belong to
     * @param full if true, the sub-region will cover the entire circle;
     *      otherwise it will be empty
     */
    public SubGreatCircle(final GreatCircle circle, final boolean full) {
        this(circle, new RegionBSPTree1S(full));
    }

    /** Construct a new instance from its defining great circle and subspace region.
     * @param circle great circle that the sub-region will belong to
     * @param region subspace region
     */
    public SubGreatCircle(final GreatCircle circle, final RegionBSPTree1S region) {
        super(circle);

        this.region = region;
    }

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

    /** {@inheritDoc} */
    @Override
    public SubGreatCircle transform(final Transform<Point2S> transform) {
        final GreatCircle circle = getCircle().transform(transform);

        return new SubGreatCircle(circle, region.copy());
    }

    /** {@inheritDoc} */
    @Override
    public List<GreatArc> toConvex() {
        return region.toIntervals().stream()
                .flatMap(i -> i.toConvex().stream())
                .map(i -> GreatArc.fromInterval(getCircle(), i))
                .collect(Collectors.toList());
    }

    /** {@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<SubGreatCircle> split(final Hyperplane<Point2S> splitter) {

        final GreatCircle splitterCircle = (GreatCircle) splitter;
        final GreatCircle thisCircle = getCircle();

        final Point2S intersection = splitterCircle.intersection(thisCircle);

        SubGreatCircle minus = null;
        SubGreatCircle plus = null;

        if (intersection != null) {
            final CutAngle subSplitter = CutAngle.createPositiveFacing(
                    thisCircle.toSubspace(intersection), splitterCircle.getPrecision());

            final Split<RegionBSPTree1S> subSplit = region.splitDiameter(subSplitter);
            final SplitLocation subLoc = subSplit.getLocation();

            if (subLoc == SplitLocation.MINUS) {
                minus = this;
            } else if (subLoc == SplitLocation.PLUS) {
                plus = this;
            } else if (subLoc == SplitLocation.BOTH) {
                minus = new SubGreatCircle(thisCircle, subSplit.getMinus());
                plus =  new SubGreatCircle(thisCircle, subSplit.getPlus());
            }
        }

        return new Split<>(minus, plus);
    }

    /** Add an arc to this instance.
     * @param arc arc to add
     * @throws GeometryException if the given arc is not from
     *      a great circle equivalent to this instance
     */
    public void add(final GreatArc arc) {
        validateGreatCircle(arc.getCircle());

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

    /** Add the region represented by the given subcircle to this instance.
     * The argument is not modified.
     * @param subcircle subcircle to add
     * @throws GeometryException if the given subcircle is not from
     *      a great circle equivalent to this instance
     */
    public void add(final SubGreatCircle subcircle) {
        validateGreatCircle(subcircle.getCircle());

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

    /** {@inheritDoc} */
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append(this.getClass().getSimpleName())
            .append('[')
            .append("circle= ")
            .append(getCircle())
            .append(", region= ")
            .append(region)
            .append(']');

        return sb.toString();
    }

    /** Validate that the given great circle is equivalent to the circle
     * defining this instance.
     * @param inputCircle the great circle to validate
     * @throws GeometryException if the argument is not equivalent
     *      to the great circle for this instance
     */
    private void validateGreatCircle(final GreatCircle inputCircle) {
        final GreatCircle circle = getCircle();

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

    /** {@link Builder} implementation for subcircles.
     */
    public static final class SubGreatCircleBuilder implements SubHyperplane.Builder<Point2S> {

        /** SubGreatCircle instance created by this builder. */
        private final SubGreatCircle subcircle;

        /** Construct a new instance for building regions for the given great circle.
         * @param circle the underlying great circle for the region
         */
        public SubGreatCircleBuilder(final GreatCircle circle) {
            this.subcircle = new SubGreatCircle(circle);
        }

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

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

        /** {@inheritDoc} */
        @Override
        public SubGreatCircle build() {
            return subcircle;
        }

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