/*
  MidiSynth, MIDI synthesiser driver module for the MidiSupport system

  store.h - storage of instrument and bank definitions

  created  14/03/2021

 Main instrument storage

 Instruments are accsessed by   ins_t pitched_instrument = instrument[bank[banks[lo]-1].ins[prg]-1];
 Percussion on channel 10 by    ins_t percussion_instrument = instrument[bank[kits[prg]-1].ins[key]-1];
 A zero index is used to denote an empty entry so valid indexes in banks, kits and bank, start at 1.
*/

#ifndef store_h
#define store_h

typedef struct bank_s
{
  char name[NAME_LEN];                     // bank name
  unsigned short int ins[MIDI_DATA_RANGE]; // instrument index
} bank_t;

typedef struct wave_s
{
  short int wave[1<<SIN_BITS]; // wave data
} wave_t;

#define NUM_HARMS 32
typedef struct harm_s
{
  char name[NAME_LEN]; // wave name
  struct
  {
    short int re; // real component
    short int im; // imaginary component
  } hrm[NUM_HARMS];
} harm_t;

typedef struct ins_data_s
{
  char name[NAME_LEN]; // name of sound set
  unsigned int date;   // creation date/time
  ins_t *instrument;   // pointer to array of instruments, melodic and percussive.
  bank_t *bank;        // pointer to instrument and drum kit banks, array of indexes to instruments[]
  wave_t *wtbl;        // pointer to waveform array
  harm_t *harm;        // pointer to waveform harmonics array
  int num_instruments; // number of entries in instrument[]
  int num_banks;       // number of entries in bank[]
  int num_waves;       // number of entries in wtbl[] and harm[]
  int max_instruments; // maximum number of entries that the current memory allocation will hold
  int max_banks;       // maximum number of entries that the current memory allocation will hold
  int max_waves;       // maximum number of entries that the current memory allocation will hold
  unsigned char banks[MIDI_DATA_RANGE]; // bank selector, indexes to bank[]
  unsigned char kits[MIDI_DATA_RANGE];  // drum kit selector, indexes to bank[]
} ins_data_t;

typedef struct kbd_patch_s
{
  int num; // number of entries in list
  int cur; // currently loaded user instrument patch number
  int max; // maximum number of entries the array will hold
  patch_t *list; // pointer to the array of patches
} kbd_patch_t;

typedef struct datetime_s
{
  short int year; // 2001..2137
  char month;     // 1..12
  char day;       // 1..31
  char hour;      // 0..23
  char minute;    // 0..59
  char second;    // 0..59
  char weekday;   // 0..6 (0 = Monday)
} datetime_t;

void harm_to_wave(const harm_t *h, short int *w);
void TimestampToDate(unsigned int t, datetime_t *dt);
int update_list(ins_data_t* idat);
int save_new(ins_data_t* idat, int instr);

enum{CREATE_NEW, LOCATE_INSTR, MOVE_PATCH}; // "action" values
int save_instrument(ins_data_t* idat, int patch, int action, int instr);

int swap_instruments(ins_data_t* idat, int instr);
int clear_instrument(ins_data_t* idat, int instr, int action);
int update_instrument(ins_data_t* idat, int instr);
int save_harm_wave(ins_data_t* idat, harm_t *h, int w);
int load_defaults(ins_data_t* idat);
int load_file(ins_data_t* idat, char *filename);
int load_csv(ins_data_t* idat, char *filename);

enum{C_SRC, TXT_PATCH, CSV_MAP, TXT_LST}; // "flags" bit numbers
int save_source(ins_data_t* idat, char *filename, int flags);

enum{ALL, NO_WAVES}; // "action" values
int save_data(ins_data_t* idat, char *filename, int action);

#endif
