/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include "../SDL_sysvideo.h"
#define INCL_DOSERRORS
#define INCL_DOSPROCESS
#define INCL_DOSMODULEMGR
#define INCL_WIN
#define INCL_GPI
#define INCL_GPIBITMAPS /* GPI bit map functions */
#include <os2.h>
#include <gradd.h>
#if 0 /* not used */
#define INCL_GRE_DEVICE
#define INCL_GRE_DEVMISC
#include <pmddi.h>
#endif
#include "SDL_os2output.h"
#include "SDL_os2video.h"

typedef struct _VODATA {
  PVOID      pBuffer;
  HRGN       hrgnVisible;
  ULONG      ulBPP;
  ULONG      ulScanLineSize;
  ULONG      ulWidth;
  ULONG      ulHeight;
  ULONG      ulScreenHeight;
  ULONG      ulScreenBytesPerLine;
  RECTL      rectlWin;

  PRECTL     pRectl;
  ULONG      cRectl;
  PBLTRECT   pBltRect;
  ULONG      cBltRect;
} VODATA;

static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo);
static PVODATA voOpen();
static VOID voClose(PVODATA pVOData);
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
                               SDL_DisplayMode *pSDLDisplayMode,
                               HRGN hrgnShape, BOOL fVisible);
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
                             ULONG ulBPP, ULONG fccColorEncoding,
                             PULONG pulScanLineSize);
static VOID voVideoBufFree(PVODATA pVOData);
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
                     ULONG cSDLRects);

OS2VIDEOOUTPUT voVMan = {
  voQueryInfo,
  voOpen,
  voClose,
  voSetVisibleRegion,
  voVideoBufAlloc,
  voVideoBufFree,
  voUpdate
};


static HMODULE         hmodVMan = NULLHANDLE;
static FNVMIENTRY      *pfnVMIEntry = NULL;
static ULONG           ulVRAMAddress = 0;

VOID APIENTRY ExitVMan(VOID)
{
  if ( ( ulVRAMAddress != 0 ) && ( hmodVMan != NULLHANDLE ) )
  {
    pfnVMIEntry( 0, VMI_CMD_TERMPROC, NULL, NULL );
    DosFreeModule( hmodVMan );
  }

  DosExitList( EXLST_EXIT, (PFNEXITLIST)NULL );
}

static BOOL _vmanInit()
{
  ULONG                ulRC;
  CHAR                 acBuf[255];
  INITPROCOUT          stInitProcOut;

  if ( hmodVMan != NULLHANDLE )
    // Already was initialized.
    return TRUE;

  // Load vman.dll
  ulRC = DosLoadModule( &acBuf, sizeof(acBuf), "VMAN", &hmodVMan );
  if ( ulRC != NO_ERROR )
  {
    debug( "Could not load VMAN.DLL, rc = %u : %s", ulRC, &acBuf );
    hmodVMan = NULLHANDLE;
    return FALSE;
  }

  // Get VMIEntry.
  ulRC = DosQueryProcAddr( hmodVMan, 0L, "VMIEntry", (PFN *)&pfnVMIEntry );
  if ( ulRC != NO_ERROR )
  {
    debug( "Could not query address of pfnVMIEntry func. of VMAN.DLL, "
           "rc = %u", ulRC );
    DosFreeModule( hmodVMan );
    hmodVMan = NULLHANDLE;
    return FALSE;
  }

  // VMAN initialization.
  stInitProcOut.ulLength = sizeof(stInitProcOut);
  ulRC = pfnVMIEntry( 0, VMI_CMD_INITPROC, NULL, &stInitProcOut );
  if ( ulRC != RC_SUCCESS )
  {
    debug( "Could not initialize VMAN for this process" );
    pfnVMIEntry = NULL;
    DosFreeModule( hmodVMan );
    hmodVMan = NULLHANDLE;
    return FALSE;
  }

  // Store video memory virtual address.
  ulVRAMAddress = stInitProcOut.ulVRAMVirt;
  // We use exit list for VMI_CMD_TERMPROC.
  if ( DosExitList( EXLST_ADD | 0x00001000, (PFNEXITLIST)ExitVMan )
       != NO_ERROR )
    debug( "DosExitList() failed" );

  return TRUE;
}

static PRECTL _getRectlArray(PVODATA pVOData, ULONG cRects)
{
  PRECTL     pRectl;

  if ( pVOData->cRectl >= cRects )
    return pVOData->pRectl;

  pRectl = SDL_realloc( pVOData->pRectl, cRects * sizeof(RECTL) );
  if ( pRectl == NULL )
    return NULL;

  pVOData->pRectl = pRectl;
  pVOData->cRectl = cRects;
  return pRectl;
}

static PBLTRECT _getBltRectArray(PVODATA pVOData, ULONG cRects)
{
  PBLTRECT   pBltRect;

  if ( pVOData->cBltRect >= cRects )
    return pVOData->pBltRect;

  pBltRect = SDL_realloc( pVOData->pBltRect, cRects * sizeof(BLTRECT) );
  if ( pBltRect == NULL )
    return NULL;

  pVOData->pBltRect = pBltRect;
  pVOData->cBltRect = cRects;
  return pBltRect;
}


static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo)
{
  ULONG                ulRC;
  GDDMODEINFO          sCurModeInfo;

  if ( !_vmanInit() )
    return FALSE;

  // Query current (desktop) mode.
  ulRC = pfnVMIEntry( 0, VMI_CMD_QUERYCURRENTMODE, NULL, &sCurModeInfo );
  if ( ulRC != RC_SUCCESS )
  {
    debug( "Could not query desktop video mode." );
    return FALSE;
  }

  pInfo->ulBPP             = sCurModeInfo.ulBpp;
  pInfo->ulHorizResolution = sCurModeInfo.ulHorizResolution;
  pInfo->ulVertResolution  = sCurModeInfo.ulVertResolution;
  pInfo->ulScanLineSize    = sCurModeInfo.ulScanLineSize;
  pInfo->fccColorEncoding  = sCurModeInfo.fccColorEncoding;

  return TRUE;
}

static PVODATA voOpen()
{
  PVODATA              pVOData;

  if ( !_vmanInit() )
    return NULL;

  pVOData = SDL_calloc( 1, sizeof(VODATA) );
  if ( pVOData == NULL )
  {
    SDL_OutOfMemory();
    return NULL;
  }

  return pVOData;
}

static VOID voClose(PVODATA pVOData)
{
  if ( pVOData->pRectl != NULL )
    SDL_free( pVOData->pRectl );

  if ( pVOData->pBltRect != NULL )
    SDL_free( pVOData->pBltRect );

  voVideoBufFree( pVOData );
}

static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
                               SDL_DisplayMode *pSDLDisplayMode,
                               HRGN hrgnShape, BOOL fVisible)
{
  HPS        hps;
  BOOL       fSuccess = FALSE;

  hps = WinGetPS( hwnd );

  if ( pVOData->hrgnVisible != NULLHANDLE )
  {
    GpiDestroyRegion( hps, pVOData->hrgnVisible );
    pVOData->hrgnVisible = NULLHANDLE;
  }

  if ( fVisible )
  {
    // Query visible rectangles

    pVOData->hrgnVisible = GpiCreateRegion( hps, 0, NULL );
    if ( pVOData->hrgnVisible == NULLHANDLE )
    {
      SDL_SetError( "GpiCreateRegion() failed" );
    }
    else
    {
      if ( WinQueryVisibleRegion( hwnd, pVOData->hrgnVisible ) == RGN_ERROR )
      {
        GpiDestroyRegion( hps, pVOData->hrgnVisible );
        pVOData->hrgnVisible = NULLHANDLE;
      }
      else
      {
        if ( hrgnShape != NULLHANDLE )
          GpiCombineRegion( hps, pVOData->hrgnVisible, pVOData->hrgnVisible,
                            hrgnShape, CRGN_AND );
        fSuccess = TRUE;
      }
    }

    WinQueryWindowRect( hwnd, &pVOData->rectlWin );
    WinMapWindowPoints( hwnd, HWND_DESKTOP, (PPOINTL)&pVOData->rectlWin, 2 );

    if ( pSDLDisplayMode != NULL )
    {
      pVOData->ulScreenHeight = pSDLDisplayMode->h;
      pVOData->ulScreenBytesPerLine =
                     ((PMODEDATA)pSDLDisplayMode->driverdata)->ulScanLineBytes;
    }
  }

  WinReleasePS( hps );

  return fSuccess;
}

static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
                             ULONG ulBPP, ULONG fccColorEncoding,
                             PULONG pulScanLineSize)
{
  ULONG      ulRC;
  ULONG      ulScanLineSize = ulWidth * (ulBPP >> 3);

  // Destroy previous buffer.
  voVideoBufFree( pVOData );

  if ( ( ulWidth == 0 ) || ( ulHeight == 0 ) || ( ulBPP == 0 ) )
    return NULL;

  // Bytes per line.
  ulScanLineSize = ( ulScanLineSize + 3 ) & ~3;	/* 4-byte aligning */
  *pulScanLineSize = ulScanLineSize;

  ulRC = DosAllocMem( &pVOData->pBuffer,
                      (ulHeight * ulScanLineSize) + sizeof(ULONG),
                      PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE );
  if ( ulRC != NO_ERROR )
  {
    debug( "DosAllocMem(), rc = %u", ulRC );
    return NULL;
  }

  pVOData->ulBPP          = ulBPP;
  pVOData->ulScanLineSize = ulScanLineSize;
  pVOData->ulWidth        = ulWidth;
  pVOData->ulHeight       = ulHeight;

  return pVOData->pBuffer;
}

static VOID voVideoBufFree(PVODATA pVOData)
{
  ULONG      ulRC;

  if ( pVOData->pBuffer == NULL )
    return;

  ulRC = DosFreeMem( pVOData->pBuffer );
  if ( ulRC != NO_ERROR )
    debug( "DosFreeMem(), rc = %u", ulRC );
  else
    pVOData->pBuffer = NULL;
}

static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
                     ULONG cSDLRects)
{
  PRECTL               prectlDst, prectlScan;
  HPS                  hps;
  HRGN                 hrgnUpdate;
  RGNRECT              rgnCtl;
  SDL_Rect             stSDLRectDef;
  BMAPINFO             bmiSrc;
  BMAPINFO             bmiDst;
  PPOINTL              pptlSrcOrg;
  PBLTRECT             pbrDst;
  HWREQIN              sHWReqIn;
  BITBLTINFO           sBitbltInfo = { 0 };
  ULONG                ulIdx;
//  RECTL                rectlScreenUpdate;

  if ( pVOData->pBuffer == NULL )
    return FALSE;

  if ( pVOData->hrgnVisible == NULLHANDLE )
    return TRUE;

  bmiSrc.ulLength = sizeof(BMAPINFO);
  bmiSrc.ulType = BMAP_MEMORY;
  bmiSrc.ulWidth = pVOData->ulWidth;
  bmiSrc.ulHeight = pVOData->ulHeight;
  bmiSrc.ulBpp = pVOData->ulBPP;
  bmiSrc.ulBytesPerLine = pVOData->ulScanLineSize;
  bmiSrc.pBits = (PBYTE)pVOData->pBuffer;

  bmiDst.ulLength = sizeof(BMAPINFO);
  bmiDst.ulType = BMAP_VRAM;
  bmiDst.pBits = (PBYTE)ulVRAMAddress;
  bmiDst.ulWidth = bmiSrc.ulWidth;
  bmiDst.ulHeight = bmiSrc.ulHeight;
  bmiDst.ulBpp = bmiSrc.ulBpp;
  bmiDst.ulBytesPerLine = pVOData->ulScreenBytesPerLine;

  // List of update rectangles. This is the intersection of requested
  // rectangles and visible rectangles.

  if ( cSDLRects == 0 )
  {
    // Full update requested.
    stSDLRectDef.x = 0;
    stSDLRectDef.y = 0;
    stSDLRectDef.w = bmiSrc.ulWidth;
    stSDLRectDef.h = bmiSrc.ulHeight;
    pSDLRects = &stSDLRectDef;
    cSDLRects = 1;
  }

  // Make list of destionation rectangles (prectlDst) list from the source
  // list (prectl).
  prectlDst = _getRectlArray( pVOData, cSDLRects );
  if ( prectlDst == NULL )
  {
    debug( "Not enough memory" );
    return FALSE;
  }
  prectlScan = prectlDst;
  for( ulIdx = 0; ulIdx < cSDLRects; ulIdx++, pSDLRects++, prectlScan++ )
  {
    prectlScan->xLeft   = pSDLRects->x;
    prectlScan->yTop    = pVOData->ulHeight - pSDLRects->y;
    prectlScan->xRight  = prectlScan->xLeft + pSDLRects->w;
    prectlScan->yBottom = prectlScan->yTop - pSDLRects->h;
  }

  hps = WinGetPS( hwnd );
  if ( hps == NULLHANDLE )
    return FALSE;

  // Make destination region to update.
  hrgnUpdate = GpiCreateRegion( hps, cSDLRects, prectlDst );
  // "AND" on visible and destination regions, result is region to update.
  GpiCombineRegion( hps, hrgnUpdate, hrgnUpdate, pVOData->hrgnVisible,
                    CRGN_AND );

  // Get rectangles of the region to update.
  rgnCtl.ircStart     = 1;
  rgnCtl.crc          = 0;
  rgnCtl.ulDirection  = 1;
  rgnCtl.crcReturned  = 0;
  GpiQueryRegionRects( hps, hrgnUpdate, NULL, &rgnCtl, NULL );
  if ( rgnCtl.crcReturned == 0 )
  {
    GpiDestroyRegion( hps, hrgnUpdate );
    WinReleasePS( hps );
    return TRUE;
  }
  // We don't need prectlDst, use it again to store update regions.
  prectlDst = _getRectlArray( pVOData, rgnCtl.crcReturned );
  if ( prectlDst == NULL )
  {
    debug( "Not enough memory" );
    GpiDestroyRegion( hps, hrgnUpdate );
    WinReleasePS( hps );
    return FALSE;
  }
  rgnCtl.ircStart     = 1;
  rgnCtl.crc          = rgnCtl.crcReturned;
  rgnCtl.ulDirection  = 1;
  GpiQueryRegionRects( hps, hrgnUpdate, NULL, &rgnCtl, prectlDst );
  GpiDestroyRegion( hps, hrgnUpdate );
  WinReleasePS( hps );
  cSDLRects = rgnCtl.crcReturned;
  // Now cRect/prectlDst is a list of regions in window (update && visible).

  // Make lists for blitting from update regions.

  pbrDst = _getBltRectArray( pVOData, cSDLRects );
  if ( pbrDst == NULL )
  {
    debug( "Not enough memory" );
    return FALSE;
  }

  prectlScan = prectlDst;
  pptlSrcOrg = (PPOINTL)prectlDst; // Yes, this memory block will be used again.
  for( ulIdx = 0; ulIdx < cSDLRects; ulIdx++, prectlScan++, pptlSrcOrg++ )
  {
    pbrDst[ulIdx].ulXOrg = pVOData->rectlWin.xLeft + prectlScan->xLeft;
    pbrDst[ulIdx].ulYOrg = pVOData->ulScreenHeight -
                           ( pVOData->rectlWin.yBottom + prectlScan->yTop );
    pbrDst[ulIdx].ulXExt = prectlScan->xRight - prectlScan->xLeft;
    pbrDst[ulIdx].ulYExt = prectlScan->yTop - prectlScan->yBottom;
    pptlSrcOrg->x = prectlScan->xLeft;
    pptlSrcOrg->y = bmiSrc.ulHeight - prectlScan->yTop;
  }
  pptlSrcOrg = (PPOINTL)prectlDst;

  // Request HW
  sHWReqIn.ulLength = sizeof(HWREQIN);
  sHWReqIn.ulFlags = REQUEST_HW;
  sHWReqIn.cScrChangeRects = 1;
  sHWReqIn.arectlScreen = &pVOData->rectlWin;
  if ( pfnVMIEntry( 0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL ) != RC_SUCCESS )
  {
    debug( "pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed" );
    sHWReqIn.cScrChangeRects = 0; // for fail signal only.
  }
  else
  {
    RECTL rclSrcBounds;

    rclSrcBounds.xLeft = 0;
    rclSrcBounds.yBottom = 0;
    rclSrcBounds.xRight = bmiSrc.ulWidth;
    rclSrcBounds.yTop = bmiSrc.ulHeight;

    sBitbltInfo.ulLength = sizeof(BITBLTINFO);
    sBitbltInfo.ulBltFlags = BF_DEFAULT_STATE | BF_ROP_INCL_SRC | BF_PAT_HOLLOW;
    sBitbltInfo.cBlits = cSDLRects;
    sBitbltInfo.ulROP = ROP_SRCCOPY;
    sBitbltInfo.pSrcBmapInfo = &bmiSrc;
    sBitbltInfo.pDstBmapInfo = &bmiDst;
    sBitbltInfo.prclSrcBounds = &rclSrcBounds;
    sBitbltInfo.prclDstBounds = &pVOData->rectlWin;
    sBitbltInfo.aptlSrcOrg = pptlSrcOrg;
    sBitbltInfo.abrDst = pbrDst;

    // Screen update.
    if ( pfnVMIEntry( 0, VMI_CMD_BITBLT, &sBitbltInfo, NULL ) != RC_SUCCESS )
    {
      debug( "pfnVMIEntry(,VMI_CMD_BITBLT,,) failed" );
      sHWReqIn.cScrChangeRects = 0; // for fail signal only.
    }

    // Release HW.
    sHWReqIn.ulFlags = 0;
    if ( pfnVMIEntry( 0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL ) != RC_SUCCESS )
      debug( "pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed" );
  }

  return sHWReqIn.cScrChangeRects != 0;
}
