#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <mmsystem.h>
#include <mem.h>
#pragma hdrstop

#include "midiio.hpp"

// Глобальные переменные
extern int  nMode;
extern int  nPosition;
extern DWORD dwFileSize;

//-----------------------------------------------------
// mcimidiOpen
// Открытие устройства вывода
//-----------------------------------------------------

UINT mcimidiOpen(LPSTR szFileName)
{
  MCI_OPEN_PARMS mciOpen;
  MCI_STATUS_PARMS mciStatus;
  DWORD dwrc;
  DWORD dwFlags;

  // Готовим блок параметров
  mciOpen.lpstrDeviceType= (LPSTR)"sequencer";
  mciOpen.lpstrElementName = (LPSTR)szFileName;
  mciOpen.dwCallback = 0;
  mciOpen.wDeviceID = 0;
  mciOpen.wReserved0 = 0;
  mciOpen.lpstrAlias = NULL;

  // Устанавливаем флаги
  dwFlags = MCI_OPEN_TYPE| 
    MCI_OPEN_ELEMENT | MCI_WAIT;

  // Открываем устройство
  dwrc = mciSendCommand(0, MCI_OPEN,
    dwFlags, (DWORD)(LPVOID)&mciOpen);
  if(dwrc)
  {
    mcimidiError(dwrc);
    return 0;
  }

  // Если устройство открыто успешно, определяем
  // длительность звучания в миллисекундах 
  else
  {
    mciStatus.dwItem = MCI_STATUS_LENGTH;
    dwrc = mciSendCommand(mciOpen.wDeviceID, MCI_STATUS,
      MCI_STATUS_ITEM | MCI_WAIT,
      (DWORD)(LPVOID)&mciStatus);
    if(dwrc)
    {
      mcimidiError(dwrc);
      return 0;
    }

    // Сохраняем длительность звучания в глобальной
    // переменной и возвращаем идентификатор устройства вывода
    dwFileSize = mciStatus.dwReturn;
    return mciOpen.wDeviceID;
  }
}

//-----------------------------------------------------
// mcimidiPlay
// Проигрывание загруженного файла MIDI
//-----------------------------------------------------
DWORD mcimidiPlay(HWND hwnd, UINT wDeviceID)
{
  MCI_PLAY_PARMS mciPlayParms;
  DWORD dwrc;

  // Позиционирование на начало фрагмента
  dwrc = mciSendCommand(wDeviceID, MCI_SEEK,
    MCI_WAIT | MCI_SEEK_TO_START, NULL);

  // Идентификатор окна, функция которого получит
  // сообщение MM_MCINOTIFY
  mciPlayParms.dwCallback = (DWORD)hwnd;

  // Запускаем проигрывание
  dwrc=mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY,
    (DWORD)(LPVOID)&mciPlayParms);

  return dwrc;
}

//-----------------------------------------------------
// mcimidiPlayCurrent
// Проигрывание загруженного файла MIDI
// с текущей позиции
//-----------------------------------------------------
DWORD mcimidiPlayCurrent(HWND hwnd, UINT wDeviceID)
{
  MCI_PLAY_PARMS mciPlayParms;
  DWORD dwrc;

  // Идентификатор окна, функция которого получит
  // сообщение MM_MCINOTIFY
  mciPlayParms.dwCallback = (DWORD)hwnd;

  // Запускаем проигрывание
  dwrc=mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY,
    (DWORD)(LPVOID)&mciPlayParms);

  return dwrc;
}

//-----------------------------------------------------
// mcimidiStop
// Останов проигрывания загруженного файла MIDI
//-----------------------------------------------------
DWORD mcimidiStop(UINT wDeviceID)
{
  MCI_GENERIC_PARMS mcigen;
  DWORD dwrc;

  dwrc = mciSendCommand(wDeviceID, MCI_STOP, MCI_WAIT,
    (DWORD)(LPMCI_GENERIC_PARMS)&mcigen);
  if(dwrc)
  {
    mcimidiError(dwrc);
  }

  return dwrc;
}

//-----------------------------------------------------
// mcimidiPause
// Временный останов проигрывания загруженного файла MIDI
//-----------------------------------------------------
DWORD mcimidiPause(UINT wDeviceID)
{
  MCI_GENERIC_PARMS mcigen;
  DWORD dwrc;

  dwrc = mciSendCommand(wDeviceID, MCI_PAUSE, MCI_WAIT,
    (DWORD)(LPMCI_GENERIC_PARMS)&mcigen);
  if(dwrc)
  {
    mcimidiError(dwrc);
  }

  return dwrc;
}

//-----------------------------------------------------
// mcimidiSelectFile
// Выбор файла MIDI
//-----------------------------------------------------
BOOL mcimidiSelectFile(LPSTR lpszFileName)
{
  OPENFILENAME ofn;

  char szFile[256];
  char szFileTitle[256];
  char szFilter[256] =
	 "MIDI Files\0*.mid;*.rmi\0Any Files\0*.*\0";
  szFile[0] = '\0';
  memset(&ofn, 0, sizeof(OPENFILENAME));

  // Инициализируем нужные нам поля
  ofn.lStructSize       = sizeof(OPENFILENAME);
  ofn.hwndOwner         = NULL;
  ofn.lpstrFilter       = szFilter;
  ofn.nFilterIndex      = 1;
  ofn.lpstrFile         = szFile;
  ofn.nMaxFile          = sizeof(szFile);
  ofn.lpstrFileTitle    = szFileTitle;
  ofn.nMaxFileTitle     = sizeof(szFileTitle);
  ofn.lpstrInitialDir   = NULL;
  ofn.Flags =   OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST
               | OFN_HIDEREADONLY;
  // Выбираем входной файл
  if (GetOpenFileName(&ofn))
  {
    // Копируем путь к выбранному файлу
    lstrcpy(lpszFileName, (LPSTR)szFile);
    return TRUE;
  }
  else
    return FALSE;
}

//-----------------------------------------------------
// mcimidiClose
// Закрытие устройства вывода
//-----------------------------------------------------
void mcimidiClose(UINT wDeviceID)
{
  MCI_GENERIC_PARMS mcigen;
  DWORD dwrc;

  dwrc = mciSendCommand(wDeviceID, MCI_CLOSE, MCI_WAIT,
    (DWORD)(LPMCI_GENERIC_PARMS)&mcigen);
  if(dwrc)
  {
    mcimidiError(dwrc);
    return;
  }
}

//-----------------------------------------------------
// mcimidiError
// Обработка ошибок
//-----------------------------------------------------
void mcimidiError(DWORD dwrc)
{
  BYTE szBuf[MAXERRORLENGTH];

  if(mciGetErrorString(dwrc, (LPSTR)szBuf, MAXERRORLENGTH))
    MessageBox(NULL, szBuf,
      "MIDIPL Error", MB_ICONEXCLAMATION);
  else
    MessageBox(NULL, "Неизвестная ошибка",
      "MIDIPL Error", MB_ICONEXCLAMATION);
}

