/*
 *
 *    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_EDIT_H
#define SONIK_EDIT_H

#include "plugin.h"
#include "uicontrol.h"

#include "sonik_types.h"

class QDialog;
class QWidget;

namespace Sonik
{
  class Data;
  class ProcessorSingle;
  class ProcessorBlock;
  class PartWidget;
  class ActionManager;
  class EditApplyDialog;

  class Edit : public Plugin
  {
    Q_OBJECT
  public:
    typedef QMap<QString, float> Preset;

    class PresetManager
    {
    public:
      typedef QMap<QString, Preset> Presets;

      PresetManager(const QString& editorId, KInstance* instance);
      ~PresetManager();

      QStringList presetNames();

      Preset    preset(const QString& presetName);
      void   setPreset(const QString& presetName, Preset preset);

      void loadPresets();
      void savePresets();

    protected:
      QStringList presetFiles();
      QString     userFile();

      void loadPresetFile(const QString& filename,
                          Presets& pluginPresets);
      void savePresetFile(const QString& filename,
                          const Presets& pluginPresets,
                          const QStringList& deletedPresets);

      void generateDeltas(const Presets& current,
                          const Presets& base,
                          Presets&       changed,
                          QStringList&   deleted);

    private:
      QString    mEditorId;
      KInstance* mInstance;

      Presets    mPresets;
      bool       mDirty;
    };

    class Processor
    {
    public:
      virtual ~Processor();

      virtual bool prepare(uint8_t channels, std::size_t len,
                           uint32_t sampleRate, std::size_t blocksize);
      virtual void apply(SampleSegment& seg);
      virtual void cleanup();
    };

    struct PluginContext
    {
      virtual ~PluginContext();

      UiControlPtrList controls;
    };

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

    virtual void init(Data* data,
                      PartWidget* widget,
                      ActionManager* actionManager);

    void pluginDialog(const QString& editorId,
                      QWidget* widget,
                      const QString& caption,
                      const char* applySlot,
                      PluginContext* context);

  protected:
    bool apply(Processor& p, bool selectionOnly = true);
    bool generate(Processor& p, InsertPosition position = kInsertEnd, size_t length = 0);

    Data*          mData;
    PartWidget*    mWidget;
    ActionManager* mActionManager;

    EditApplyDialog* mDialog;

  private:
    void runPlugin(Processor& p, off_t start, size_t length);

  };
}


bool operator==(const Sonik::Edit::Preset& a, const Sonik::Edit::Preset& b);
bool operator!=(const Sonik::Edit::Preset& a, const Sonik::Edit::Preset& b);

#endif // SONIK_EDIT_H
