/*
 * 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.core.partitioning.bsp;

import org.apache.commons.geometry.core.Point;

/** Simple {@link BSPTree} implementation allowing arbitrary values to be
 * associated with each node.
 * @param <P> Point implementation type
 * @param <T> Tree node attribute type
 */
public class AttributeBSPTree<P extends Point<P>, T>
    extends AbstractBSPTree<P, AttributeBSPTree.AttributeNode<P, T>> {
    /** The initial attribute value to use for newly created nodes. */
    private final T initialNodeAttribute;

    /** Create a new tree instance. New nodes in the tree are given an attribute
     * of null.
     */
    public AttributeBSPTree() {
        this(null);
    }

    /** Create a new tree instance. New nodes in the tree are assigned the given
     * initial attribute value.
     * @param initialNodeAttribute The attribute value to assign to newly created nodes.
     */
    public AttributeBSPTree(T initialNodeAttribute) {
        this.initialNodeAttribute = initialNodeAttribute;

        this.getRoot().setAttribute(initialNodeAttribute);
    }

    /** {@inheritDoc} */
    @Override
    protected AttributeNode<P, T> createNode() {
        return new AttributeNode<>(this);
    }

    /** {@inheritDoc} */
    @Override
    protected void initChildNode(final AttributeNode<P, T> parent, final AttributeNode<P, T> child,
            final boolean isPlus) {
        super.initChildNode(parent, child, isPlus);

        child.setAttribute(initialNodeAttribute);
    }

    /** {@inheritDoc} */
    @Override
    protected void copyNodeProperties(final AttributeNode<P, T> src, final AttributeNode<P, T> dst) {
        dst.setAttribute(src.getAttribute());
    }

    /** {@link BSPTree.Node} implementation for use with {@link AttributeBSPTree}s.
     * @param <P> Point implementation type
     * @param <T> Tree node attribute type
     */
    public static class AttributeNode<P extends Point<P>, T>
        extends AbstractBSPTree.AbstractNode<P, AttributeNode<P, T>> {
        /** The node attribute. */
        private T attribute;

        /** Simple constructor.
         * @param tree the owning tree; this must be an instance of {@link AttributeBSPTree}
         */
        protected AttributeNode(AbstractBSPTree<P, AttributeNode<P, T>> tree) {
            super(tree);
        }

        /** {@inheritDoc} */
        @Override
        public AttributeBSPTree<P, T> getTree() {
            // cast to our parent tree type
            return (AttributeBSPTree<P, T>) super.getTree();
        }

        /** Get the attribute associated with this node.
         * @return the attribute associated with this node
         */
        public T getAttribute() {
            return attribute;
        }

        /** Set the attribute associated with this node.
         * @param attribute the attribute to associate with this node
         */
        public void setAttribute(T attribute) {
            this.attribute = attribute;
        }

        /** Set the attribute for this node. The node is returned.
         * @param attributeValue attribute to set for the node
         * @return the node instance
         */
        public AttributeNode<P, T> attr(final T attributeValue) {
            setAttribute(attributeValue);

            return this;
        }

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

            return sb.toString();
        }

        /** {@inheritDoc} */
        @Override
        protected AttributeNode<P, T> getSelf() {
            return this;
        }
    }
}
