#include <windows.h>
#include <math.h>
#include <stdio.h>

void printtms(UINT8 MusicType, UINT32 SongPos, UINT32 SongLen)
{
  UINT LgLen;
  char StrBuff[20];
  UINT i;

  if ((SongLen > 0) && (SongPos >= 0) && (SongPos <= SongLen))
  {
    if (SongLen < 600000)
      printf("%i:%02i / %i:%02i", (int) floor(SongPos / 60000), (int) floor(SongPos / 1000) % 60, (int) floor(SongLen / 60000), (int) floor(SongLen / 1000) % 60);
    else if (SongLen < 3600000)
      printf("%02i:%02i / %02i:%02i", (int) floor(SongPos / 60000), (int) floor(SongPos / 1000) % 60, (int) floor(SongLen / 60000), (int) floor(SongLen / 1000) % 60);
    else if ((SongLen < 3600000) && (SongPos < 3600000))
    {
      LgLen = floor(log10(SongLen / 3600000)) + 1;
      sprintf(StrBuff, "%%%ii:%%02i:%%02i / %%%ii:%%02i:%%02i", LgLen, LgLen);
      printf(StrBuff, (int) floor(SongPos / 3600000), ((int) floor(SongPos / 60000) % 60), (int) floor(SongPos / 1000), (int) floor(SongLen / 3600000), ((int) floor(SongLen / 60000) % 60), (int) floor(SongLen / 1000));
    }
  }
  else
  {
    if (SongLen < 600000)
      printf("?:??");
    else if (SongLen < 3600000)
      printf("??:??");
    else
    {
      LgLen = floor(log(SongLen / 3600000)) + 1;
      for (i=0; i<LgLen; i++)
        printf("?");
      printf(":??:??");
    }
  }
}

int main()
{
    HANDLE hWndCalaym;
    HANDLE hMapFile;
    LPVOID lpMapAddress;
    UINT RetCode;
    UINT TxtCharLen;
    UINT32 *SongPos;
    UINT32 *SongLen;
    UINT8 *MusicType;
    UINT8 *Delay;

    hWndCalaym = FindWindow("CalaymInterMsgClass101", "Calaym");
    if (hWndCalaym)
    {
      hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x204, "calaym_1234");
      if (hMapFile)
      {
        // It is not required to map the file-mapping object before passing
        RetCode = SendMessageW(hWndCalaym, WM_COMMAND, 800, 1234);
        lpMapAddress = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
        if (lpMapAddress)
        {
          printf("\nResult: 0x%x\n", RetCode);
          if (RetCode)
          {
            //wprintf(L"Current playing song: ");
            printf("  Volume: %i/7\n", ((RetCode & 0x70000000) >> 28));
            printf("  Repeat mode: ");
            switch ((RetCode & 0x0c000000) >> 26)
            {
              case 0: printf("single"); break;
              case 1: printf("all"); break;
              case 2: printf("random"); break;
            }
            printf("\n");
            printf("  Play state: ");
            switch ((RetCode & 0x03000000) >> 24)
            {
              case 0: printf("stopped"); break;
              case 1: printf("playing"); break;
              case 2: printf("paused"); break;
            }
            printf("\n");
            printf("  Operation state: ");
            switch ((RetCode & 0x00ff0000) >> 16)
            {
              case  0: printf("stopped"); break;
              case  1: printf("playing"); break;
              case  2: printf("paused"); break;
              case  3: printf("starting"); break;
              case  4: printf("applying soundcard"); break;
              case  5: printf("quitting"); break;
              case  6: printf("deleting files"); break;
              case  7: printf("reading files"); break;
              case  8: printf("crossfading"); break;
              case  9: printf("too many songs"); break;
              case 10: printf("loading song"); break;
              case 11: printf("loading internet stream"); break;
              case 12: printf("waiting for device removal"); break;
            }
            printf("\n");
            TxtCharLen = (RetCode & 0x0000ffff);
            printf("  Number of chars for song: %i\n", TxtCharLen);
            if (TxtCharLen)
            {
              printf("Song: ");
              // MessageBoxW(NULL, lpMapAddress, L"Current playing song", MB_OK | MB_ICONINFORMATION);
              wprintf(lpMapAddress);
              printf("\n");
              MusicType = lpMapAddress + ((TxtCharLen + 1) << 1) + 0;
              printf("Music type: ");
              switch (*MusicType)
              {
                case 0: printf("none"); break;
                case 1: printf("sequenced"); break;
                case 2: printf("streamed"); break;
                case 3: printf("cd audio"); break;
                case 4: printf("internet stream"); break;
              }
              printf("\n");
              Delay = lpMapAddress + ((TxtCharLen + 1) << 1) + 1;
              printf("Delay (e.g. for Lyric display; ms): %i\n", (*Delay << 4));

              SongPos = lpMapAddress + ((TxtCharLen + 1) << 1) + 2;
              SongLen = lpMapAddress + ((TxtCharLen + 1) << 1) + 6;
              printf("Position/Length: %i / %i\n", *SongPos, *SongLen);
              if (*MusicType == 4)
                printf("Buffer: %i%%\n", *SongPos);
              else
              {
                printf("Position/Length: ");
                printtms(*MusicType, *SongPos, *SongLen);
                printf("\n");
              }

            }
          }
          else
            printf("Not playing");
          UnmapViewOfFile(lpMapAddress);
        }
        CloseHandle(hMapFile);
      }
    }
    return 0;
}
