#ifndef SCSTWSTARTSOUNDPLAYER_H
#define SCSTWSTARTSOUNDPLAYER_H

#include <QObject>
#include <QFile>
#include <QAudioOutput>
#include <QDebug>
#include <QEventLoop>
#include <QTimer>
#include <QDateTime>

/*!
 * \brief The ScStwSoundPlayer class is used for ultra low latency sound playback of the speed clibing start tones and commands
 */
class ScStwSoundPlayer : public QObject
{
    Q_OBJECT
public:
    /*!
     * \brief ScStwSoundPlayer constructor
     * \param parent
     */
    explicit ScStwSoundPlayer(QObject *parent = nullptr);

private:
    /*!
     * \brief A map containing all sound files
     * 0: AtYourMarksSound
     * 1: ReadySound
     * 2: StartSound
     */
    QMap<int, QFile*> soundFiles;

    /*!
     * \brief Containng the false start sound file
     */
    QFile *falseStartSoundFile;

    /*!
     * \brief The audio output object
     */
    QAudioOutput *audioOutput;

    /*!
     * \brief The QEventLoop used to wait for the sound to finish
     */
    QEventLoop *waitLoop;

    /*!
     * \brief The QTimer to wait for the sound to finish
     */
    QTimer *waitTimer;

    /*!
     * \brief The action that is currently played
     */
    int currentlyPlayingAction;

public slots:

    /*!
     * \brief Function to begin playing the sound of a certain state
     * \param action The action to play (0: AtYourMarks, 1:Ready, 2:Start)
     * \param volume The volume to play at
     * \param timeOfStop The time the playback actually started (msecs since epoch)
     * \return true if the playback was successfully started, false otherwise
     */
    bool play(int action, double volume, double *timeOfStart = nullptr);

    /*!
     * \brief Function to wait for the playback to finish
     * \param timeOfStop the point in time when the plyback actually stopped (msecs since epoch)
     * \return false if there was any error (eg. there was no playback currently), true otherwise
     */
    bool waitForSoundFinish(double *timeOfStop = nullptr);

    /*!
     * \brief Function to cancel the current playback
     *
     * Note that this function will automatically play the false start tone if the currently playing action is 2
     *
     * \param volume the volume to play the false start sound at
     * \return true if the playback was successfully stopped, false otherwise
     */
    bool cancel(double volume = 0);

private slots:

    /*!
     * \brief Handle a state change of the audio output
     * \param newState the new state of the audio output
     */
    void handleStateChanged(QAudio::State newState);

signals:

    /*!
     * \brief Emitted whenever a playback started
     */
    void playbackStarted();

};

#endif // SCSTWSTARTSOUNDPLAYER_H
