#define INCL_PM
#define INCL_VIO
#define INCL_DOSERRORS
#define INCL_DOSPROCESS

#include <OS2.h>
#include <Stdio.h>
#include <String.h>

#define let void

#define Run int main
#define Say printf

#define ESC_CLR_RESET      "\x1B" "[0m"
#define ESC_CLR_BOLD       "\x1B" "[1m"
#define ESC_CLR_DIM        "\x1B" "[2m"
#define ESC_CLR_ITALIC     "\x1B" "[3m"

#define ESC_CLR_BLACK      "\x1B" "[30m"
#define ESC_CLR_RED        "\x1B" "[31m"
#define ESC_CLR_GREEN      "\x1B" "[32m"
#define ESC_CLR_YELLOW     "\x1B" "[33m"
#define ESC_CLR_BLUE       "\x1B" "[34m"
#define ESC_CLR_PINK       "\x1B" "[35m"
#define ESC_CLR_CYAN       "\x1B" "[36m"
#define ESC_CLR_WHITE      "\x1B" "[37m"

HAB MixedPMVIO_Ascend ()
{
  PPIB Process_info = NULL;
  PTIB Thread_info = NULL;

  HAB Shell_handle = NULLHANDLE;

  DosGetInfoBlocks (&Thread_info, &Process_info);

  if (Process_info->pib_ultype == PROG_WINDOWABLEVIO)
  {
    Process_info->pib_ultype = PROG_PM; 

    Shell_handle = WinInitialize (0);

    if (Shell_handle) 
    {
      return Shell_handle;
    }
    else
    {
      DosExit (EXIT_PROCESS, ERROR_INVALID_FUNCTION);
    }
  }
  else
  {
    DosExit (EXIT_PROCESS, ERROR_BAD_ENVIRONMENT);
  }

  return 0;
}

let MixedPMVIO_Descend (HAB Shell_handle)
{
  if (Shell_handle)
  {
    PPIB Process_info = NULL;
    PTIB Thread_info = NULL;

    DosGetInfoBlocks (&Thread_info, &Process_info);

    if (Process_info->pib_ultype == PROG_PM)
    {
      WinTerminate (Shell_handle); Process_info->pib_ultype = PROG_WINDOWABLEVIO;
    }
    else
    {
      DosExit (EXIT_PROCESS, ERROR_BAD_ENVIRONMENT);
    }
  }
  else
  {
    DosExit (EXIT_PROCESS, ERROR_INVALID_HANDLE);
  }
}

let VIO_SetColor (PCHAR Color)
{
  Say (Color);
}

Run ()
{
  HAB Shell_handle = NULLHANDLE;
  HMQ Msg_queue = NULLHANDLE;

  VIO_SetColor (ESC_CLR_WHITE);
  Say ("\n"); Say (" Hello, World!" "\n");

  VIO_SetColor (ESC_CLR_CYAN);
  Say ("   Morphing into PM application..." "\n");

  Shell_handle = MixedPMVIO_Ascend ();

  Msg_queue = WinCreateMsgQueue (Shell_handle, 0);

  VIO_SetColor (ESC_CLR_GREEN);
  Say ("   Calling " "\"" "WinMessageBox()" "\"" "..." "\n");

  WinMessageBox (HWND_DESKTOP, NULLHANDLE, "Hello, World!", "", 0, 0);

  WinDestroyMsgQueue (Msg_queue);

  VIO_SetColor (ESC_CLR_CYAN);
  Say ("   Morphing into VIO application..." "\n");

  MixedPMVIO_Descend (Shell_handle);

  VIO_SetColor (ESC_CLR_WHITE);
  Say (" All done" "\n");

  VIO_SetColor (ESC_CLR_RESET);

  return 0;
}
