//=========================================================
//  MusE
//  Linux Music Editor
//  $Id: ctrl.h,v 1.4 2004/02/11 22:05:39 spamatica Exp $
//
//    controller for mixer automation
//
//  (C) Copyright 2003-2004 Werner Schweer (ws@seh.de)
//=========================================================

#ifndef __CTRL_H__
#define __CTRL_H__

#include <map>
#include <list>

const int AC_VOLUME = 0;
const int AC_PAN    = 1;
const int AC_MUTE   = 2;

inline int genACnum(int plugin, int ctrl) { return plugin * 0x10000 + ctrl; }

class Xml;

enum CtrlValueType { VAL_LOG, VAL_LINEAR, VAL_INT, VAL_BOOL };

//---------------------------------------------------------
//   CtrlVal
//    controller "event"
//---------------------------------------------------------

struct CtrlVal {
      int frame;
      float val;
      CtrlVal(int f, float v) {
            frame = f;
            val   = v;
            }
      };

//---------------------------------------------------------
//   CtrlRecVal
//    recorded controller event, mixer automation
//---------------------------------------------------------

struct CtrlRecVal : public CtrlVal {
      int id;
      int type;   // 0 - ctrlVal, 1 - start, 2 - end
      CtrlRecVal(int f, int n, float v) : CtrlVal(f, v), id(n), type(0) {}
      CtrlRecVal(int f, int n, int t) : CtrlVal(f, 0.0), id(n), type(t) {}
      };

//---------------------------------------------------------
//   CtrlRecList
//---------------------------------------------------------

class CtrlRecList : public std::list<CtrlRecVal> {
   public:
      };

typedef CtrlRecList::iterator iCtrlRec;

//---------------------------------------------------------
//   CtrlList
//    arrange controller events of a specific type in a
//    list for easy retrieval
//---------------------------------------------------------

typedef std::map<int, CtrlVal, std::less<int> >::iterator iCtrl;
typedef std::map<int, CtrlVal, std::less<int> >::const_iterator ciCtrl;

class CtrlList : public std::map<int, CtrlVal, std::less<int> > {
      enum Mode { INTERPOLATE, DISCRETE};
      Mode _mode;
      int _id;
      float _default;
      float _curVal;
      void del(CtrlVal);
      QString _name;
      float _min, _max;
      CtrlValueType _valueType;

   public:
      CtrlList();
      CtrlList(int id);
      Mode mode() const          { return _mode; }
      void setMode(Mode m)       { _mode = m; }
      float getDefault() const   { return _default; }
      void setDefault(float val) { _default = val; }
      float curVal() const       { return _curVal; }
      void setCurVal(float val)  { _curVal = val; }
      int id() const             { return _id; }
      QString name() const       { return _name; }
      void setName(const QString& s) { _name = s; }
      void setRange(double min, double max) {
            _min = min;
            _max = max;
            }
      void range(double* min, double* max) const {
            *min = _min;
            *max = _max;
            }
      CtrlValueType valueType() const { return _valueType; }
      void setValueType(CtrlValueType t) { _valueType = t; }

      float value(int frame);
      void add(int tick, float value);
      void del(int tick);
      void read(Xml& xml);
      };

//---------------------------------------------------------
//   CtrlListList
//    List of controller value lists.
//    This list represents the controller state of a
//    mixer strip
//---------------------------------------------------------

typedef std::map<int, CtrlList*, std::less<int> >::iterator iCtrlList;
typedef std::map<int, CtrlList*, std::less<int> >::const_iterator ciCtrlList;

class CtrlListList : public std::map<int, CtrlList*, std::less<int> > {
   public:
      void add(CtrlList* vl);
      iCtrlList find(int id) {
            return std::map<int, CtrlList*, std::less<int> >::find(id);
            }
      ciCtrlList find(int id) const {
            return std::map<int, CtrlList*, std::less<int> >::find(id);
            }
      };

#endif

