//=========================================================
//  MusE
//  Linux Music Editor
//    $Id: ctrlcanvas.h,v 1.1.1.1 2003/10/29 10:05:21 wschweer Exp $
//  (C) Copyright 1999 Werner Schweer (ws@seh.de)
//=========================================================

#ifndef __CTRLCANVAS_H__
#define __CTRLCANVAS_H__

#include <list>
#include "view.h"
#include "tools.h"
#include "midictrl.h"

const int CTRL_VELOCITY = 129;

class MidiEvent;
class MidiPart;
class PartList;
class MidiTrack;
class MidiEditor;
class QWidget;

//---------------------------------------------------------
//   CEvent
//    ''visual'' Controller Event
//---------------------------------------------------------

class CEvent {
      MidiEvent* _event;
      int       _val;
      MidiPart* _part;
      int ex;

   public:
      CEvent(MidiEvent* e, MidiPart* part, int v);
      MidiEvent* event() const     { return _event; }
      void setEvent(MidiEvent* ev) { _event = ev; }
      int val() const              { return _val;   }
      void setVal(int v)           { _val = v; }
      void setEX(int v)            { ex = v; }
      MidiPart* part() const       { return _part;  }
      bool contains(int x1, int x2) const;
      int x()                      { return ex; }
      };

typedef std::list<CEvent*>::iterator iCEvent;
typedef std::list<CEvent*>::const_iterator ciCEvent;

//---------------------------------------------------------
//   CEventList
//    Controller Item List
//---------------------------------------------------------

class CEventList: public std::list<CEvent*> {
   public:
      void add(CEvent* item) { push_back(item); }
      };

//---------------------------------------------------------
//   CtrlCanvas
//---------------------------------------------------------

class CtrlCanvas : public View {
      MidiEditor* editor;
      MidiTrack* curTrack;
      MidiPart* curPart;
      MidiController ctrl;

      int line1x;
      int line1y;
      int line2x;
      int line2y;
      bool drawLineMode;

      void viewMousePressEvent(QMouseEvent* event);
      void viewMouseMoveEvent(QMouseEvent*);
      void viewMouseReleaseEvent(QMouseEvent*);

      virtual void draw(QPainter&, const QRect&);
      virtual void pdraw(QPainter&, const QRect&);
      virtual void drawOverlay(QPainter& p);
      virtual QRect overlayRect() const;

      void changeValRamp(int x1, int x2, int y1, int y2);
      void newValRamp(int x1, int y1, int x2, int y2);
      void changeVal(int x1, int x2, int y);
      void newVal(int x1, int x2, int y);
      void deleteVal(int x1, int x2, int y);

      char keyFilter; //Used by the drum-editor to filter controllers of only one key (one drum)

      Q_OBJECT

   protected:
      enum DragMode { DRAG_OFF, DRAG_NEW, DRAG_MOVE_START, DRAG_MOVE,
            DRAG_DELETE, DRAG_COPY_START, DRAG_COPY,
            DRAG_RESIZE, DRAG_LASSO_START, DRAG_LASSO
            };

      CEventList items;
      CEventList selection;
      CEventList moving;
      CEvent* curItem;

      DragMode drag;
      QRect lasso;
      QPoint start;
      Tool tool;
      int pos[3];

      void leaveEvent(QEvent*e);
      QPoint raster(const QPoint&) const;

      // selection
      bool isSingleSelection()  { return selection.size() == 1; }
      void deselectAll();
      void selectItem(CEvent* e);
      void deselectItem(CEvent* e);

   private slots:
      void songChanged(int type);

   public slots:
      void setTool(int t);
      void setPos(int, int, bool adjustScrollbar);
      void setController(const MidiController&);
      void setKeyfilter(const char in_keyfilter);

   signals:
      void followEvent(int);
      void xposChanged(int);
      void yposChanged(int);

   public:
      CtrlCanvas(MidiEditor*, QWidget* parent, int,
         const char* name = 0);
      const MidiController& controller() { return ctrl; }
      };

#endif

