/* ====================================================================
   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 java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.Locale;

import org.apache.poi.sl.usermodel.PlaceableShape;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.StrokeStyle;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;


public class DrawShape implements Drawable {

    protected final Shape<?,?> shape;

    public DrawShape(Shape<?,?> shape) {
        this.shape = shape;
    }

    /**
     * Sometimes it's necessary to distinguish between XSLF/HSLF for the rendering.
     * Use this method on the shape to determine, if we work on the BIFF implementation
     *
     * @param shape the shape to render
     * @return {@code true} if HSLF implementation is used
     */
    protected static boolean isHSLF(Shape<?,?> shape) {
        return shape.getClass().getCanonicalName().toLowerCase(Locale.ROOT).contains("hslf");
    }

    /**
     * Apply 2-D transforms before drawing this shape. This includes rotation and flipping.
     *
     * @param graphics the graphics whos transform matrix will be modified
     */
    @Override
    public void applyTransform(Graphics2D graphics) {
        if (!(shape instanceof PlaceableShape)) {
            return;
        }

        PlaceableShape<?,?> ps = (PlaceableShape<?,?>)shape;
        final boolean isHSLF = isHSLF(shape);
        AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
        if (tx == null) {
            tx = new AffineTransform();
        }
        final Rectangle2D anchor = tx.createTransformedShape(ps.getAnchor()).getBounds2D();

        char cmds[] = isHSLF ? new char[]{ 'h','v','r' } : new char[]{ 'r','h','v' };
        for (char ch : cmds) {
            switch (ch) {
            case 'h':
                //flip horizontal
                if (ps.getFlipHorizontal()) {
                    graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());
                    graphics.scale(-1, 1);
                    graphics.translate(-anchor.getX(), -anchor.getY());
                }
                break;
            case 'v':
                //flip vertical
                if (ps.getFlipVertical()) {
                    graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());
                    graphics.scale(1, -1);
                    graphics.translate(-anchor.getX(), -anchor.getY());
                }
                break;
            case 'r':
                // rotation
                double rotation = ps.getRotation();
                if (rotation != 0.) {
                    // PowerPoint rotates shapes relative to the geometric center
                    double centerX = anchor.getCenterX();
                    double centerY = anchor.getCenterY();

                    // normalize rotation
                    rotation %= 360.;
                    if (rotation < 0) {
                        rotation += 360.;
                    }

                    int quadrant = (((int)rotation+45)/90)%4;
                    double scaleX = 1.0, scaleY = 1.0;

                    // scale to bounding box (bug #53176)
                    if (quadrant == 1 || quadrant == 3) {
                        // In quadrant 1 and 3, which is basically a shape in a more or less portrait orientation
                        // (45-135 degrees and 225-315 degrees), we need to first rotate the shape by a multiple
                        // of 90 degrees and then resize the bounding box to its original bbox. After that we can
                        // rotate the shape to the exact rotation amount.
                        // It's strange that you'll need to rotate the shape back and forth again, but you can
                        // think of it, as if you paint the shape on a canvas. First you rotate the canvas, which might
                        // be already (differently) scaled, so you can paint the shape in its default orientation
                        // and later on, turn it around again to compare it with its original size ...

                        AffineTransform txs;
                        if (isHSLF) {
                            txs = new AffineTransform(tx);
                        } else {
                            // this handling is only based on try and error ... not sure why xslf is handled differently.
                            txs = new AffineTransform();
                            txs.translate(centerX, centerY);
                            txs.rotate(Math.PI/2.); // actually doesn't matter if +/- 90 degrees
                            txs.translate(-centerX, -centerY);
                            txs.concatenate(tx);
                        }

                        txs.translate(centerX, centerY);
                        txs.rotate(Math.PI/2.);
                        txs.translate(-centerX, -centerY);

                        Rectangle2D anchor2 = txs.createTransformedShape(ps.getAnchor()).getBounds2D();

                        scaleX = safeScale(anchor.getWidth(), anchor2.getWidth());
                        scaleY = safeScale(anchor.getHeight(), anchor2.getHeight());
                    } else {
                        quadrant = 0;
                    }

                    // transformation is applied reversed ...
                    graphics.translate(centerX, centerY);
                    double rot = Math.toRadians(rotation-quadrant*90.);
                    if (rot != 0) {
                        graphics.rotate(rot);
                    }
                    graphics.scale(scaleX, scaleY);
                    rot = Math.toRadians(quadrant*90.);
                    if (rot != 0) {
                        graphics.rotate(rot);
                    }
                    graphics.translate(-centerX, -centerY);
                }
                break;
            default:
                throw new RuntimeException("unexpected transform code " + ch);
            }
        }
    }

    private static double safeScale(double dim1, double dim2) {
        if (dim1 == 0.) {
            return 1;
        }
        return (dim2 == 0.) ? 1 : dim1/dim2;
    }

    @Override
    public void draw(Graphics2D graphics) {
    }

    @Override
    public void drawContent(Graphics2D graphics) {
    }

    public static Rectangle2D getAnchor(Graphics2D graphics, PlaceableShape<?,?> shape) {
        return getAnchor(graphics, shape.getAnchor());
    }

    public static Rectangle2D getAnchor(Graphics2D graphics, Rectangle2D anchor) {
        if(graphics == null)  {
            return anchor;
        }

        AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
        if(tx != null && !tx.isIdentity()) {
            anchor = tx.createTransformedShape(anchor).getBounds2D();
        }
        return anchor;
    }

    protected Shape<?,?> getShape() {
        return shape;
    }

    protected static BasicStroke getStroke(StrokeStyle strokeStyle) {
        float lineWidth = (float) strokeStyle.getLineWidth();
        if (lineWidth == 0.0f) {
            // Both PowerPoint and OOo draw zero-length lines as 0.25pt
            lineWidth = 0.25f;
        }

        LineDash lineDash = strokeStyle.getLineDash();
        if (lineDash == null) {
            lineDash = LineDash.SOLID;
        }

        int dashPatI[] = lineDash.pattern;
        final float dash_phase = 0;
        float[] dashPatF = null;
        if (dashPatI != null) {
            dashPatF = new float[dashPatI.length];
            for (int i=0; i<dashPatI.length; i++) {
                dashPatF[i] = dashPatI[i]*Math.max(1, lineWidth);
            }
        }

        LineCap lineCapE = strokeStyle.getLineCap();
        if (lineCapE == null) {
            lineCapE = LineCap.FLAT;
        }
        int lineCap;
        switch (lineCapE) {
            case ROUND:
                lineCap = BasicStroke.CAP_ROUND;
                break;
            case SQUARE:
                lineCap = BasicStroke.CAP_SQUARE;
                break;
            default:
            case FLAT:
                lineCap = BasicStroke.CAP_BUTT;
                break;
        }

        int lineJoin = BasicStroke.JOIN_ROUND;

        return new BasicStroke(lineWidth, lineCap, lineJoin, lineWidth, dashPatF, dash_phase);
    }
}
