/*
 *
 *    soniK digital audio editor
 *    Copyright (C) 2003-2006  Robert Walker <rob@tenfoot.org.uk>
 *
 *    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.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
#ifndef SONIK_NORMAL_DISPLAY_PLUGIN_H
#define SONIK_NORMAL_DISPLAY_PLUGIN_H

#include "display.h"
#include "wavewidget.h"

#include <klibloader.h>

#include <qcolor.h>
#include <qpen.h>

class NormalDisplayConfigDlg;

namespace Sonik
{
  class NormalDisplayPlugin : public Sonik::Display
  {
    Q_OBJECT
  public:
    class Widget : public Sonik::WaveWidget
    {
    public:
      Widget(const NormalDisplayPlugin& display,
             const Data& data, uint8_t channel,
             QWidget* parent = 0, const char* name = 0);
      virtual ~Widget();

    protected:
      virtual void render(QPainter& p, const QRect& r);
      virtual void clearCache(CacheClearOp op, off_t start, size_t length);

    private:
      void drawBackground(QPainter& p, const QRect& r,
                          bool selection, int selLeft, int selRight);
      void drawAxes(QPainter& p, const QRect& r,
                    int vCentre, int maxDisp);
      void drawSamples(QPainter& p, const QRect& r,
                       int vCentre, int maxDisp,
                       bool selection, int selLeft, int selRight);
      void drawSamplesZoomedFarOut(QPainter& p, const QRect& r,
                                   int vCentre, int maxDisp,
                                   bool selection, int selLeft, int selRight,
                                   uint start, uint end, uint length,
                                   uint pre, uint post, uint validLength);
      void drawSamplesZoomedOut(QPainter& p, const QRect& r,
                                int vCentre, int maxDisp,
                                bool selection, int selLeft, int selRight,
                                uint start, uint end, uint length,
                                uint pre, uint post, uint validLength);
      void drawSamplesZoomedIn(QPainter& p, const QRect& r,
                               int vCentre, int maxDisp,
                               bool selection, int selLeft, int selRight,
                               uint start, uint end, uint length,
                               uint pre, uint post, uint validLength);

      void getMinMaxData(off_t pos, size_t length, size_t samplePerPixel,
                         SampleBuffer& min, SampleBuffer& max);

      // Cache data is keyed on:
      //   (window size)[(pos / zoom level)]
      struct CacheEntry
      {
        CacheEntry() : valid(false) {}

        bool   valid;
        Sample min;
        Sample max;
      };
      typedef size_t CacheKey;
      typedef QValueVector<CacheEntry> CacheData;
      typedef QMap<CacheKey, CacheData> Cache;

      const NormalDisplayPlugin& mDisplay;

      Cache mCache;
    };

    NormalDisplayPlugin(QObject* parent, const char* name,
                        const QStringList& args);
    virtual ~NormalDisplayPlugin();

    virtual WaveWidget* makeWidget(const Data& data,
                                   uint8_t channel,
                                   QWidget* parent = 0,
                                   const char* name = 0) const;

    virtual VerticalAxis verticalAxis() const { return Display::kValue; }
    virtual uint32_t verticalBorder() const;

    const QColor& backgroundColour() const       { return mBackgroundColour; }
    const QPen&   wavePen() const                { return mWavePen; }
    const QPen&   gridPen() const                { return mGridPen; }
    const QColor& sampleColour() const           { return mSampleColour; }
    const QColor& selectBackgroundColour() const { return mSelectBackgroundColour; }
    const QColor& selectColour() const           { return mSelectColour; }

    virtual QWidget* makeConfigPage(QWidget* parent=0);
    virtual void     applyConfigPage();

  private:
    void     applyConfig();

    QColor mBackgroundColour;
    QPen   mWavePen;
    QPen   mGridPen;
    QColor mSampleColour;
    QColor mSelectBackgroundColour;
    QColor mSelectColour;

    NormalDisplayConfigDlg *mConfigDlg;
  };
}

#endif // SONIK_NORMAL_DISPLAY_PLUGIN_H
