/* ====================================================================
   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.poi.hemf.record.emfplus;

import static org.apache.poi.hemf.record.emfplus.HemfPlusDraw.readRectF;

import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;

import org.apache.poi.common.usermodel.GenericRecord;
import org.apache.poi.hemf.draw.HemfDrawProperties;
import org.apache.poi.hemf.draw.HemfGraphics;
import org.apache.poi.hemf.record.emfplus.HemfPlusHeader.EmfPlusGraphicsVersion;
import org.apache.poi.hemf.record.emfplus.HemfPlusObject.EmfPlusObjectData;
import org.apache.poi.hemf.record.emfplus.HemfPlusObject.EmfPlusObjectType;
import org.apache.poi.hemf.record.emfplus.HemfPlusPath.EmfPlusPath;
import org.apache.poi.util.GenericRecordUtil;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;

public class HemfPlusRegion {
    public enum EmfPlusRegionNodeDataType {
        /**
         * Specifies a region node with child nodes. A Boolean AND operation SHOULD be applied to the left and right
         * child nodes specified by an EmfPlusRegionNodeChildNodes object
         */
        AND(0X00000001, EmfPlusRegionNode::new, Area::intersect),
        /**
         * Specifies a region node with child nodes. A Boolean OR operation SHOULD be applied to the left and right
         * child nodes specified by an EmfPlusRegionNodeChildNodes object.
         */
        OR(0X00000002, EmfPlusRegionNode::new, Area::add),
        /**
         * Specifies a region node with child nodes. A Boolean XOR operation SHOULD be applied to the left and right
         * child nodes specified by an EmfPlusRegionNodeChildNodes object.
         */
        XOR(0X00000003, EmfPlusRegionNode::new, Area::exclusiveOr),
        /**
         * Specifies a region node with child nodes. A Boolean operation, defined as "the part of region 1 that is excluded
         * from region 2", SHOULD be applied to the left and right child nodes specified by an EmfPlusRegionNodeChildNodes object.
         */
        EXCLUDE(0X00000004, EmfPlusRegionNode::new, Area::subtract),
        /**
         * Specifies a region node with child nodes. A Boolean operation, defined as "the part of region 2 that is excluded
         * from region 1", SHOULD be applied to the left and right child nodes specified by an EmfPlusRegionNodeChildNodes object.
         */
        COMPLEMENT(0X00000005, EmfPlusRegionNode::new, Area::subtract),
        /**
         * Specifies a region node with no child nodes.
         * The RegionNodeData field SHOULD specify a boundary with an EmfPlusRectF object.
         */
        RECT(0X10000000, EmfPlusRegionRect::new, null),
        /**
         * Specifies a region node with no child nodes.
         * The RegionNodeData field SHOULD specify a boundary with an EmfPlusRegionNodePath object
         */
        PATH(0X10000001, EmfPlusRegionPath::new, null),
        /** Specifies a region node with no child nodes. The RegionNodeData field SHOULD NOT be present. */
        EMPTY(0X10000002, EmfPlusRegionEmpty::new, null),
        /** Specifies a region node with no child nodes, and its bounds are not defined. */
        INFINITE(0X10000003, EmfPlusRegionInfinite::new, null)
        ;

        public final int id;
        public final Supplier<EmfPlusRegionNodeData> constructor;
        public final BiConsumer<Area,Area> operation;

        EmfPlusRegionNodeDataType(int id, Supplier<EmfPlusRegionNodeData> constructor, BiConsumer<Area,Area> operation) {
            this.id = id;
            this.constructor = constructor;
            this.operation = operation;
        }

        public static EmfPlusRegionNodeDataType valueOf(int id) {
            for (EmfPlusRegionNodeDataType wrt : values()) {
                if (wrt.id == id) return wrt;
            }
            return null;
        }
    }

    /** The EmfPlusRegion object specifies line and curve segments that define a nonrectilinear shape. */
    public static class EmfPlusRegion implements EmfPlusObjectData {

        private final EmfPlusGraphicsVersion graphicsVersion = new EmfPlusGraphicsVersion();
        private EmfPlusRegionNodeData regionNode;

        @SuppressWarnings("unused")
        @Override
        public long init(LittleEndianInputStream leis, long dataSize, EmfPlusObjectType objectType, int flags) throws IOException {
            long size = graphicsVersion.init(leis);

            // A 32-bit unsigned integer that specifies the number of child nodes in the RegionNode field.
            int nodeCount = leis.readInt();
            size += LittleEndianConsts.INT_SIZE;

            // An array of RegionNodeCount+1 EmfPlusRegionNode objects. Regions are specified as a binary tree of
            // region nodes, and each node MUST either be a terminal node or specify one or two child nodes.
            // RegionNode MUST contain at least one element.
            size += readNode(leis, this::setRegionNode);

            return size;
        }

        @Override
        public void applyObject(HemfGraphics ctx, List<? extends EmfPlusObjectData> continuedObjectData) {
            HemfDrawProperties prop = ctx.getProperties();
            Shape shape = regionNode.getShape();
            prop.setPath(shape == null ? null : new Path2D.Double(shape));
        }

        @Override
        public EmfPlusGraphicsVersion getGraphicsVersion() {
            return graphicsVersion;
        }

        @Override
        public EmfPlusObjectType getGenericRecordType() {
            return EmfPlusObjectType.REGION;
        }

        private void setRegionNode(EmfPlusRegionNodeData regionNode) {
            this.regionNode = regionNode;
        }

        public EmfPlusRegionNodeData getRegionNode() {
            return regionNode;
        }

        @Override
        public Map<String, Supplier<?>> getGenericProperties() {
            return GenericRecordUtil.getGenericProperties(
                "graphicsVersion", this::getGraphicsVersion,
                "regionNode", this::getRegionNode
            );
        }
    }


    public interface EmfPlusRegionNodeData extends GenericRecord {
        long init(LittleEndianInputStream leis) throws IOException;
        Shape getShape();
        default void setNodeType(EmfPlusRegionNodeDataType type) {}
    }

    public static class EmfPlusRegionPath extends EmfPlusPath implements EmfPlusRegionNodeData {
        public long init(LittleEndianInputStream leis) throws IOException {
            int dataSize = leis.readInt();
            return super.init(leis, dataSize, EmfPlusObjectType.PATH, 0) + LittleEndianConsts.INT_SIZE;
        }

        @Override
        public Shape getShape() {
            return getPath();
        }

        @Override
        public EmfPlusRegionNodeDataType getGenericRecordType() {
            return EmfPlusRegionNodeDataType.PATH;
        }
    }

    public static class EmfPlusRegionInfinite implements EmfPlusRegionNodeData {
        @Override
        public long init(LittleEndianInputStream leis) throws IOException {
            return 0;
        }

        @Override
        public Map<String, Supplier<?>> getGenericProperties() {
            return null;
        }

        @Override
        public Shape getShape() {
            return null;
        }

        @Override
        public EmfPlusRegionNodeDataType getGenericRecordType() {
            return EmfPlusRegionNodeDataType.INFINITE;
        }
    }

    public static class EmfPlusRegionEmpty implements EmfPlusRegionNodeData {
        @Override
        public long init(LittleEndianInputStream leis) throws IOException {
            return 0;
        }

        @Override
        public Map<String, Supplier<?>> getGenericProperties() {
            return null;
        }

        @Override
        public Shape getShape() {
            return new Rectangle2D.Double(0,0,0,0);
        }

        @Override
        public EmfPlusRegionNodeDataType getGenericRecordType() {
            return EmfPlusRegionNodeDataType.EMPTY;
        }
    }

    public static class EmfPlusRegionRect implements EmfPlusRegionNodeData {
        private final Rectangle2D rect = new Rectangle2D.Double();

        @Override
        public long init(LittleEndianInputStream leis) {
            return readRectF(leis, rect);
        }

        @Override
        public Map<String, Supplier<?>> getGenericProperties() {
            return GenericRecordUtil.getGenericProperties("rect", () -> rect);
        }

        @Override
        public Shape getShape() {
            return rect;
        }

        @Override
        public EmfPlusRegionNodeDataType getGenericRecordType() {
            return EmfPlusRegionNodeDataType.RECT;
        }
    }

    /** The EmfPlusRegionNode object specifies nodes of a graphics region. */
    public static class EmfPlusRegionNode implements EmfPlusRegionNodeData {
        private EmfPlusRegionNodeData left, right;
        private EmfPlusRegionNodeDataType nodeType;

        @Override
        public long init(LittleEndianInputStream leis) throws IOException {
            long size = readNode(leis, this::setLeft);
            size += readNode(leis, this::setRight);
            return size;
        }

        private void setLeft(EmfPlusRegionNodeData left) {
            this.left = left;
        }

        private void setRight(EmfPlusRegionNodeData right) {
            this.right = right;
        }

        public EmfPlusRegionNodeData getLeft() {
            return left;
        }

        public EmfPlusRegionNodeData getRight() {
            return right;
        }

        public EmfPlusRegionNodeDataType getNodeType() {
            return nodeType;
        }

        @Override
        public void setNodeType(EmfPlusRegionNodeDataType nodeType) {
            this.nodeType = nodeType;
        }

        @Override
        public Map<String, Supplier<?>> getGenericProperties() {
            return GenericRecordUtil.getGenericProperties(
                "nodeType", this::getNodeType,
                "left", this::getLeft,
                "right", this::getRight
            );
        }

        @Override
        public Shape getShape() {
            boolean com = (nodeType == EmfPlusRegionNodeDataType.COMPLEMENT);
            final Shape leftShape =  (com ? right : left).getShape();
            final Shape rightShape = (com ? left : right).getShape();

            if (leftShape == null) {
                return rightShape;
            } else if (rightShape == null) {
                return leftShape;
            }

            // TODO: check Area vs. Path manipulation
            Area leftArea = new Area(leftShape);
            Area rightArea = new Area(rightShape);

            assert(nodeType.operation != null);
            nodeType.operation.accept(leftArea, rightArea);

            return leftArea;
        }

        @Override
        public EmfPlusRegionNodeDataType getGenericRecordType() {
            return nodeType;
        }
    }

    private static long readNode(LittleEndianInputStream leis, Consumer<EmfPlusRegionNodeData> con) throws IOException {
        // A 32-bit unsigned integer that specifies the type of data in the RegionNodeData field.
        // This value MUST be defined in the RegionNodeDataType enumeration
        EmfPlusRegionNodeDataType type = EmfPlusRegionNodeDataType.valueOf(leis.readInt());
        assert(type != null);
        EmfPlusRegionNodeData nd = type.constructor.get();
        con.accept(nd);
        nd.setNodeType(type);
        return LittleEndianConsts.INT_SIZE + nd.init(leis);
    }
}
