// ----
// ---- file   : MIDIPipeDevice.h
// ---- author : Bastian Spiegel <bs@tkscript.de>
// ---- legal  : (c) 2014-2019 by Bastian Spiegel. 
// ----          Distributed under terms of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL). See 
// ----          http://www.gnu.org/licenses/licenses.html#LGPL or COPYING for further information.
// ----
// ---- info   : This is part of the "syntracker" sequencer.
// ----
// ---- changed: 01Sep2014, 11Jan2015, 16Feb2015, 11Sep2015, 14Sep2015, 09Sep2016, 03Dec2016
// ----          03Mar2017, 22Nov2017, 22Jan2019
// ----
// ----
// ----

#ifndef __TK_MIDIPIPEDEVICE_H__
#define __TK_MIDIPIPEDEVICE_H__

YG("midipipe")


class midipipe_ctl_state_t {
  public:
   sS16 value;  // -1=undef
};

class midipipe_note_state_t {
  public:
   sS32 ticks_left;  // -1=note inactive, 0=manual note-off, >0=auto-off countdown
   sS16 poly_pressure; // -1=undef
   /* sS16 velocity; */
};

class midipipe_device_ch_t {
  public:
   sS16 prg;
   sS16 ch_pressure;
   sS16 pitchbend;
   midipipe_ctl_state_t  cc_states[128];
   midipipe_ctl_state_t  rpn_states[16384];
   midipipe_ctl_state_t  nrpn_states[16384];
   midipipe_note_state_t note_states[128];
   sS16 note_low;
   sU16 note_hi;
   sS16 num_notes;
};


/* @class MIDIPipeDevice,Object
 */
YC class MIDIPipeDevice : public YAC_Object {
  public:
   sUI dev_idx;
   YAC_Buffer *cmd_buffer;   // ref to STX_MIDIOutDevice.cmd_buffer
   YAC_Buffer *note_buffer;  // ref to STX_MIDIOutDevice.note_buffer

   midipipe_device_ch_t channels[16];        // current state
   /* midipipe_device_ch_t channel_resets[16];  // reset state */

   midipipe_device_ch_t shadow_channels[16];  // Shadow copy of channels, never reset (for getCCState(), ..)

   sBool b_midicache;

   sBool b_note_off;  // 1=use 0x8x for note off, 0=use 0x9x vel=0 for note off

   sBool b_global;    // true=use output of last pipe as input of next pipe

   sSI param_mode[16];  // 0=MSBLSB, 1=LSBMSB, 2=MSB (see MIDIIn.h)
  

  public:
   MIDIPipeDevice(void);
   ~MIDIPipeDevice();

   YAC(MIDIPipeDevice);

  public:
   void setDevIdx(sUI _devIdx);

   void clearMIDICache(void);

  public:
   YM void setBuffers(YAC_Buffer *_cmdBuffer, YAC_Buffer *_noteBuffer);

   YM void  setEnableMIDICache (sBool _bEnable);
   YM sBool getEnableMIDICache (void);

   YM void setEnableNoteOffMsg (sBool _bEnable);  // 1=use 0x8x for note off, 0=use 0x9x vel=0 for note off
   YM sBool getEnableNoteOffMsg (void);

   YM void  setEnableGlobal (sBool _bEnable);
   YM sBool getEnableGlobal (void);

   // (note) ret=-1 => undef
   YM sSI getPrg (sUI _ch);
   YM sSI getChPressure (sUI _ch);
   YM sSI getPitchbend (sUI _ch);
   YM sSI getCCState (sUI _ch, sUI _cc);
   YM sSI getRPNState (sUI _ch, sUI _rpn);
   YM sSI getNRPNState (sUI _ch, sUI _nrpn);
   YM sSI getPolyPressure (sUI _ch, sUI _note);

   // 0=MSBLSB, 1=LSBMSB, 2=MSB  (see MIDIIn.h:MIDI_DATAENTRYMODE_xxx)
   YM void setParamMode (sUI _ch, sSI _mode);
   YM sSI  getParamMode (sUI _ch);
};


#endif // __TK_MIDIPIPEDEVICE_H__
