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

import java.awt.BasicStroke;

/*
 * 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.Color;
import java.awt.RenderingHints;
import java.util.ArrayList;
import java.util.List;

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

/**
 * Diese Klasse stellt einen kleinen Schalter dar, der ein n-Eck darstellt.
 *
 * Er kann zwei Zustände darstellen, ausgewählt und nicht ausgewählt. Ist der Zustand aktiviert,
 * wird der Stern ausgefüllt, anderenfalls ist nur dessen Rand zu sehen.
 *
 * @version 1.01     2025-07-23
 * @author Christian Dühl
 */

final public class NPolygonButton extends PaintedStateButton {

    private static final long serialVersionUID = 1L;

    private static final boolean SHOW_AREA_RECTANGLE = false;
    

    /** Die Anzahl der Ecken. */
    private int number;

    /** Konstruktor mit schwarzer Farbe und fünf Ecken. */
    public NPolygonButton() {
        this(5);
    }

    /**
     * Konstruktor mit schwarzer Farbe.
     *
     * @param number
     *            Die Anzahl der Ecken.
     */
    public NPolygonButton(int number) {
        this(Color.BLACK, number);
    }

    /**
     * Konstruktor.
     *
     * @param color
     *            Die Farbe.
     * @param number
     *            Die Anzahl der Ecken.
     */
    public NPolygonButton(Color color, int number) {
        super(color);
        this.number = number;
    }

    /** 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 n-Eck. Da es dabei egal ist, ob horizontal oder vertikal, wird es in beiden
     * Fällen verwendet.
     */
    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));
        }

        float centralPointAngle = 360.0f / number;
        float startAngle = -90.0f;
        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 radius = halfSmallerWidthOrHeight - delta;

        List<PixelPoint> points = new ArrayList<>();
        for (int index = 0; index < number; ++index) {
            double centerAngle = index * centralPointAngle;
            double winkel = centerAngle + startAngle;
            double radians = Math.PI * winkel / 180.0;
            int x = (int)(radius * Math.cos(radians)) + centerX;
            int y = (int)(radius * Math.sin(radians)) + centerY;
            PixelPoint point = new PixelPoint(x, y);
            points.add(point);
        }

        graphics2.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON));
        graphics2.setStroke(new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        
        if (isElected()) {
            paintPolygon(points);
        }
        else {
            paintHollowPolygon(points);
        }
    }

}
