package de.duehl.swing.ui.elements.watch;

/*
 * 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 javax.swing.JLabel;
import javax.swing.SwingUtilities;

import de.duehl.basics.datetime.time.watch.StopWatch;
import de.duehl.basics.datetime.time.watch.WatchBase;

/**
 * Diese Klasse stellt die Basis eines Labels dar, das die auf ihm angezeigte Uhr automatisch
 * aktualisiert.
 *
 * @version 1.01     2021-03-17
 * @author Christian Dühl
 */

public class WatchBaseLabel extends JLabel {

    private static final long serialVersionUID = 1L;

    /** Text vor der Zeit. */
    private volatile String startText;

    /** Text nach der Zeit. */
    private volatile String endText;

    /** Uhr, deren Zeit angezeigt wird. */
    private final WatchBase watch;

    /** Das Runnable, das die Aktualisierung behandelt. */
    private WatchActualisationRunnable actualisationRunnable;

    /** Gibt an, auch die Sekunden oder nur Stunden und Minuten angezeigt werden. */
    private boolean showSeconds;

    /** Konstruktor ohne Text vor und nach der Stoppuhr. */
    public WatchBaseLabel() {
        this("", new StopWatch(), "");
    }

    /**
     * Konstruktor mit Text vor und nach der Zeit sowie eigener Uhr, die übergeben wird.
     *
     * @param startText
     *            Text vor der Stoppuhr.
     * @param watch
     *            Uhr, deren Zeit angezeigt wird.
     * @param endText
     *            Text nach der Stoppuhr.
     */
    public WatchBaseLabel(String startText, WatchBase watch, String endText) {
        super();
        this.startText = startText;
        this.watch = watch;
        this.endText = endText;

        showSeconds = true;
        //GuiTools.setMonospacedFont(this);
        createRunnableAndStartActualisationThread();
    }

    /** Erstellt ein neues Runnable-Objekt und startet es in einem Thread. */
    protected final void createRunnableAndStartActualisationThread() {
        actualisationRunnable = new WatchActualisationRunnable(this);
        Thread thread = new Thread(actualisationRunnable);
        thread.start();
    }

    /** Hält das Runnable-Objekt an. */
    public final void stopActualisationRunnable() {
        actualisationRunnable.stop();
    }

    /** Setter für den Text vor der Stoppuhr. */
    public final void setStartText(String startText) {
        this.startText = startText;
        setWatchText();
    }

    /** Setter für den Text nach der Stoppuhr. */
    public final void setEndText(String endText) {
        this.endText = endText;
        setWatchText();
    }

    /**
     * Setzt die Millisekunden zwischen den Aktualisierungen des StopWatchLabels. Default ist 50ms.
     */
    public final void setSleepTimeMillis(int sleepTimeMillis) {
        actualisationRunnable.setSleepTimeMillis(sleepTimeMillis);
    }

    /** Gibt an, dass nur Stunden und Minuten angezeigt werden sollen. */
    public final void hideSeconds() {
        showSeconds = false;
    }

    /**
     * Setzt den richtigen anzuzeigenden Text. (aus dem Aktualisierungs-Runnable und Methoden
     * dieser Klasse).
     */
    final void setWatchText() {
        SwingUtilities.invokeLater(() -> setStopWatchTextInEdt());
    }

    private void setStopWatchTextInEdt() {
        setText(createWatchLabelText());
    }

    protected final String createWatchLabelText() {
        String time = watch.getTime();
        if (!showSeconds) {
            time = time.substring(0, time.length() - 3);
        }
        return startText + time + endText;
    }

    /**
     * Liest die Zeit auf der Uhr ab und gibt sie in einem von Menschen lesbarem Format zurück.
     *
     * @return Zeit im Format HH:MM:SS.
     */
    public final String getTime() {
        return watch.getTime();
    }

    /** Stringrepräsentation. */
    @Override
    public String toString() {
        return "WatchBaseLabel [" + createWatchLabelText() + "]";
    }


}
