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

#include "mciwavio.hpp"

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

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

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

  // Готовим блок параметров
  mciOpen.lpstrDeviceType= (LPSTR)"waveaudio";
  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)
  {
    mciwioError(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)
    {
      mciwioError(dwrc);
      return 0;
    }

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

//-----------------------------------------------------
// mciwioPlay
// Проигрывание загруженного wav-файла
//-----------------------------------------------------
DWORD mciwioPlay(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;
}

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

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

  return dwrc;
}

//-----------------------------------------------------
// mciwioResume
// Проигрывание после временного останова
//-----------------------------------------------------
DWORD mciwioResume(UINT wDeviceID)
{
  MCI_GENERIC_PARMS mcigen;
  DWORD dwrc;

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

  return dwrc;
}

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

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

  return dwrc;
}

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

  char szFile[256];
  char szFileTitle[256];
  char szFilter[256] =
	 "Wave Files\0*.wav\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;
}

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

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

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

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

//-----------------------------------------------------
// mciwioRecord
// Запись wav-файла
//-----------------------------------------------------
WORD mciwioRecord(HWND hwnd, DWORD dwMSec)
{
  MCI_RECORD_PARMS mciRecordParms;
  MCI_OPEN_PARMS mciOpen;
  DWORD dwrc;
  DWORD dwFlags;
  WORD wInDeviceID;

  // Готовим блок параметров
  // для команды открытия устройства
  mciOpen.lpstrDeviceType  = (LPSTR)"waveaudio";
  mciOpen.lpstrElementName = (LPSTR)"";
  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)
  {
    mciwioError(dwrc);
    return 0;
  }
  else
  {
    // В случае успеха сохраняем идентификатор
    // устройства ввода в глобальной переменной
    wInDeviceID = mciOpen.wDeviceID;
  }

  // Готовим блок параметров для команды записи
  mciRecordParms.dwTo       = dwMSec;
  mciRecordParms.dwCallback = (DWORD)hwnd;

  // Запускаем запись
  dwrc=mciSendCommand(wInDeviceID,
     MCI_RECORD, MCI_NOTIFY | MCI_TO,
    (DWORD)(LPVOID)&mciRecordParms);
  if(dwrc)
  {
    mciwioError(dwrc);
    return 0;
  }
  return wInDeviceID;
}
