package magic.ui.widget.duel.animation;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;

public class ArrowBuilder {
    private ArrowBuilder() {}

    static void drawArrow(Graphics g, Rectangle startRect, Rectangle endRect) {

        final Composite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f);

        final int startX = startRect.x + (startRect.width / 2);
        final int startY = startRect.y + (startRect.height / 2);
        final int endX = endRect.x;
        final int endY = endRect.y + (endRect.height / 2);

        float ex = endX - startX;
        float ey = endY - startY;
        if (ex == 0 && ey == 0) return;
        float length = (float)Math.sqrt(ex * ex + ey * ey);
        float bendPercent = (float)Math.asin(ey / length);
        if (endX > startX) bendPercent = -bendPercent;

        Area arrow = getArrow(length, -bendPercent);

        Graphics2D g2d = (Graphics2D) g.create();
        g2d.translate(startX, startY);
        g2d.rotate(Math.atan2(ey, ex));
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setComposite(composite);
        g2d.setColor(Color.RED);
        g2d.fill(arrow);
        g2d.setColor(Color.BLACK);
        g2d.draw(arrow);
        g2d.dispose();

    }

    private static Area getArrow (float length, float bendPercent) {

        final int bodyWidth = 10;
        final float headSize = 17;

        float p1x = 0, p1y = 0;
        float p2x = length, p2y = 0;
        float cx = length / 2, cy = length / 8f * bendPercent;

        float adjSize, ex, ey, abs_e;
        adjSize = (float)(bodyWidth / 2 / Math.sqrt(2));
        ex = p2x - cx;
        ey = p2y - cy;
        abs_e = (float)Math.sqrt(ex * ex + ey * ey);
        ex /= abs_e;
        ey /= abs_e;
        GeneralPath bodyPath = new GeneralPath();
        bodyPath.moveTo(p2x + (ey - ex) * adjSize, p2y - (ex + ey) * adjSize);
        bodyPath.quadTo(cx, cy, p1x, p1y - bodyWidth / 2);
        bodyPath.lineTo(p1x, p1y + bodyWidth / 2);
        bodyPath.quadTo(cx, cy, p2x - (ey + ex) * adjSize, p2y + (ex - ey) * adjSize);
        bodyPath.closePath();

        adjSize = (float)(headSize / Math.sqrt(2));
        ex = p2x - cx;
        ey = p2y - cy;
        abs_e = (float)Math.sqrt(ex * ex + ey * ey);
        ex /= abs_e;
        ey /= abs_e;
        GeneralPath headPath = new GeneralPath();
        headPath.moveTo(p2x - (ey + ex) * adjSize, p2y + (ex - ey) * adjSize);
        headPath.lineTo(p2x, p2y);
        headPath.lineTo(p2x + (ey - ex) * adjSize, p2y - (ex + ey) * adjSize);
        headPath.closePath();

        Area area = new Area(headPath);
        area.add(new Area(bodyPath));
        return area;
    }

}