/* ====================================================================
   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.draw;

import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;

import org.apache.poi.hemf.record.emfplus.HemfPlusBrush.EmfPlusHatchStyle;
import org.apache.poi.hwmf.draw.HwmfDrawProperties;
import org.apache.poi.sl.draw.ImageRenderer;

public class HemfDrawProperties extends HwmfDrawProperties {
    enum TransOperand {
        left(AffineTransform::concatenate),
        right(AffineTransform::preConcatenate);

        BiConsumer<AffineTransform,AffineTransform> fun;
        TransOperand(BiConsumer<AffineTransform,AffineTransform> fun) {
            this.fun = fun;
        }
    }

    /** Path for path bracket operations */
    protected Path2D path = null;
    protected boolean usePathBracket = false;
    private EmfPlusHatchStyle emfPlusBrushHatch;
    private ImageRenderer emfPlusImage;

    private final List<AffineTransform> transXForm = new ArrayList<>();
    private final List<TransOperand> transOper = new ArrayList<>();

    private Rectangle2D brushRect;
    private List<? extends Map.Entry<Float,Color>> brushColorsV;
    private List<? extends Map.Entry<Float,Color>> brushColorsH;

    public HemfDrawProperties() {
    }

    public HemfDrawProperties(HemfDrawProperties other) {
        super(other);
        path = (other.path != null) ? (Path2D)other.path.clone() : null;
        usePathBracket = other.usePathBracket;
        emfPlusBrushHatch = other.emfPlusBrushHatch;
        // TODO: check how to clone
        clip = other.clip;
        emfPlusImage = other.emfPlusImage;
        transXForm.addAll(other.transXForm);
        transOper.addAll(other.transOper);
        if (other.brushRect != null) {
            brushRect = (Rectangle2D)other.brushRect.clone();
        }
        if (other.brushColorsV != null) {
            brushColorsV = new ArrayList<>(other.brushColorsV);
        }
        if (other.brushColorsH != null) {
            brushColorsH = new ArrayList<>(other.brushColorsH);
        }
    }

    /**
     * @return the current path used for bracket operations
     */
    public Path2D getPath() {
        return path;
    }

    /**
     * Un-/Sets the bracket path
     * @param path the bracket path
     */
    public void setPath(Path2D path) {
        this.path = path;
    }

    /**
     * Use path (bracket) or graphics context for drawing operations
     * @return {@code true}, if the drawing should go to the path bracket,
     *      if {@code false} draw directly to the graphics context
     */
    public boolean getUsePathBracket() {
        return usePathBracket;
    }

    public void setUsePathBracket(boolean usePathBracket) {
        this.usePathBracket = usePathBracket;
    }

    public EmfPlusHatchStyle getEmfPlusBrushHatch() {
        return emfPlusBrushHatch;
    }

    public void setEmfPlusBrushHatch(EmfPlusHatchStyle emfPlusBrushHatch) {
        this.emfPlusBrushHatch = emfPlusBrushHatch;
    }

    public ImageRenderer getEmfPlusImage() {
        return emfPlusImage;
    }

    public void setEmfPlusImage(ImageRenderer emfPlusImage) {
        this.emfPlusImage = emfPlusImage;
    }

    public void addLeftTransform(AffineTransform transform) {
        addLRTransform(transform, TransOperand.left);
    }

    public void addRightTransform(AffineTransform transform) {
        addLRTransform(transform, TransOperand.right);
    }

    private static <T> T last(List<T> list) {
        return list.isEmpty() ? null : list.get(list.size()-1);
    }

    private void addLRTransform(AffineTransform transform, TransOperand lr) {
        if (transform.isIdentity() || (transform.equals(last(transXForm)) && lr.equals(last(transOper)))) {
            // some EMFs add duplicated transformations - ignore them
            return;
        }
        transXForm.add(transform);
        transOper.add(lr);
    }

    public void clearTransform() {
        transXForm.clear();
        transOper.clear();
    }

    List<AffineTransform> getTransXForm() {
        return transXForm;
    }

    List<TransOperand> getTransOper() {
        return transOper;
    }

    public Rectangle2D getBrushRect() {
        return brushRect;
    }

    public void setBrushRect(Rectangle2D brushRect) {
        this.brushRect = brushRect;
    }

    public List<? extends Map.Entry<Float, Color>> getBrushColorsV() {
        return brushColorsV;
    }

    public void setBrushColorsV(List<? extends Map.Entry<Float, Color>> brushColorsV) {
        this.brushColorsV = brushColorsV;
    }

    public List<? extends Map.Entry<Float, Color>> getBrushColorsH() {
        return brushColorsH;
    }

    public void setBrushColorsH(List<? extends Map.Entry<Float, Color>> brushColorsH) {
        this.brushColorsH = brushColorsH;
    }
}
