package de.duehl.swing.ui.buttons.painted.state;

/*
 * Copyright 2025 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import java.awt.BasicStroke;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;

import de.duehl.swing.ui.geometry.PixelPoint;

/**
 * Diese Klasse stellt einen kleinen Schalter dar, der ein Herz darstellt.
 *
 * Er kann zwei Zustände darstellen, ausgewählt und nicht ausgewählt. Ist der Zustand aktiviert,
 * wird das Herz ausgefüllt, anderenfalls ist nur dessen Rand zu sehen.
 *
 * So sieht es leider nur in groß gut aus (in 550 x 500 z.B.).
 *
 * @version 1.01     2025-07-24
 * @author Christian Dühl
 */

final public class BigHeartButton extends PaintedStateButton {

    private static final long serialVersionUID = 1L;

    private static final boolean SHOW_AREA_RECTANGLE = true;

    /** Zeichnet das Symbol in horizontaler und rechteckiger Anordnung. */
    @Override
    protected void paintHorizontalSymbolRectangle() {
        paintSymbol();
    }

    /** Zeichnet das Symbol in vertikaler und rechteckiger Anordnung. */
    @Override
    protected void paintVerticalSymbolRectangle() {
        paintSymbol();
    }

    /** Zeichnet das Symbol in horizontaler und quadratischer Anordnung. */
    @Override
    protected void paintHorizontalSymbolSquare() {
        paintSymbol();
    }

    /** Zeichnet das Symbol in vertikaler und quadratischer Anordnung. */
    @Override
    protected void paintVerticalSymbolSquare() {
        paintSymbol();
    }

    /** Zeichnet das Herz. */
    private void paintSymbol() {
        int width = getWidth();
        int height = getHeight();

        if (isForceSquare()) {
            width = Math.min(width, height);
            height = width;
        }

        int delta = 6;

        int firstLeftPixel = (getWidth() - width)/2;
        int left = firstLeftPixel + delta;

        int lastRightPixel = firstLeftPixel + width - 1;
        int right = lastRightPixel - delta;

        int firstUpperPixel = (getHeight() - height)/2;
        int upper = firstUpperPixel + delta;

        int lastLowerPixel = firstUpperPixel + height - 1;
        int lower = lastLowerPixel - delta;

        if (SHOW_AREA_RECTANGLE) {
            paintLine(new PixelPoint(left, upper), new PixelPoint(right, upper));
            paintLine(new PixelPoint(right, upper), new PixelPoint(right, lower));
            paintLine(new PixelPoint(left, upper), new PixelPoint(left, lower));
            paintLine(new PixelPoint(left, lower), new PixelPoint(right, lower));
        }

        int innerWidth = right - left;
        int innerHeight = lower - upper;
        int centerX = left + innerWidth / 2;
        int centerY = upper + innerHeight / 2;

        int halfSmallerWidthOrHeight = Math.min(width, height) / 2;
        int halfWidthHeight = halfSmallerWidthOrHeight - delta;
        int distance = (int) (halfWidthHeight * 0.43);

        centerY -= halfWidthHeight * 2.18;

        int spitzeX = centerX; int spitzeY = centerY + 100; // untere Spitze

        int anzahlPunkteDelta = 3;
        int [] xDelta = new int[anzahlPunkteDelta];

        xDelta[0] = 3 * distance;
        xDelta[1] = 3 * distance;
        xDelta[2] = 0;

        int [] yDelta = new int[anzahlPunkteDelta];

        yDelta[0] = - distance;
        yDelta[1] = 4 * distance;
        yDelta[2] = 5 * distance;


        int [] leftCurveWerteX = new int[anzahlPunkteDelta];
        int [] leftCurveWerteY = new int[anzahlPunkteDelta];

        int [] rightCurveWerteX = new int[anzahlPunkteDelta];
        int [] rightCurveWerteY = new int[anzahlPunkteDelta];

        for (int index = 0; index < anzahlPunkteDelta; ++index) {
            int deltaX = xDelta[index];
            int deltaY = yDelta[index];

            leftCurveWerteX[index] = centerX - deltaX;
            leftCurveWerteY[index] = centerY + deltaY;

            rightCurveWerteX[index] = centerX + deltaX;
            rightCurveWerteY[index] = centerY + deltaY;
        }

        //graphics2.setStroke(new BasicStroke(2));
        graphics2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        graphics2.setStroke(new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));

        Path2D herz = new Path2D.Double();

        // Linke Hälfte des Herzens
        herz.moveTo(spitzeX, spitzeY); // untere Spitze
        herz.curveTo(
                leftCurveWerteX[0], leftCurveWerteY[0],
                leftCurveWerteX[1], leftCurveWerteY[1],
                leftCurveWerteX[2], leftCurveWerteY[2]);

        // Rechte Hälfte des Herzens
        herz.moveTo(spitzeX, spitzeY); // untere Spitze
        herz.curveTo(
                rightCurveWerteX[0], rightCurveWerteY[0],
                rightCurveWerteX[1], rightCurveWerteY[1],
                rightCurveWerteX[2], rightCurveWerteY[2]);


        if (isElected()) {
            graphics2.fill(herz); // Herz ausfüllen
        }
        else {
            graphics2.draw(herz); // Herzumrandung
        }
    }

}
