package de.duehl.swing.ui.tabs.close;

/*
 * Copyright 2021 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.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.JButton;

/**
 * Diese Klasse stellt einen kleinen Schalter zum Schließen eines Reiters dar.
 *
 * @version 1.01     2021-03-30
 * @author Christian Dühl
 */

public class CloseTabButton extends JButton {

    private static final long serialVersionUID = 1L;

    private static final Dimension BUTTON_DIMENSION = new Dimension(17, 17);

    /**
     * Eindeutige Bezeichnung des Tabulators, wie etwa der Name einer Datei, das Login eines
     * Benutzers oder die ID der Gruppe, zu dem bzw. der der Reiter gehört.
     */
    private final String tabIdentifier;

    /** Objekt, das über das Schließen des Reiters informiert wird. */
    private final CloseButtonReaktor closeButtonReaktor;

    /**
     * Konstruktor.
     *
     * @param tabIdentifier
     *            Eindeutige Bezeichnung des Tabulators, wie etwa der Name einer Datei, das Login
     *            eines Benutzers oder die ID der Gruppe, zu dem bzw. der der Reiter gehört.
     * @param closeButtonReaktor
     *            Objekt, das über das Schließen des Reiters informiert wird.
     */
    public CloseTabButton(String tabIdentifier, CloseButtonReaktor closeButtonReaktor) {
        super();
        this.tabIdentifier = tabIdentifier;
        this.closeButtonReaktor = closeButtonReaktor;

        setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
        setPreferredSize(BUTTON_DIMENSION);
        addCloseActionListener();
        setContentAreaFilled(false);

        setFocusable(false);
        setBorder(BorderFactory.createEtchedBorder());
        setBorderPainted(false);

        addMouseListener(BUTTON_MOUSE_LISTENER);
        setRolloverEnabled(true);
    }

    /** Fügt einen ActionListener hinzu, der das Schließen dieses Tabs veranlasst. */
    private void addCloseActionListener() {
        addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                closeButtonReaktor.closeButtonPressed(tabIdentifier);
                removeActionListener(this); // this bezieht sich hier auf den ActionListener.
            }
        });
    }

    /**
     * Da der ActionListener entfernt wird, wenn der Close-Button gedrückt wird, muss wieder ein
     * solcher installiert werden, wenn der Reiter wieder aktiviert wird.
     */
    public void reactivate() {
        addCloseActionListener();
    }

    /** Zeichnet das kleine Kreuz zum Schließen. */
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();

        /* Für gedrückte Buttons wird die Grafik sacht verschoben: */
        if (getModel().isPressed()) {
            g2.translate(1, 1);
        }

        /* Farbwahl: schwarz normalerweise, wenn die Maus darüber kommt, rot: */
        g2.setStroke(new BasicStroke(2));
        g2.setColor(Color.BLACK);
        if (getModel().isRollover()) {
            g2.setColor(Color.RED);
        }

        int delta = 6;
        g2.drawLine(
                delta,
                delta,
                getWidth() - delta - 1,
                getHeight() - delta - 1);
        g2.drawLine(
                getWidth() - delta - 1,
                delta,
                delta,
                getHeight() - delta - 1);

        g2.dispose();
    }

    /** Ein MouseListener für alle Schließbuttons: */
    private final static MouseListener BUTTON_MOUSE_LISTENER = new MouseAdapter() {
        @Override
        public void mouseEntered(MouseEvent e) {
            Component component = e.getComponent();
            if (component instanceof AbstractButton button) {
                button.setBorderPainted(true);
            }
        }

        @Override
        public void mouseExited(MouseEvent e) {
            Component component = e.getComponent();
            if (component instanceof AbstractButton button) {
                button.setBorderPainted(false);
            }
        }
    };

}
