/* IDirectDrawSurface3 -> IDirectDrawSurface7 thunks
 * Copyright 2000 TransGaming Technologies Inc.
 *
 * 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 "config.h"
#include "wine/port.h"
#include "wine/debug.h"
#include <stdarg.h>
#include <assert.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "ddraw.h"
#include "winerror.h"

#include "ddraw_private.h"
#include "ddcomimpl.h"

#define CONVERT(pdds) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,	\
					 IDirectDrawSurface3,		\
					 IDirectDrawSurface7,		\
					 (pdds))

#define CONVERT_REV(pdds) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl,	\
					     IDirectDrawSurface7,	\
					     IDirectDrawSurface3,	\
					     (pdds))

WINE_DEFAULT_DEBUG_CHANNEL(ddraw_thunk);
WINE_DECLARE_DEBUG_CHANNEL(ddraw);

static HRESULT WINAPI
IDirectDrawSurface3Impl_QueryInterface(LPDIRECTDRAWSURFACE3 This, REFIID iid,
				       LPVOID *ppObj)
{
    return IDirectDrawSurface7_QueryInterface(CONVERT(This), iid, ppObj);
}

static ULONG WINAPI
IDirectDrawSurface3Impl_AddRef(LPDIRECTDRAWSURFACE3 This)
{
    return IDirectDrawSurface7_AddRef(CONVERT(This));
}

static ULONG WINAPI
IDirectDrawSurface3Impl_Release(LPDIRECTDRAWSURFACE3 iface)
{
    ICOM_THIS_FROM( IDirectDrawSurfaceImpl, IDirectDrawSurface3, iface);
    TRACE("(%p)\n", This);
    return IDirectDrawSurface7_Release(CONVERT(iface));
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_AddAttachedSurface(LPDIRECTDRAWSURFACE3 iface,
					   LPDIRECTDRAWSURFACE3 pAttach)
{
    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface3, iface);
    IDirectDrawSurfaceImpl *Surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, pAttach);
    TRACE("(%p)->(%p)\n", This, Surf);

    /* Tests suggest that
     * -> offscreen plain surfaces can be attached to other offscreen plain surfaces
     * -> offscreen plain surfaces can be attached to primaries
     * -> primaries can be attached to offscreen plain surfaces
     * -> z buffers can be attached to primaries
     *
     */
    if(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN) &&
       Surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN))
    {
        /* Sizes have to match */
        if(Surf->surface_desc.dwWidth != This->surface_desc.dwWidth ||
        Surf->surface_desc.dwHeight != This->surface_desc.dwHeight)
        {
            WARN("Surface sizes do not match\n");
            return DDERR_CANNOTATTACHSURFACE;
        }
        /* OK */
    }
    else if(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE) &&
            Surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER))
    {
        /* OK */
    }
    else
    {
        WARN("Invalid attachment combination\n");
        return DDERR_CANNOTATTACHSURFACE;
    }

    return IDirectDrawSurfaceImpl_AddAttachedSurface(This,
                                                     Surf);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE3 This,
					    LPRECT pRect)
{
    return IDirectDrawSurface7_AddOverlayDirtyRect(CONVERT(This), pRect);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_Blt(LPDIRECTDRAWSURFACE3 This, LPRECT prcDst,
			    LPDIRECTDRAWSURFACE3 pSrcSurf, LPRECT prcSrc,
			    DWORD dwFlags, LPDDBLTFX pFX)
{
    return IDirectDrawSurface7_Blt(CONVERT(This), prcDst, CONVERT(pSrcSurf),
				   prcSrc, dwFlags, pFX);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_BltBatch(LPDIRECTDRAWSURFACE3 This,
				 LPDDBLTBATCH pBatch, DWORD dwCount,
				 DWORD dwFlags)
{
    return IDirectDrawSurface7_BltBatch(CONVERT(This), pBatch, dwCount,
					dwFlags);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_BltFast(LPDIRECTDRAWSURFACE3 This, DWORD x, DWORD y,
				LPDIRECTDRAWSURFACE3 pSrcSurf, LPRECT prcSrc,
				DWORD dwTrans)
{
    return IDirectDrawSurface7_BltFast(CONVERT(This), x, y, CONVERT(pSrcSurf),
				       prcSrc, dwTrans);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_DeleteAttachedSurface(LPDIRECTDRAWSURFACE3 This,
					      DWORD dwFlags,
					      LPDIRECTDRAWSURFACE3 pAttached)
{
    return IDirectDrawSurface7_DeleteAttachedSurface(CONVERT(This), dwFlags,
						     CONVERT(pAttached));
}

struct callback_info
{
    LPDDENUMSURFACESCALLBACK callback;
    LPVOID context;
};

static HRESULT CALLBACK
EnumCallback(LPDIRECTDRAWSURFACE7 iface, LPDDSURFACEDESC2 pDDSD,
	     LPVOID context)
{
    const struct callback_info* info = context;

#if 0
    /* This is an outgoing conversion so we have to do it. */
    DDSURFACEDESC ddsd;
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    DDRAW_Convert_DDSURFACEDESC_2_To_1(pDDSD, &ddsd);
#endif

    /* the LPDDSURFACEDESC2 -> LPDDSURFACEDESC coercion is safe, since
     * the data format is compatible with older enum procs */
    return info->callback((LPDIRECTDRAWSURFACE)CONVERT_REV(iface), (LPDDSURFACEDESC)pDDSD,
			  info->context);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 This,
					     LPVOID context,
					     LPDDENUMSURFACESCALLBACK callback)
{
    struct callback_info info;

    info.callback = callback;
    info.context  = context;

    return IDirectDrawSurface7_EnumAttachedSurfaces(CONVERT(This), &info,
						    EnumCallback);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_EnumOverlayZOrders(LPDIRECTDRAWSURFACE3 This,
					   DWORD dwFlags, LPVOID context,
					   LPDDENUMSURFACESCALLBACK callback)
{
    struct callback_info info;

    info.callback = callback;
    info.context  = context;

    return IDirectDrawSurface7_EnumOverlayZOrders(CONVERT(This), dwFlags,
						  &info, EnumCallback);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_Flip(LPDIRECTDRAWSURFACE3 This,
			     LPDIRECTDRAWSURFACE3 pOverride, DWORD dwFlags)
{
    return IDirectDrawSurface7_Flip(CONVERT(This), CONVERT(pOverride),
				    dwFlags);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetAttachedSurface(LPDIRECTDRAWSURFACE3 This,
					   LPDDSCAPS pCaps,
					   LPDIRECTDRAWSURFACE3* ppAttached)
{
    DDSCAPS2 caps;
    LPDIRECTDRAWSURFACE7 pAttached7;
    HRESULT hr;

    caps.dwCaps  = pCaps->dwCaps;
    caps.dwCaps2 = 0;
    caps.dwCaps3 = 0;
    caps.dwCaps4 = 0;

    hr = IDirectDrawSurface7_GetAttachedSurface(CONVERT(This), &caps,
						&pAttached7);
    if (FAILED(hr)) return hr;

    *ppAttached = CONVERT_REV(pAttached7);
    return hr;
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetBltStatus(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags)
{
    return IDirectDrawSurface7_GetBltStatus(CONVERT(This), dwFlags);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetCaps(LPDIRECTDRAWSURFACE3 This, LPDDSCAPS pCaps)
{
    DDSCAPS2 caps;
    HRESULT hr;

    hr = IDirectDrawSurface7_GetCaps(CONVERT(This), &caps);
    if (FAILED(hr)) return hr;

    pCaps->dwCaps = caps.dwCaps;
    return hr;
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetClipper(LPDIRECTDRAWSURFACE3 This,
				   LPDIRECTDRAWCLIPPER* ppClipper)
{
    return IDirectDrawSurface7_GetClipper(CONVERT(This), ppClipper);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetColorKey(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags,
				    LPDDCOLORKEY pCKey)
{
    return IDirectDrawSurface7_GetColorKey(CONVERT(This), dwFlags, pCKey);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetDC(LPDIRECTDRAWSURFACE3 This, HDC* phDC)
{
    return IDirectDrawSurface7_GetDC(CONVERT(This), phDC);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetFlipStatus(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags)
{
    return IDirectDrawSurface7_GetFlipStatus(CONVERT(This), dwFlags);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetOverlayPosition(LPDIRECTDRAWSURFACE3 This, LPLONG pX,
				       LPLONG pY)
{
    return IDirectDrawSurface7_GetOverlayPosition(CONVERT(This), pX, pY);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetPalette(LPDIRECTDRAWSURFACE3 This,
				   LPDIRECTDRAWPALETTE* ppPalette)
{
    return IDirectDrawSurface7_GetPalette(CONVERT(This), ppPalette);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetPixelFormat(LPDIRECTDRAWSURFACE3 This,
				       LPDDPIXELFORMAT pPixelFormat)
{
    return IDirectDrawSurface7_GetPixelFormat(CONVERT(This), pPixelFormat);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetSurfaceDesc(LPDIRECTDRAWSURFACE3 iface,
				       LPDDSURFACEDESC pDDSD)
{
    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface3, iface);

    TRACE_(ddraw)("(%p)->(%p)\n",This,pDDSD);

    if(!pDDSD)
        return DDERR_INVALIDPARAMS;

    if (pDDSD->dwSize != sizeof(DDSURFACEDESC))
    {
        WARN("Incorrect struct size %d, returning DDERR_INVALIDPARAMS\n",pDDSD->dwSize);
        return DDERR_INVALIDPARAMS;
    }

    EnterCriticalSection(&ddraw_cs);
    DD_STRUCT_COPY_BYSIZE(pDDSD,(DDSURFACEDESC *) &This->surface_desc);
    TRACE("Returning surface desc:\n");
    if (TRACE_ON(ddraw))
    {
        /* DDRAW_dump_surface_desc handles the smaller size */
        DDRAW_dump_surface_desc((DDSURFACEDESC2 *) pDDSD);
    }

    LeaveCriticalSection(&ddraw_cs);
    return DD_OK;
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_Initialize(LPDIRECTDRAWSURFACE3 This, LPDIRECTDRAW pDD,
				   LPDDSURFACEDESC pDDSD)
{
    return IDirectDrawSurface7_Initialize(CONVERT(This), pDD,
					  (LPDDSURFACEDESC2)pDDSD);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_IsLost(LPDIRECTDRAWSURFACE3 This)
{
    return IDirectDrawSurface7_IsLost(CONVERT(This));
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_Lock(LPDIRECTDRAWSURFACE3 This, LPRECT pRect,
			     LPDDSURFACEDESC pDDSD, DWORD dwFlags, HANDLE h)
{
    return IDirectDrawSurface7_Lock(CONVERT(This), pRect,
				    (LPDDSURFACEDESC2)pDDSD, dwFlags, h);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_ReleaseDC(LPDIRECTDRAWSURFACE3 This, HDC hDC)
{
    return IDirectDrawSurface7_ReleaseDC(CONVERT(This), hDC);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_Restore(LPDIRECTDRAWSURFACE3 This)
{
    return IDirectDrawSurface7_Restore(CONVERT(This));
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_SetClipper(LPDIRECTDRAWSURFACE3 This,
				   LPDIRECTDRAWCLIPPER pClipper)
{
    return IDirectDrawSurface7_SetClipper(CONVERT(This), pClipper);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_SetColorKey(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags,
				    LPDDCOLORKEY pCKey)
{
    return IDirectDrawSurface7_SetColorKey(CONVERT(This), dwFlags, pCKey);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_SetOverlayPosition(LPDIRECTDRAWSURFACE3 This, LONG x,
				       LONG y)
{
    return IDirectDrawSurface7_SetOverlayPosition(CONVERT(This), x, y);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_SetPalette(LPDIRECTDRAWSURFACE3 This,
				   LPDIRECTDRAWPALETTE pPalette)
{
    return IDirectDrawSurface7_SetPalette(CONVERT(This), pPalette);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_Unlock(LPDIRECTDRAWSURFACE3 This, LPVOID data)
{
    /* data might not be the LPRECT of later versions, so drop it. */
    return IDirectDrawSurface7_Unlock(CONVERT(This), NULL);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_UpdateOverlay(LPDIRECTDRAWSURFACE3 This, LPRECT prcSrc,
				      LPDIRECTDRAWSURFACE3 pDstSurf,
				      LPRECT prcDst, DWORD dwFlags,
				      LPDDOVERLAYFX pFX)
{
    return IDirectDrawSurface7_UpdateOverlay(CONVERT(This), prcSrc,
					     CONVERT(pDstSurf), prcDst,
					     dwFlags, pFX);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE3 This,
					     DWORD dwFlags)
{
    return IDirectDrawSurface7_UpdateOverlayDisplay(CONVERT(This), dwFlags);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE3 This,
					    DWORD dwFlags,
					    LPDIRECTDRAWSURFACE3 pSurfReference)
{
    return IDirectDrawSurface7_UpdateOverlayZOrder(CONVERT(This), dwFlags,
						   CONVERT(pSurfReference));
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_GetDDInterface(LPDIRECTDRAWSURFACE3 This, LPVOID* ppDD)
{
    return IDirectDrawSurface7_GetDDInterface(CONVERT(This), ppDD);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_PageLock(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags)
{
    return IDirectDrawSurface7_PageLock(CONVERT(This), dwFlags);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_PageUnlock(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags)
{
    return IDirectDrawSurface7_PageUnlock(CONVERT(This), dwFlags);
}

static HRESULT WINAPI
IDirectDrawSurface3Impl_SetSurfaceDesc(LPDIRECTDRAWSURFACE3 This,
				       LPDDSURFACEDESC pDDSD, DWORD dwFlags)
{
    return IDirectDrawSurface7_SetSurfaceDesc(CONVERT(This),
					      (LPDDSURFACEDESC2)pDDSD,
					      dwFlags);
}

const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl =
{
    IDirectDrawSurface3Impl_QueryInterface,
    IDirectDrawSurface3Impl_AddRef,
    IDirectDrawSurface3Impl_Release,
    IDirectDrawSurface3Impl_AddAttachedSurface,
    IDirectDrawSurface3Impl_AddOverlayDirtyRect,
    IDirectDrawSurface3Impl_Blt,
    IDirectDrawSurface3Impl_BltBatch,
    IDirectDrawSurface3Impl_BltFast,
    IDirectDrawSurface3Impl_DeleteAttachedSurface,
    IDirectDrawSurface3Impl_EnumAttachedSurfaces,
    IDirectDrawSurface3Impl_EnumOverlayZOrders,
    IDirectDrawSurface3Impl_Flip,
    IDirectDrawSurface3Impl_GetAttachedSurface,
    IDirectDrawSurface3Impl_GetBltStatus,
    IDirectDrawSurface3Impl_GetCaps,
    IDirectDrawSurface3Impl_GetClipper,
    IDirectDrawSurface3Impl_GetColorKey,
    IDirectDrawSurface3Impl_GetDC,
    IDirectDrawSurface3Impl_GetFlipStatus,
    IDirectDrawSurface3Impl_GetOverlayPosition,
    IDirectDrawSurface3Impl_GetPalette,
    IDirectDrawSurface3Impl_GetPixelFormat,
    IDirectDrawSurface3Impl_GetSurfaceDesc,
    IDirectDrawSurface3Impl_Initialize,
    IDirectDrawSurface3Impl_IsLost,
    IDirectDrawSurface3Impl_Lock,
    IDirectDrawSurface3Impl_ReleaseDC,
    IDirectDrawSurface3Impl_Restore,
    IDirectDrawSurface3Impl_SetClipper,
    IDirectDrawSurface3Impl_SetColorKey,
    IDirectDrawSurface3Impl_SetOverlayPosition,
    IDirectDrawSurface3Impl_SetPalette,
    IDirectDrawSurface3Impl_Unlock,
    IDirectDrawSurface3Impl_UpdateOverlay,
    IDirectDrawSurface3Impl_UpdateOverlayDisplay,
    IDirectDrawSurface3Impl_UpdateOverlayZOrder,
    IDirectDrawSurface3Impl_GetDDInterface,
    IDirectDrawSurface3Impl_PageLock,
    IDirectDrawSurface3Impl_PageUnlock,
    IDirectDrawSurface3Impl_SetSurfaceDesc
};
