/*
 *
 *    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_FILE_IO_H
#define SONIK_FILE_IO_H

#include <sonik/plugin.h>

#include <sonik/types.h>

#include <qstring.h>
#include <qstringlist.h>
#include <qmap.h>

class QWidget;

namespace Sonik
{
  class FileIO : public Plugin
  {
    Q_OBJECT
  public:
    class IOBase
    {
    public:
      virtual ~IOBase()                    = 0;

      virtual IOResult open()              = 0;
      virtual void     close()             = 0;

              size_t   length() const      { return mLength; }
              uint8_t  channels() const    { return mChannels; }
              uint32_t sampleRate() const  { return mSampleRate; }
              uint8_t  bits() const        { return mBits; }

              QString  fileName() const    { return mFileName; }
              QString  mimeType() const    { return mMimeType; }

      virtual bool     optionsAvailable()                  = 0;
      virtual QWidget* makeOptionsPage(QWidget* parent=0,
                                       const char *name=0) = 0;
    protected:
      IOBase(const QString& fileName, const QString& mimeType,
             size_t length, uint8_t channels,
             uint32_t sampleRate, uint8_t bits);

      IOBase(const IOBase& rhs);             // Not defined
      IOBase& operator=(const IOBase& rhs);  // Not defined

      QString  mFileName;
      QString  mMimeType;

      size_t   mLength;
      uint8_t  mChannels;
      uint32_t mSampleRate;
      uint8_t  mBits;
    };

    class Reader : public IOBase
    {
    public:
      Reader(const QString& fileName, const QString& mimeType);
      virtual ~Reader() = 0;

      virtual uint32_t read(SampleBuffer& data)         = 0;
    };

    class Writer : public IOBase
    {
    public:
      Writer(const QString& fileName, const QString& mimeType,
             size_t length, uint8_t channels,
             uint32_t sampleRate, uint8_t bits);
      virtual ~Writer() = 0;

      virtual uint32_t write(const SampleBuffer& data)  = 0;
    };

    FileIO(const QString& pluginName, const QString& displayName,
           QObject* parent=0, const char* name=0,
           const QStringList& args=QStringList());
    virtual ~FileIO()                             = 0;

    const QString&     readFilter()     { return mReadFilter; }
    const QString&     writeFilter()    { return mWriteFilter; }

    const QStringList& readMimeTypes()  { return mReadMimeTypes; }
    const QStringList& writeMimeTypes() { return mWriteMimeTypes; }

    virtual Reader* makeReader(const QString& fileName,
                               const QString& mimeType) const = 0;
    virtual Writer* makeWriter(const QString& fileName,
                               const QString& mimeType,
                               size_t length, uint8_t channels,
                               uint32_t sampleRate, uint8_t bits) const = 0;

  protected:
    QString     mReadFilter;
    QString     mWriteFilter;
    QStringList mReadMimeTypes;
    QStringList mWriteMimeTypes;
  };

  class FileIOFactory
  {
  public:
    typedef QMap<QString, FileIO*> MimeTypeMap;
    FileIOFactory();
    virtual ~FileIOFactory();

    void    add(FileIO* f);
    FileIO::Reader* makeReader(const QString& fileName,
                               const QString& mimeType);
    FileIO::Writer* makeWriter(const QString& fileName,
                               const QString& mimeType,
                               size_t length, uint8_t channels,
                               uint32_t sampleRate, uint8_t bits);
  private:
    MimeTypeMap mReaders;
    MimeTypeMap mWriters;
  };
}

#endif // SONIK_FILE_IO_H
