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

#ifndef __MINSTRUMENT_H__
#define __MINSTRUMENT_H__

#include "globaldefs.h"
#include <list>
#include <vector>
#include <qstring.h>

class MidiPort;
class QPopupMenu;
class MidiPlayEvent;
class Xml;
class EventList;

//---------------------------------------------------------
//   Patch
//---------------------------------------------------------

struct Patch {
      signed char typ;                     // 1 - GM  2 - GS  4 - XG
      signed char hbank, lbank, prog;
      QString name;
      bool drum;
      void read(Xml&);
      };

//---------------------------------------------------------
//   MidiInstrument
//---------------------------------------------------------

class MidiInstrument {

   protected:
      EventList* _midiInit;
      EventList* _midiReset;
      EventList* _midiState;
      QString _name;

   public:
      MidiInstrument();
      virtual ~MidiInstrument();
      MidiInstrument(const QString& txt);
      const QString& iname() const      { return _name; }
      void setIName(const QString& txt) { _name = txt; }

      EventList* midiInit() const       { return _midiInit; }
      EventList* midiReset() const      { return _midiReset; }
      EventList* midiState() const      { return _midiState; }

      void readMidiState(Xml& xml);
      virtual bool guiVisible() const   { return false; }
      virtual void showGui(bool)        {}
      virtual bool hasGui() const       { return false; }
      virtual void writeToGui(const MidiPlayEvent*) {}

      virtual void reset(int, MType);
      virtual const char* getPatchName(int,int,int,int,MType);
      virtual void populatePatchPopup(QPopupMenu*, int, MType) {}
      };

//---------------------------------------------------------
//   MidiInstrumentList
//---------------------------------------------------------

class MidiInstrumentList : public std::list<MidiInstrument*> {

   public:
      MidiInstrumentList() {}
      };

typedef std::list<MidiInstrument*>::iterator iMidiInstrument;
typedef std::list<Patch> PatchList;

//---------------------------------------------------------
//   PatchGroup
//---------------------------------------------------------

struct PatchGroup {
      QString name;
      PatchList patches;
      void read(Xml&);
      };

//---------------------------------------------------------
//   MidiIDFInstrument
//---------------------------------------------------------

class MidiIDFInstrument : public MidiInstrument {
      std::vector<PatchGroup> pg;

   public:
      MidiIDFInstrument() {};
      virtual void reset(int port, MType type);
      virtual const char* getPatchName(int, int, int, int, MType);
      virtual void populatePatchPopup(QPopupMenu*, int, MType);
      void read(Xml&);
      };

extern MidiInstrumentList midiInstruments;
extern MidiInstrument* genericMidiInstrument;
extern void initMidiInstruments();
extern MidiInstrument* registerMidiInstrument(const QString&);
extern void removeMidiInstrument(const QString& name);

#endif

