/*

    This file is part of QProgressIndicator,
    an open-source recent files menu widget

    SPDX-FileCopyrightText: 2009-2010 Morgan Leborgne
    SPDX-License-Identifier: LGPL-3.0-or-later
*/

#pragma once

#include <QWidget>
#include <QColor>

/**
 * @class QProgressIndicator
 * @brief The QProgressIndicator class lets an application display a progress indicator to show that a long task is
 * under way.
 * Progress indicators are indeterminate and do nothing more than spin to show that the application is busy.
 *
 * @sa QProgressBar
 */
class QProgressIndicator : public QWidget
{
        Q_OBJECT
        Q_PROPERTY(int delay READ animationDelay WRITE setAnimationDelay)
        Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped)
        Q_PROPERTY(QColor color READ color WRITE setColor)
    public:
        explicit QProgressIndicator(QWidget *parent = nullptr);

        /**
         * Returns the delay between animation steps.
         * @return The number of milliseconds between animation steps. By default, the animation delay is set to
         * 40 milliseconds.
         *
         * @sa setAnimationDelay
         */
        int animationDelay() const
        {
            return m_delay;
        }

        /**
         * Returns a Boolean value indicating whether the component is currently animated.
         * @return Animation state.
         * @sa startAnimation stopAnimation
         */
        bool isAnimated() const;

        /**
         * Returns a Boolean value indicating whether the receiver shows itself even when it is not animating.
         * @return Return true if the progress indicator shows itself even when it is not animating. By default,
         * it returns false.
         * @sa setDisplayedWhenStopped
         */
        bool isDisplayedWhenStopped() const;

        /**
         * Returns the color of the component.
         * @sa setColor
         */
        const QColor &color() const
        {
            return m_color;
        }

        QSize sizeHint() const override;
        int heightForWidth(int w) const override;
    public Q_SLOTS:
        /**
         * Starts the spin animation.
         * @sa stopAnimation isAnimated
         */
        void startAnimation();

        /**
         * Stops the spin animation.
         * @sa startAnimation isAnimated
         */
        void stopAnimation();

        /**
         * Sets the delay between animation steps.
         * Setting the \a delay to a value larger than 40 slows the animation, while setting the @a delay to a
         * smaller value speeds it up.
         * @param delay The delay, in milliseconds.
         * @sa animationDelay
         */
        void setAnimationDelay(int delay);

        /**
         * Sets whether the component hides itself when it is not animating.
         * @param state The animation state. Set false to hide the progress indicator when it is not animating; otherwise true.
         * @sa isDisplayedWhenStopped
         */
        void setDisplayedWhenStopped(bool state);

        /**
         * Sets the color of the components to the given color.
         * @sa color
         */
        void setColor(const QColor &color);

    protected:
        void timerEvent(QTimerEvent *event) override;
        void paintEvent(QPaintEvent *event) override;

    private:
        int m_angle { 0 };
        int m_timerId { -1 };
        int m_delay { 40 };
        bool m_displayedWhenStopped { false };
        QColor m_color { Qt::black };
};
