/*
 * Enhanced MetaFile driver BitBlt functions
 *
 * Copyright 2002 Huw D M Davies for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi.h"
#include "enhmetafiledrv.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);

BOOL EMFDRV_PatBlt( PHYSDEV dev, INT left, INT top,
                    INT width, INT height, DWORD rop )
{
    EMRBITBLT emr;
    BOOL ret;

    emr.emr.iType = EMR_BITBLT;
    emr.emr.nSize = sizeof(emr);
    emr.rclBounds.left = left;
    emr.rclBounds.top = top;
    emr.rclBounds.right = left + width - 1;
    emr.rclBounds.bottom = top + height - 1;
    emr.xDest = left;
    emr.yDest = top;
    emr.cxDest = width;
    emr.cyDest = height;
    emr.dwRop = rop;
    emr.xSrc = 0;
    emr.ySrc = 0;
    emr.xformSrc.eM11 = 1.0;
    emr.xformSrc.eM12 = 0.0;
    emr.xformSrc.eM21 = 0.0;
    emr.xformSrc.eM22 = 1.0;
    emr.xformSrc.eDx = 0.0;
    emr.xformSrc.eDy = 0.0;
    emr.crBkColorSrc = 0;
    emr.iUsageSrc = 0;
    emr.offBmiSrc = 0;
    emr.cbBmiSrc = 0;
    emr.offBitsSrc = 0;
    emr.cbBitsSrc = 0;

    ret = EMFDRV_WriteRecord( dev, &emr.emr );
    if(ret)
        EMFDRV_UpdateBBox( dev, &emr.rclBounds );
    return ret;
}

/* Utilitarian function used by EMFDRV_BitBlt and EMFDRV_StretchBlt */

static BOOL EMFDRV_BitBlockTransfer( 
    PHYSDEV devDst, INT xDst, INT yDst, INT widthDst, INT heightDst,  
    PHYSDEV devSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop,
    DWORD emrType)
{
    BOOL ret;
    PEMRBITBLT pEMR;
    UINT emrSize;
    UINT bmiSize;
    UINT bitsSize;
    UINT size;
    BITMAP  BM;
    WORD nBPP;
    LPBITMAPINFOHEADER lpBmiH;
    EMFDRV_PDEVICE* physDevSrc = (EMFDRV_PDEVICE*)devSrc;
    HBITMAP hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP);

    if (emrType == EMR_BITBLT)
        emrSize = sizeof(EMRBITBLT);
    else if (emrType == EMR_STRETCHBLT)
        emrSize = sizeof(EMRSTRETCHBLT);
    else
        return FALSE;

    if(sizeof(BITMAP) != GetObjectW(hBitmap, sizeof(BITMAP), &BM))
        return FALSE;

    nBPP = BM.bmPlanes * BM.bmBitsPixel;
    if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */

    bitsSize = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight;
    bmiSize = sizeof(BITMAPINFOHEADER) + 
        (nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD);
    size = emrSize + bmiSize + bitsSize;

    pEMR = HeapAlloc(GetProcessHeap(), 0, size);
    if (!pEMR) return FALSE;

    /* Initialize EMR */
    pEMR->emr.iType = emrType;
    pEMR->emr.nSize = size;
    pEMR->rclBounds.left = xDst;
    pEMR->rclBounds.top = yDst;
    pEMR->rclBounds.right = xDst + widthDst - 1;
    pEMR->rclBounds.bottom = yDst + heightDst - 1;
    pEMR->xDest = xDst;
    pEMR->yDest = yDst;
    pEMR->cxDest = widthDst;
    pEMR->cyDest = heightDst;
    pEMR->dwRop = rop;
    pEMR->xSrc = xSrc;
    pEMR->ySrc = ySrc;
    pEMR->xformSrc.eM11 = 1.0;  /** FIXME:           */
    pEMR->xformSrc.eM12 = 0.0;  /** Setting default  */
    pEMR->xformSrc.eM21 = 0.0;  /** value.           */
    pEMR->xformSrc.eM22 = 1.0;  /** Where should we  */
    pEMR->xformSrc.eDx = 0.0;   /** get that info    */
    pEMR->xformSrc.eDy = 0.0;   /** ????             */
    pEMR->crBkColorSrc = GetBkColor(physDevSrc->hdc);
    pEMR->iUsageSrc = DIB_RGB_COLORS;
    pEMR->offBmiSrc = emrSize;
    pEMR->cbBmiSrc = bmiSize;
    pEMR->offBitsSrc = emrSize + bmiSize;
    pEMR->cbBitsSrc = bitsSize;
    if (emrType == EMR_STRETCHBLT) 
    {
        PEMRSTRETCHBLT pEMRStretch = (PEMRSTRETCHBLT)pEMR;
        pEMRStretch->cxSrc = widthSrc;
        pEMRStretch->cySrc = heightSrc;
    }

    /* Initialize BITMAPINFO structure */
    lpBmiH = (LPBITMAPINFOHEADER)((BYTE*)pEMR + pEMR->offBmiSrc);

    lpBmiH->biSize = sizeof(BITMAPINFOHEADER); 
    lpBmiH->biWidth =  BM.bmWidth;
    lpBmiH->biHeight = BM.bmHeight;
    lpBmiH->biPlanes = BM.bmPlanes;
    lpBmiH->biBitCount = nBPP;
    /* Assume the bitmap isn't compressed and set the BI_RGB flag. */
    lpBmiH->biCompression = BI_RGB;
    lpBmiH->biSizeImage = bitsSize;
    lpBmiH->biYPelsPerMeter = /* 1 meter  = 39.37 inch */
        MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSX),3937,100);
    lpBmiH->biXPelsPerMeter = 
        MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSY),3937,100);
    lpBmiH->biClrUsed   = nBPP <= 8 ? 1 << nBPP : 0;
    /* Set biClrImportant to 0, indicating that all of the 
       device colors are important. */
    lpBmiH->biClrImportant = 0; 

    /* Initiliaze bitmap bits */
    if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBmiH->biHeight,
                  (BYTE*)pEMR + pEMR->offBitsSrc,
                  (LPBITMAPINFO)lpBmiH, DIB_RGB_COLORS))
    {
        ret = EMFDRV_WriteRecord(devDst, (EMR*)pEMR);
        if (ret) EMFDRV_UpdateBBox(devDst, &(pEMR->rclBounds));
    } 
    else
        ret = FALSE;

    HeapFree( GetProcessHeap(), 0, pEMR);
    return ret;
}

BOOL EMFDRV_BitBlt( 
    PHYSDEV devDst, INT xDst, INT yDst, INT width, INT height,
    PHYSDEV devSrc, INT xSrc, INT ySrc, DWORD rop)
{
    return EMFDRV_BitBlockTransfer( devDst, xDst, yDst, width, height,  
                                    devSrc, xSrc, ySrc, width, height, 
                                    rop, EMR_BITBLT );
}

BOOL EMFDRV_StretchBlt( 
    PHYSDEV devDst, INT xDst, INT yDst, INT widthDst, INT heightDst,  
    PHYSDEV devSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop )
{
    return EMFDRV_BitBlockTransfer( devDst, xDst, yDst, widthDst, heightDst,  
                                    devSrc, xSrc, ySrc, widthSrc, heightSrc, 
                                    rop, EMR_STRETCHBLT );
}

INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
                                      INT heightDst, INT xSrc, INT ySrc,
                                      INT widthSrc, INT heightSrc,
                                      const void *bits, const BITMAPINFO *info,
                                      UINT wUsage, DWORD dwRop )
{
    EMRSTRETCHDIBITS *emr;
    BOOL ret;
    UINT bmi_size=0, bits_size, emr_size;
    
    bits_size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
                                     info->bmiHeader.biHeight,
                                     info->bmiHeader.biBitCount);

    /* calculate the size of the colour table */
    bmi_size = DIB_BitmapInfoSize(info, wUsage);

    emr_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + bits_size;
    emr = HeapAlloc(GetProcessHeap(), 0, emr_size );
    if (!emr) return 0;

    /* write a bitmap info header (with colours) to the record */
    memcpy( &emr[1], info, bmi_size);

    /* write bitmap bits to the record */
    memcpy ( ( (BYTE *) (&emr[1]) ) + bmi_size, bits, bits_size);

    /* fill in the EMR header at the front of our piece of memory */
    emr->emr.iType = EMR_STRETCHDIBITS;
    emr->emr.nSize = emr_size;

    emr->xDest     = xDst;
    emr->yDest     = yDst;
    emr->cxDest    = widthDst;
    emr->cyDest    = heightDst;
    emr->dwRop     = dwRop;
    emr->xSrc      = xSrc; /* FIXME: only save the piece of the bitmap needed */
    emr->ySrc      = ySrc;

    emr->iUsageSrc    = wUsage;
    emr->offBmiSrc    = sizeof (EMRSTRETCHDIBITS);
    emr->cbBmiSrc     = bmi_size;
    emr->offBitsSrc   = emr->offBmiSrc + bmi_size; 
    emr->cbBitsSrc    = bits_size;

    emr->cxSrc = widthSrc;
    emr->cySrc = heightSrc;

    emr->rclBounds.left   = xDst;
    emr->rclBounds.top    = yDst;
    emr->rclBounds.right  = xDst + widthDst;
    emr->rclBounds.bottom = yDst + heightDst;

    /* save the record we just created */
    ret = EMFDRV_WriteRecord( dev, &emr->emr );
    if(ret)
        EMFDRV_UpdateBBox( dev, &emr->rclBounds );

    HeapFree(GetProcessHeap(), 0, emr);

    return ret ? heightSrc : GDI_ERROR;
}

INT EMFDRV_SetDIBitsToDevice( 
    PHYSDEV dev, INT xDst, INT yDst, DWORD width, DWORD height,
    INT xSrc, INT ySrc, UINT startscan, UINT lines,
    LPCVOID bits, const BITMAPINFO *info, UINT wUsage )
{
    EMRSETDIBITSTODEVICE* pEMR;
    DWORD size, bmiSize, bitsSize;

    bmiSize = DIB_BitmapInfoSize(info, wUsage);
    bitsSize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
                                     info->bmiHeader.biHeight,
                                     info->bmiHeader.biBitCount );
    size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + bitsSize;

    pEMR = HeapAlloc(GetProcessHeap(), 0, size);
    if (!pEMR) return 0;

    pEMR->emr.iType = EMR_SETDIBITSTODEVICE;
    pEMR->emr.nSize = size;
    pEMR->rclBounds.left = xDst;
    pEMR->rclBounds.top = yDst;
    pEMR->rclBounds.right = xDst + width - 1;
    pEMR->rclBounds.bottom = yDst + height - 1;
    pEMR->xDest = xDst;
    pEMR->yDest = yDst;
    pEMR->xSrc = xSrc;
    pEMR->ySrc = ySrc;
    pEMR->cxSrc = width;
    pEMR->cySrc = height;
    pEMR->offBmiSrc = sizeof(EMRSETDIBITSTODEVICE);
    pEMR->cbBmiSrc = bmiSize;
    pEMR->offBitsSrc = sizeof(EMRSETDIBITSTODEVICE) + bmiSize;
    pEMR->cbBitsSrc = bitsSize;
    pEMR->iUsageSrc = wUsage;
    pEMR->iStartScan = startscan;
    pEMR->cScans = lines;
    memcpy((BYTE*)pEMR + pEMR->offBmiSrc, info, bmiSize);
    memcpy((BYTE*)pEMR + pEMR->offBitsSrc, bits, bitsSize);

    if (EMFDRV_WriteRecord(dev, (EMR*)pEMR))
        EMFDRV_UpdateBBox(dev, &(pEMR->rclBounds));

    HeapFree( GetProcessHeap(), 0, pEMR);
    return lines;
}
