/*
  MidiSynth, MIDI synthesiser, a repacement for the Acorn MIDI module

  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 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 TimestampToDate(unsigned int t, datetime_t *dt);
int load_defaults(ins_data_t* idat);
int load_file(ins_data_t* idat, char *filename);

#endif
