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

/*
 * 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.util.Random;

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

/**
 * Diese Klasse stellt einen kleinen Schalter dar, der die Seite eines Würfels anzeigt.
 *
 * @version 1.01     2025-07-23
 * @author Christian Dühl
 */

public class DiceButton extends PaintedButton {

    private static final long serialVersionUID = -1L;

    private static final Color BACKGROUND_COLOR = new Color(231, 224, 189);
    private static final Color EYE_COLOR        = new Color( 28,  28,  28);

    public enum RollValue {
        ONE, TWO, THREE, FOUR, FIVE, SIX, NONE;
        public static RollValue selectRandomly() {
            int size = RollValue.values().length;
            int randomIndex = new Random().nextInt(size);
            return RollValue.values()[randomIndex];
        }
        public static RollValue generateFromInteger(int index) {
            switch (index) {
                case 0 : return ONE;
                case 1 : return TWO;
                case 2 : return THREE;
                case 3 : return FOUR;
                case 4 : return FIVE;
                case 5 : return SIX;
                default : return NONE;
            }
        }
    }

    /** Angezeigte Augenzahl. */
    private RollValue rollValue;

    /**
     * Konstruktor.
     *
     * @param rollValue
     *            Angezeigte Augenzahl.
     */
    public DiceButton(RollValue rollValue) {
        super();
        setForceSquare(true);
        this.rollValue = rollValue;
    }

    /**
     * Setter für die Augenzahl.
     *
     * @param rollValue
     *            Angezeigte Augenzahl.
     */
    public void setRollValue(RollValue rollValue) {
        this.rollValue = rollValue;
        repaint();
    }

    /**
     * Farbwahl abhängig davon, ob die Maus über dem Button ist.
     *
     * Die Farbe der Augen auf dem Würfel normalerweise, wenn die Maus darüber kommt, rot.
     */
    @Override
    protected void setSymbolColorInGraphics() {
        graphics2.setColor(EYE_COLOR);
        if (isChangeColorOnMouseOver() && getModel().isRollover()) {
            graphics2.setColor(Color.RED);
        }
    }

    /** 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 ein farbiges Rechteck mit den Augen des Wurfes. Da es dabei egal ist, ob horizontal
     * oder vertikal, wird es in beiden Fällen verwendet. Sinn macht die Anzeige aber hauptsächlich
     * quadratisch.
     */
    private void paintSymbol() {
        int width = getWidth();
        int height = getHeight();

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

        int radius = Math.max(2,  width / 10);

        int delta = (int) Math.max(5, radius * 1.7);

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

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

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

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

        int centerX = (firstLeftPixel + lastRightPixel) /  2;
        int centerY = (firstUpperPixel + lastLowerPixel) /  2;

        PixelPoint leftUpperCorner = new PixelPoint(left, upper);
        PixelPoint rightUpperCorner = new PixelPoint(right, upper);
        PixelPoint leftLowerCorner = new PixelPoint(left, lower);
        PixelPoint rightLowerCorner = new PixelPoint(right, lower);
        PixelPoint center = new PixelPoint(centerX, centerY);
        PixelPoint upperCenter = new PixelPoint(centerX, upper);
        PixelPoint lowerCenter = new PixelPoint(centerX, lower);

        graphics2.setColor(BACKGROUND_COLOR);
        paintTwoPointRectangle(firstLeftPixel, firstUpperPixel, lastRightPixel, lastLowerPixel);

        setSymbolColorInGraphics();
        boolean paintLeftUpperCorner = rollValue == RollValue.FOUR || rollValue == RollValue.FIVE
                || rollValue == RollValue.SIX;
        boolean paintRightUpperCorner =  rollValue == RollValue.TWO || rollValue == RollValue.THREE
                || rollValue == RollValue.FOUR || rollValue == RollValue.FIVE
                || rollValue == RollValue.SIX;
        boolean paintLeftLowerCorner = paintRightUpperCorner;
        boolean paintRightLowerCorner = paintLeftUpperCorner;
        boolean paintCenter = rollValue == RollValue.ONE || rollValue == RollValue.THREE
                || rollValue == RollValue.FIVE;
        boolean paintUpperCenter = rollValue == RollValue.SIX;
        boolean paintLowerCenter = rollValue == RollValue.SIX;

        if (paintLeftUpperCorner) {
            paintCircle(leftUpperCorner, radius);
        }
        if (paintRightUpperCorner) {
            paintCircle(rightUpperCorner, radius);
        }
        if (paintLeftLowerCorner) {
            paintCircle(leftLowerCorner, radius);
        }
        if (paintRightLowerCorner) {
            paintCircle(rightLowerCorner, radius);
        }
        if (paintCenter) {
            paintCircle(center, radius);
        }
        if (paintUpperCenter) {
            paintCircle(upperCenter, radius);
        }
        if (paintLowerCenter) {
            paintCircle(lowerCenter, radius);
        }
    }

}
