/*************************************************************************
           LevelMeter.h  -  multi-track audio level meter
                             -------------------
    view copyright       : Copyright 2002 Rik Hemsley (rikkus) <rik@kde.org>

    begin                : Mon Nov 17 2003
    copyright            : (C) 2003 by Thomas Eschenbacher
    email                : Thomas.Eschenbacher@gmx.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef LEVEL_METER_H
#define LEVEL_METER_H

#include "config.h"

#include <QColor>
#include <QQueue>
#include <QTimer>
#include <QVector>
#include <QWidget>

#include "libkwave/Sample.h"
#include "libkwave/SampleArray.h"

class QPaintEvent;
class QTimer;

namespace Kwave
{
    class LevelMeter: public QWidget
    {
        Q_OBJECT
    public:
        /** Constructor */
        explicit LevelMeter(QWidget *parent);

        /** Destructor */
        virtual ~LevelMeter() Q_DECL_OVERRIDE;

        /** @see QWidget::paintEvent */
        virtual void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;

        /** @see QWidget::resizeEvent */
        virtual void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE;

    public slots:

        /** sets the number of tracks that the display should use */
        virtual void setTracks(unsigned int tracks);

        /**
         * sets the sample rate for interpreting the samples used
         * for updating the display.
         */
        virtual void setSampleRate(double rate);

        /**
         * Updates a apecific track
         * @param track index of the track
         * @param buffer array with samples
         */
        virtual void updateTrack(unsigned int track,
                                 const Kwave::SampleArray &buffer);

        /**
         * Resets all meters to zero
         */
        virtual void reset();

        /**
         * Redraws the whole widget
         * @author (original idea taken from) Rik Hemsley (rikkus) <rik@kde.org>
         *          Copyright 2002
         */
        virtual void drawContents();

    protected slots:

        /** Called via m_timer to update the bar(s) */
        virtual void timedUpdate();

    protected:

        /**
         * Enqueue a pair of fast and peak value of a track for later timed
         * update. If the queue already contains the maximum number of elements,
         * the oldest ones will be removed.
         *
         * @param track index of the track [0...m_tracks-1]
         * @param fast value of the fast level bar [0.0 ... 1.0]
         * @param peak value of the peak level [0.0 ... 1.0]
         * @param queue_depth maximum number of elements to queue
         */
        virtual void enqueue(unsigned int track, float fast, float peak,
                             unsigned int queue_depth);

        /**
         * Dequeue a pair of fast and peek value of a track.
         * @param track index of the track [0...m_tracks-1]
         * @param fast receives the value of the fast level bar [0.0 ... 1.0]
         * @param peak receives value of the peak level [0.0 ... 1.0]
         * @return true if there was something to dequeue, false if
         *         the queue was empty.
         * @note fast and peak will not be modified if the queue was empty
         */
        virtual bool dequeue(unsigned int track, float &fast, float &peak);

        /**
         * Draw some scale into the meter, using 3dB steps
         * @param p an already opened QPainter
         */
        void drawScale(QPainter &p);

    private:

        /** number of tracks */
        int m_tracks;

        /** sample rate used for interpreting the received buffers */
        float m_sample_rate;

        /** last output value of the filter for fast updates */
        QVector<float> m_yf;

        /** last output value of the filter for peak updates */
        QVector<float> m_yp;

        /** queues with fast update values for each track */
        QVector< QQueue<float> > m_fast_queue;

        /** queues with peak values for each track */
        QVector< QQueue<float> > m_peak_queue;

        /** current fast value for each track */
        QVector<float> m_current_fast;

        /** current peak value for each track */
        QVector<float> m_current_peak;

        /** timer for display updates */
        QTimer *m_timer;

        /** color for low levels, below -3dB */
        QColor m_color_low;

        /** color for normal levels, -3dB...-1.5dB */
        QColor m_color_normal;

        /** color high levels, above -1.5dB */
        QColor m_color_high;

    };
}

#endif /* LEVEL_METER_H */

//***************************************************************************
//***************************************************************************
