//=========================================================
//  MusE
//  Linux Music Editor
//  $Id: mpevent.cpp,v 1.6 2004/05/16 16:54:59 wschweer Exp $
//
//  (C) Copyright 2002-2004 Werner Schweer (ws@seh.de)
//=========================================================

#include "mpevent.h"

#include "helper.h"
#include "event.h"
#include "midictrl.h"
#include "midiport.h"
#include "muse/midi.h"

//---------------------------------------------------------
//   MEvent
//---------------------------------------------------------

MEvent::MEvent(unsigned t, int port, int tpe, const unsigned char* data, int len)
      {
      _time = t;
      _port = port;
      edata.setData(data, len);
      _type = tpe;
      }

MEvent::MEvent(unsigned tick, int port, int channel, const Event& e)
      {
      setChannel(channel);
      setTime(tick);
      setPort(port);
      switch(e.type()) {
            case Note:
                  setType(ME_NOTEON);
                  setA(e.dataA());
                  setB(e.dataB());
                  break;
            case Controller:
                  setType(ME_CONTROLLER);
                  setA(e.dataA());  // controller number
                  setB(e.dataB());  // controller value
                  break;
            case PAfter:
                  setType(ME_POLYAFTER);
                  setA(e.dataA());
                  setB(e.dataB());
                  break;
            case CAfter:
                  setType(ME_AFTERTOUCH);
                  setA(e.dataA());
                  setB(0);
                  break;
            case Sysex:
                  setType(ME_SYSEX);
                  setData(e.eventData());
                  break;
            default:
                  printf("MEvent::MEvent(): event type %d not implemented\n",
                     type());
                  break;
            }
      }

//---------------------------------------------------------
//   dump
//---------------------------------------------------------

void MEvent::dump() const
      {
      printf("time:%d port:%d chan:%d ", _time, _port, _channel+1);
      if (_type == 0x90) {   // NoteOn
            QString s = pitch2string(_a);
            printf("NoteOn %s(0x%x) %d\n", s.latin1(), _a, _b);
           }
      else if (_type == 0xf0) {
            printf("SysEx len %d 0x%0x ...\n", len(), data()[0]);
            }
      else
            printf("type:0x%02x a=%d b=%d\n", _type, _a, _b);
      }

//---------------------------------------------------------
//   operator <
//---------------------------------------------------------

bool MEvent::operator<(const MEvent& e) const
      {
      if (time() != e.time())
            return time() < e.time();
      if (port() != e.port())
            return port() < e.port();

      // play note off events first to prevent overlapping
      // notes

      if (channel() == e.channel())
            return type() == ME_NOTEOFF
               || (type() == ME_NOTEON && dataB() == 0);

      int map[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 14, 15 };
      return map[channel()] < map[e.channel()];
      }

