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

import static org.apache.poi.sl.draw.DrawPaint.fillPaintWorkaround;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;

import org.apache.poi.sl.draw.geom.Context;
import org.apache.poi.sl.draw.geom.CustomGeometry;
import org.apache.poi.sl.draw.geom.Outline;
import org.apache.poi.sl.draw.geom.Path;
import org.apache.poi.sl.usermodel.LineDecoration;
import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;
import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.PaintModifier;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.Shadow;
import org.apache.poi.sl.usermodel.SimpleShape;
import org.apache.poi.util.Units;


public class DrawSimpleShape extends DrawShape {

    private static final double DECO_SIZE_POW = 1.5d;

    public DrawSimpleShape(SimpleShape<?,?> shape) {
        super(shape);
    }

    @Override
    public void draw(Graphics2D graphics) {
        if (getAnchor(graphics, getShape()) == null) {
            return;
        }

        Paint oldPaint = graphics.getPaint();
        Stroke oldStroke = graphics.getStroke();
        Color oldColor = graphics.getColor();

        Paint fill = getFillPaint(graphics);
        Paint line = getLinePaint(graphics);
        BasicStroke stroke = getStroke(); // the stroke applies both to the shadow and the shape
        graphics.setStroke(stroke);

        Collection<Outline> elems = computeOutlines(graphics);

        // first paint the shadow
        drawShadow(graphics, elems, fill, line);

        // then fill the shape interior
        if (fill != null) {
            final Path2D area = new Path2D.Double();
            graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, area);

            Consumer<PaintModifier> fun = (pm) -> fillArea(graphics, pm, area);

            PaintModifier pm = null;
            for (Outline o : elems) {
                Path path = o.getPath();
                if (path.isFilled()) {
                    PaintModifier pmOld = pm;
                    pm = path.getFill();
                    if (pmOld != null && pmOld != pm) {
                        fun.accept(pmOld);
                        area.reset();
                    } else {
                        area.append(o.getOutline(), false);
                    }
                }
            }

            if (area.getCurrentPoint() != null) {
                fun.accept(pm);
            }
        }

        // then draw any content within this shape (text, image, etc.)
        drawContent(graphics);

        // then stroke the shape outline
        if(line != null) {
            graphics.setPaint(line);
            graphics.setStroke(stroke);
            for(Outline o : elems){
                if(o.getPath().isStroked()){
                    java.awt.Shape s = o.getOutline();
                    graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s);
                    graphics.draw(s);
                }
            }
        }

        // draw line decorations
        drawDecoration(graphics, line, stroke);

        graphics.setColor(oldColor);
        graphics.setPaint(oldPaint);
        graphics.setStroke(oldStroke);
    }

    private void fillArea(Graphics2D graphics, PaintModifier pm, Path2D area) {
        final SimpleShape<?, ?> ss = getShape();
        final PaintStyle ps = ss.getFillStyle().getPaint();
        final DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(ss);
        final Paint fillMod = drawPaint.getPaint(graphics, ps, pm);
        if (fillMod != null) {
            graphics.setPaint(fillMod);
            fillPaintWorkaround(graphics, area);
        }
    }

    protected Paint getFillPaint(Graphics2D graphics) {
        DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape());
        return drawPaint.getPaint(graphics, getShape().getFillStyle().getPaint());
    }

    protected Paint getLinePaint(Graphics2D graphics) {
        DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape());
        return drawPaint.getPaint(graphics, getShape().getStrokeStyle().getPaint());
    }


    protected void drawDecoration(Graphics2D graphics, Paint line, BasicStroke stroke) {
        if(line == null) {
            return;
        }
        graphics.setPaint(line);

        List<Outline> lst = new ArrayList<>();
        LineDecoration deco = getShape().getLineDecoration();
        Outline head = getHeadDecoration(graphics, deco, stroke);
        if (head != null) {
            lst.add(head);
        }
        Outline tail = getTailDecoration(graphics, deco, stroke);
        if (tail != null) {
            lst.add(tail);
        }


        for(Outline o : lst){
            java.awt.Shape s = o.getOutline();
            Path p = o.getPath();
            graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s);

            if(p.isFilled()) {
                graphics.fill(s);
            }
            if(p.isStroked()) {
                graphics.draw(s);
            }
        }
    }

    protected Outline getTailDecoration(Graphics2D graphics, LineDecoration deco, BasicStroke stroke) {
        if (deco == null || stroke == null) {
            return null;
        }
        DecorationSize tailLength = deco.getTailLength();
        if (tailLength == null) {
            tailLength = DecorationSize.MEDIUM;
        }
        DecorationSize tailWidth = deco.getTailWidth();
        if (tailWidth == null) {
            tailWidth = DecorationSize.MEDIUM;
        }

        double lineWidth = Math.max(2.5, stroke.getLineWidth());

        Rectangle2D anchor = getAnchor(graphics, getShape());
        double x2 = anchor.getX() + anchor.getWidth(),
               y2 = anchor.getY() + anchor.getHeight();

        double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());

        AffineTransform at = new AffineTransform();
        java.awt.Shape tailShape = null;
        Path p = null;
        Rectangle2D bounds;
        final double scaleY = Math.pow(DECO_SIZE_POW, tailWidth.ordinal()+1.);
        final double scaleX = Math.pow(DECO_SIZE_POW, tailLength.ordinal()+1.);

        DecorationShape tailShapeEnum = deco.getTailShape();

        if (tailShapeEnum == null) {
            return null;
        }

        switch (tailShapeEnum) {
            case OVAL:
                p = new Path();
                tailShape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
                bounds = tailShape.getBounds2D();
                at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2);
                at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
                break;
            case STEALTH:
            case ARROW:
                p = new Path();
                p.setFill(PaintModifier.NONE);
                p.setStroke(true);
                Path2D.Double arrow = new Path2D.Double();
                arrow.moveTo((-lineWidth * scaleX), (-lineWidth * scaleY / 2));
                arrow.lineTo(0, 0);
                arrow.lineTo((-lineWidth * scaleX), (lineWidth * scaleY / 2));
                tailShape = arrow;
                at.translate(x2, y2);
                at.rotate(alpha);
                break;
            case TRIANGLE:
                p = new Path();
                Path2D.Double triangle = new Path2D.Double();
                triangle.moveTo((-lineWidth * scaleX), (-lineWidth * scaleY / 2));
                triangle.lineTo(0, 0);
                triangle.lineTo((-lineWidth * scaleX), (lineWidth * scaleY / 2));
                triangle.closePath();
                tailShape = triangle;
                at.translate(x2, y2);
                at.rotate(alpha);
                break;
            default:
                break;
        }

        if (tailShape != null) {
            tailShape = at.createTransformedShape(tailShape);
        }
        return tailShape == null ? null : new Outline(tailShape, p);
    }

    protected Outline getHeadDecoration(Graphics2D graphics, LineDecoration deco, BasicStroke stroke) {
        if (deco == null || stroke == null) {
            return null;
        }
        DecorationSize headLength = deco.getHeadLength();
        if (headLength == null) {
            headLength = DecorationSize.MEDIUM;
        }
        DecorationSize headWidth = deco.getHeadWidth();
        if (headWidth == null) {
            headWidth = DecorationSize.MEDIUM;
        }

        double lineWidth = Math.max(2.5, stroke.getLineWidth());

        Rectangle2D anchor = getAnchor(graphics, getShape());
        double x1 = anchor.getX(), y1 = anchor.getY();

        double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());

        AffineTransform at = new AffineTransform();
        java.awt.Shape headShape = null;
        Path p = null;
        Rectangle2D bounds;
        final double scaleY = Math.pow(DECO_SIZE_POW, headWidth.ordinal()+1.);
        final double scaleX = Math.pow(DECO_SIZE_POW, headLength.ordinal()+1.);
        DecorationShape headShapeEnum = deco.getHeadShape();

        if (headShapeEnum == null) {
            return null;
        }

        switch (headShapeEnum) {
            case OVAL:
                p = new Path();
                headShape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
                bounds = headShape.getBounds2D();
                at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2);
                at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
                break;
            case STEALTH:
            case ARROW:
                p = new Path();
                p.setFill(PaintModifier.NONE);
                p.setStroke(true);
                Path2D.Double arrow = new Path2D.Double();
                arrow.moveTo((lineWidth * scaleX), (-lineWidth * scaleY / 2));
                arrow.lineTo(0, 0);
                arrow.lineTo((lineWidth * scaleX), (lineWidth * scaleY / 2));
                headShape = arrow;
                at.translate(x1, y1);
                at.rotate(alpha);
                break;
            case TRIANGLE:
                p = new Path();
                Path2D.Double triangle = new Path2D.Double();
                triangle.moveTo((lineWidth * scaleX), (-lineWidth * scaleY / 2));
                triangle.lineTo(0, 0);
                triangle.lineTo((lineWidth * scaleX), (lineWidth * scaleY / 2));
                triangle.closePath();
                headShape = triangle;
                at.translate(x1, y1);
                at.rotate(alpha);
                break;
            default:
                break;
        }

        if (headShape != null) {
            headShape = at.createTransformedShape(headShape);
        }
        return headShape == null ? null : new Outline(headShape, p);
    }

    public BasicStroke getStroke() {
        return getStroke(getShape().getStrokeStyle());
    }

    protected void drawShadow(
        Graphics2D graphics
      , Collection<Outline> outlines
      , Paint fill
      , Paint line
    ) {
        Shadow<?,?> shadow = getShape().getShadow();
        if (shadow == null || (fill == null && line == null)) {
            return;
        }

        SolidPaint shadowPaint = shadow.getFillStyle();
        Color shadowColor = DrawPaint.applyColorTransform(shadowPaint.getSolidColor());

        double shapeRotation = getShape().getRotation();
        if (getShape().getFlipVertical()) {
            shapeRotation += 180;
        }
        double angle = shadow.getAngle() - shapeRotation;
        double dist = shadow.getDistance();
        double dx = dist * Math.cos(Math.toRadians(angle));
        double dy = dist * Math.sin(Math.toRadians(angle));

        graphics.translate(dx, dy);

        for (Outline o : outlines) {
            java.awt.Shape s = o.getOutline();
            Path p = o.getPath();
            graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s);
            graphics.setPaint(shadowColor);

            if (fill != null && p.isFilled()) {
                fillPaintWorkaround(graphics, s);
            } else if (line != null && p.isStroked()) {
                graphics.draw(s);
            }
        }

        graphics.translate(-dx, -dy);
    }

    protected Collection<Outline> computeOutlines(Graphics2D graphics) {
        final SimpleShape<?,?> sh = getShape();

        List<Outline> lst = new ArrayList<>();
        CustomGeometry geom = sh.getGeometry();
        if(geom == null) {
            return lst;
        }

        Rectangle2D anchor = getAnchor(graphics, sh);
        if(anchor == null) {
            return lst;
        }
        for (Path p : geom) {

            double w = p.getW(), h = p.getH(), scaleX, scaleY;
            if (w == -1) {
                w = Units.toEMU(anchor.getWidth());
                scaleX = Units.toPoints(1);
            } else if (anchor.getWidth() == 0) {
                scaleX = 1;
            } else {
                scaleX = anchor.getWidth() / w;
            }
            if (h == -1) {
                h = Units.toEMU(anchor.getHeight());
                scaleY = Units.toPoints(1);
            } else if (anchor.getHeight() == 0) {
                scaleY = 1;
            } else {
                scaleY = anchor.getHeight() / h;
            }

            // the guides in the shape definitions are all defined relative to each other,
            // so we build the path starting from (0,0).
            final Rectangle2D pathAnchor = new Rectangle2D.Double(0,0,w,h);

            Context ctx = new Context(geom, pathAnchor, sh);

            java.awt.Shape gp = p.getPath(ctx);

            // translate the result to the canvas coordinates in points
            AffineTransform at = new AffineTransform();
            at.translate(anchor.getX(), anchor.getY());
            at.scale(scaleX, scaleY);

            java.awt.Shape canvasShape = at.createTransformedShape(gp);

            lst.add(new Outline(canvasShape, p));
        }

        return lst;
    }

    @Override
    protected SimpleShape<?,?> getShape() {
        return (SimpleShape<?,?>)shape;
    }
}
