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

#ifndef __MIDIPORT_H__
#define __MIDIPORT_H__

class MidiDevice;
class MidiInstrument;

const int MIDI_PORTS  = 16;   // max Number of Midi Ports

#ifndef MIDI_CHANNELS
#define MIDI_CHANNELS 16       // Channels per Port
#endif

class MidiPlayEvent;

//---------------------------------------------------------
//   ChannelState
//---------------------------------------------------------

struct ChannelState {
      int pitch;              // -8192 -- + 8191
      int program;
      signed char controller[128];
      };

//---------------------------------------------------------
//   MidiPort
//---------------------------------------------------------

class MidiPort {
      ChannelState _iState[MIDI_CHANNELS];    // Initial State
      ChannelState _cState[MIDI_CHANNELS];    // Current State
      MidiDevice* _device;
      int _masterVol;
      QString _state;
      MidiInstrument* _instrument;
      int _rwFlags;      // bits: 1 play, 2 capture, 3 duplex

   public:
      MidiPort();

      bool guiVisible() const;
      void showGui(bool f);
      bool hasGui() const;

      int portno() const;
      int rwFlags() const              { return _rwFlags; }
      void setrwFlags(int val);

      ChannelState* iState(int ch) { return &_iState[ch]; }
      ChannelState* cState(int ch) { return &_cState[ch]; }
      MidiDevice* device() const   { return _device; }
      const QString& state() const { return _state; }
      void setState(const QString& s) { _state = s; }
      void resetCstate(int channel, bool active);
      void resetIstate(int channel, bool active);
      void setMidiDevice(MidiDevice* dev);
      const QString& portname() const;
      MidiInstrument* instrument() const { return _instrument; }
      void setInstrument(MidiInstrument* i) { _instrument = i; }

      void gmOn();
      void gsOn();
      void xgOn();

      void programChange(int chn, int hbank, int lbank, int prg);
      void programChange(int chn, int prg);
      void setCtrl(int chan, int ctrl, int val);
      void nrpn(int chan, int ctrl, int val);
      void rpn(int chan, int ctrl, int val);
      void bender(int chn, int val);

      void clock() const;
      void putStart() const;
      void putContinue() const;
      void putEvent(const MidiPlayEvent*);
      void sysex(const unsigned char* p, int n);

      int masterVol() const { return _masterVol; }

      void setMasterVol(int chan);
      void resetRunstate();
      };

extern MidiPort midiPorts[MIDI_PORTS];
extern void initMidiPorts();

class QPopupMenu;
class QWidget;
extern QPopupMenu* midiPortsPopup(QWidget*);
#endif

