/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#include "prologue.h"

#include "log.h"
#include "parse.h"
#include "timing.h"
#include "midi.h"

struct MidiDeviceStruct {
  HMIDIOUT handle;
  unsigned char note;
  int count;
  char buffer[0X80];
};

typedef enum {
  MIDI_NoteOff        = 0X80,
  MIDI_NoteOn         = 0X90,
  MIDI_KeyPressure    = 0XA0,
  MIDI_ControlChange  = 0XB0,
  MIDI_ProgramChange  = 0XC0,
  MIDI_ChannelPresure = 0XD0,
  MIDI_PitchBend      = 0XE0,
  MIDI_SystemPrefix   = 0XF0
} MidiEvent;

static void
logMidiOutError (MMRESULT error, int errorLevel, const char *action) {
  char text[MAXERRORLENGTH];
  midiOutGetErrorText(error, text, sizeof(text));
  logMessage(errorLevel, "%s error %d: %s", action, error, text);
}

static int
addMidiMessage (MidiDevice *midi, const unsigned char *message, int length) {
  if ((midi->count + length) > sizeof(midi->buffer))
    if (!flushMidiDevice(midi))
      return 0;

  memcpy(&midi->buffer[midi->count], message, length);
  midi->count += length;
  return 1;
}

static int
writeMidiMessage (MidiDevice *midi, const unsigned char *message, int length) {
  if (!addMidiMessage(midi, message, length)) return 0;
  if (!flushMidiDevice(midi)) return 0;
  return 1;
}

MidiDevice *
openMidiDevice (int errorLevel, const char *device) {
  MidiDevice *midi;
  MMRESULT error;
  int id = 0;
  static const char *const defaultDevice = "default";

  if (!*device) device = defaultDevice;

  if (strcmp(device, defaultDevice) == 0) {
    id = -1;
  } else if (!isInteger(&id, device) || (id < 0) || (id >= midiOutGetNumDevs())) {
    int count = midiOutGetNumDevs();
    for (id=0; id<count; ++id) {
      MIDIOUTCAPS cap;
      if (midiOutGetDevCaps(id, &cap, sizeof(cap)) == MMSYSERR_NOERROR)
        if (strncasecmp(device, cap.szPname, strlen(device)) == 0)
          break;
    }

    if (id == count) {
      logMessage(errorLevel, "invalid MIDI device number: %s", device);
      return NULL;
    }
  }

  if ((midi = malloc(sizeof(*midi)))) {
    if ((error = midiOutOpen(&midi->handle, id, 0, 0, CALLBACK_NULL)) == MMSYSERR_NOERROR) {
      midi->note = 0;
      midi->count = 0;
      return midi;
    } else {
      logMidiOutError(error, errorLevel, "MIDI device open");
    }

    free(midi);
  } else {
    logSystemError("MIDI device allocation");
  }
  return NULL;
}

void
closeMidiDevice (MidiDevice *midi) {
  flushMidiDevice(midi);
  midiOutClose(midi->handle);
  free(midi);
}

int
flushMidiDevice (MidiDevice *midi) {
  int ok = 1;

  if (midi->count > 0) {
    MMRESULT error;
    MIDIHDR header;
    
    header.lpData = midi->buffer;
    header.dwBufferLength = midi->count;
    header.dwFlags = 0;

    if ((error = midiOutPrepareHeader(midi->handle, &header, sizeof(header))) == MMSYSERR_NOERROR) {
      if ((error = midiOutLongMsg(midi->handle, &header, sizeof(header))) == MMSYSERR_NOERROR) {
        midi->count = 0;
      } else {
        logMidiOutError(error, LOG_ERR, "midiOutLongMsg");
        ok = 0;
      }

      while ((error = midiOutUnprepareHeader(midi->handle, &header, sizeof(header))) == MIDIERR_STILLPLAYING) {
        approximateDelay(1);
      }

      if (error != MMSYSERR_NOERROR) {
        logMidiOutError(error, LOG_ERR, "midiOutUnprepareHeader");
      }
    } else {
      logMidiOutError(error, LOG_ERR, "midiOutPrepareHeader");
      ok = 0;
    }
  }

  return ok;
}

int
setMidiInstrument (MidiDevice *midi, unsigned char channel, unsigned char instrument) {
  const unsigned char message[] = {
    MIDI_ProgramChange|channel, instrument
  };
  return writeMidiMessage(midi, message, sizeof(message));
}

int
beginMidiBlock (MidiDevice *midi) {
  return 1;
}

int
endMidiBlock (MidiDevice *midi) {
  return 1;
}

int
startMidiNote (MidiDevice *midi, unsigned char channel, unsigned char note, unsigned char volume) {
  const unsigned char message[] = {
    MIDI_NoteOn|channel, note, (0X7F * volume / 100)
  };
  int ok = writeMidiMessage(midi, message, sizeof(message));
  if (ok) midi->note = note;
  return ok;
}

int
stopMidiNote (MidiDevice *midi, unsigned char channel) {
  const unsigned char message[] = {
    MIDI_NoteOff|channel, midi->note, 0
  };
  int ok = writeMidiMessage(midi, message, sizeof(message));
  if (ok) midi->note = 0;
  return ok;
}

int
insertMidiWait (MidiDevice *midi, int duration) {
  approximateDelay(duration);
  return 1;
}
