/*
  midi support system
  main.c
  ------
  13/4/23

  startup code for the support module and drivers
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <kernel.h>
#include <swis.h>


// MIDISupport SWI numbers
#define MIDISupport_InstallDriver   0x4EE80
#define MIDISupport_RemoveDriver    0x4EE81
#define MIDISupport_DriverInfo      0x4EE82
#define MIDISupport_CreateDriver    0x4EE83
#define MIDISupport_Send            0x4EE84
#define MIDISupport_Receive         0x4EE85
#define MIDISupport_Connect         0x4EE86
#define MIDISupport_ConnectName     0x4EE87
#define MIDISupport_GetAddress      0x4EE88
#define MIDISupport_Insert          0x4EE89

// driver swi numbers
#define MIDIPlay_Control            0x45353
#define USBMidi_Control             0xCDEC0

/*
 * report_error
 * ------------
 */
int report_error(char *errmess, int flags)
{
  _kernel_oserror blk;
  _kernel_swi_regs regs;

  blk.errnum = 1;
  strcpy(blk.errmess, errmess);
  regs.r[0] = (int)&blk;
  regs.r[1] = flags;
  regs.r[2] = (int)"Midi Support Startup";
  _kernel_swi(Wimp_ReportError, &regs, &regs);

  /* Returns 1 if OK selected, 2 if Cancel selected */
  return regs.r[1];
}


/*
 * read_config
 * -----------
 * returns non zero on error
 */
static int read_config(const char* filename)
{
  _kernel_swi_regs regs;
  _kernel_oserror *err;
  FILE *f;
  char s[256], src[64], dst[64];
  enum {ST_NULL,ST_INSTALL,ST_CONNECT,ST_PLAYER,ST_USB} state = ST_NULL;
  int value;

  if((f = fopen(filename,"r")) == 0)
    return -1;

  while(fgets(s, 255, f))
  {
    *strchr(s, '\n') = 0; // replace line end with null

    if(s[0] != '#')
    {
      if(strncmp(s, "Install:", 8) == 0)
        state = ST_INSTALL;
      else if(strncmp(s, "Connect:", 8) == 0)
        state = ST_CONNECT;
      else if(strncmp(s, "PlayerOpts:", 11) == 0)
        state = ST_PLAYER;
      else if(strncmp(s, "USBOpts:", 8) == 0)
        state = ST_USB;
      else
        switch(state)
        {
          case ST_NULL:
            break;

          case ST_INSTALL:
            if(sscanf(s, " %s", src) == 1)
            {
              sprintf(s, "<MIDISupport$Dir>.Drivers.%s", src);
              regs.r[0] = 1; // RMLoad
              regs.r[1] = (int)s;
              if((err = _kernel_swi(OS_Module, &regs, &regs)) != 0)
                report_error(err->errmess, 1);
            }
            break;

          case ST_CONNECT:
            if(sscanf(s, " %s to %s", src , dst) == 2)
            {
              regs.r[0] = 1; // connect
              regs.r[1] = (int)src;
              regs.r[2] = (int)dst;
              _kernel_swi(MIDISupport_ConnectName, &regs, &regs);
            }
            break;

          case ST_PLAYER:
            if(sscanf(s, " Tempo: %d", &value) == 1)
              regs.r[0] = 1;
            else if(sscanf(s, " Pitch: %d", &value) == 1)
              regs.r[0] = 2;
            else if(sscanf(s, " Options: %d", &value) == 1)
              regs.r[0] = 3;
            else
              break;
            if(regs.r[0] < 3)
              regs.r[1] = value;
            else
            {
              regs.r[1] = 3; // 2 option bits
              regs.r[2] = value;
            }
            _kernel_swi(MIDIPlay_Control, &regs, &regs);
            break;

          case ST_USB:
            if(sscanf(s, " Options: %d", &value) == 1)
              regs.r[0] = 1;
            else
              break;
            regs.r[1] = 1; // 1 option bit
            regs.r[2] = value;
            _kernel_swi(USBMidi_Control, &regs, &regs);
            break;
        }
    }
  }
  fclose(f);

  return 0;
}


/*
 * main
 * ----
 * Initialisation tasks.
 */
int main(int argc, char *argv[])
{
  read_config("<MIDISupport$Dir>.!Config");

  return 0;
}
