/*
 * Unit tests for DirectDraw overlay functions
 *
 * Copyright (C) 2008,2011 Stefan Dösinger 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
 */
#define COBJMACROS

#include "wine/test.h"
#include "ddraw.h"
#include "unknwn.h"

static HRESULT (WINAPI *pDirectDrawCreateEx)(LPGUID,LPVOID*,REFIID,LPUNKNOWN);

static IDirectDraw7 *ddraw = NULL;
static IDirectDrawSurface7 *primary = NULL;

static IDirectDrawSurface7 *create_overlay(DWORD width, DWORD height, DWORD format) {
    DDSURFACEDESC2 ddsd;
    HRESULT hr;
    IDirectDrawSurface7 *ret;

    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
    ddsd.dwWidth = width;
    ddsd.dwHeight = height;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
    U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
    U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
    U4(ddsd).ddpfPixelFormat.dwFourCC = format;
    hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &ret, NULL);
    if(FAILED(hr)) return NULL;
    else return ret;
}

static BOOL CreateDirectDraw(void)
{
    HRESULT hr;
    DDSURFACEDESC2 ddsd;
    IDirectDrawSurface7 *overlay = NULL;
    HMODULE hmod = GetModuleHandleA("ddraw.dll");

    pDirectDrawCreateEx = (void*)GetProcAddress(hmod, "DirectDrawCreateEx");
    if (!pDirectDrawCreateEx) {
        win_skip("DirectDrawCreateEx is not available\n");
        return FALSE;
    }

    hr = pDirectDrawCreateEx(NULL, (void**)&ddraw, &IID_IDirectDraw7, NULL);
    ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
    if (!ddraw) {
        trace("DirectDrawCreateEx() failed with an error %x\n", hr);
        return FALSE;
    }

    hr = IDirectDraw_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
    ok(hr == DD_OK, "SetCooperativeLevel returned: %x\n", hr );

    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
    if (FAILED(hr)) {
        IDirectDraw7_Release(ddraw);
        trace("IDirectDraw7_CreateSurface() failed with an error %x\n", hr);
        return FALSE;
    }

    overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y'));
    if (!overlay) {
        IDirectDrawSurface7_Release(primary);
        IDirectDraw7_Release(ddraw);
        skip("Failed to create an overlay - assuming not supported\n");
        return FALSE;
    }
    IDirectDraw7_Release(overlay);

    return TRUE;
}

static void rectangle_settings(void) {
    IDirectDrawSurface7 *overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y'));
    HRESULT hr, hr2;
    RECT rect = {0, 0, 64, 64};
    LONG posx, posy;

    /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is used. This is not true
     * in Windows Vista and earlier, but changed in Win7 */
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_SHOW, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, DDOVER_HIDE, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, DDOVER_SHOW, NULL);
    ok(hr == DD_OK || hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);

    /* Show that the overlay position is the (top, left) coordinate of the dest rectangle */
    rect.top += 16;
    rect.left += 32;
    rect.bottom += 16;
    rect.right += 32;
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_SHOW, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
    posx = -1; posy = -1;
    hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
    ok(hr == DD_OK, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
    ok(posx == rect.left && posy == rect.top, "Overlay position is (%d, %d), expected (%d, %d)\n",
       posx, posy, rect.left, rect.top);

    /* Passing a NULL dest rect sets the position to 0/0 . Visually it can be seen that the overlay overlays the whole primary(==screen)*/
    hr2 = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, 0, NULL);
    ok(hr2 == DD_OK || hr2 == DDERR_INVALIDPARAMS
            || hr2 == DDERR_OUTOFCAPS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr2);
    hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
    ok(hr == DD_OK, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
    if (SUCCEEDED(hr2))
    {
        ok(posx == 0 && posy == 0, "Overlay position is (%d, %d), expected (%d, %d)\n",
                posx, posy, 0, 0);
    }
    else
    {
        /* Otherwise the position remains untouched */
        ok(posx == 32 && posy == 16, "Overlay position is (%d, %d), expected (%d, %d)\n",
                posx, posy, 32, 16);
    }
    /* The position cannot be retrieved when the overlay is not shown */
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_HIDE, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
    posx = -1; posy = -1;
    hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
    ok(hr == DDERR_OVERLAYNOTVISIBLE, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
    ok(posx == 0 && posy == 0, "Overlay position is (%d, %d), expected (%d, %d)\n",
       posx, posy, 0, 0);

    IDirectDrawSurface7_Release(overlay);
}

static void offscreen_test(void) {
    IDirectDrawSurface7 *overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y')), *offscreen = NULL;
    HRESULT hr;
    DDSURFACEDESC2 ddsd;

    /* Try to overlay a NULL surface */
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, NULL, NULL, DDOVER_SHOW, NULL);
    ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, NULL, NULL, DDOVER_HIDE, NULL);
    ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);

    /* Try to overlay an offscreen surface */
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
    ddsd.dwWidth = 64;
    ddsd.dwHeight = 64;
    U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
    U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
    U4(ddsd).ddpfPixelFormat.dwFourCC = 0;
    U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
    U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
    U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07e0;
    U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &offscreen, NULL);
    ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed with hr=0x%08x\n", hr);

    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, offscreen, NULL, DDOVER_SHOW, NULL);
    ok(hr == DD_OK || broken(hr == E_NOTIMPL),
       "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);

    /* Try to overlay the primary with a non-overlay surface */
    hr = IDirectDrawSurface7_UpdateOverlay(offscreen, NULL, primary, NULL, DDOVER_SHOW, NULL);
    ok(hr == DDERR_NOTAOVERLAYSURFACE, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);

    IDirectDrawSurface7_Release(offscreen);
    IDirectDrawSurface7_Release(overlay);
}

static void yv12_test(void)
{
    HRESULT hr;
    DDSURFACEDESC2 desc;
    IDirectDrawSurface7 *surface, *dst;
    char *base;
    RECT rect = {13, 17, 14, 18};
    unsigned int offset, y;

    surface = create_overlay(256, 256, MAKEFOURCC('Y','V','1','2'));
    if(!surface) {
        skip("YV12 surfaces not available\n");
        return;
    }

    memset(&desc, 0, sizeof(desc));
    desc.dwSize = sizeof(desc);
    hr = IDirectDrawSurface7_Lock(surface, NULL, &desc, 0, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned 0x%08x, expected DD_OK\n", hr);

    ok(desc.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH),
       "Unexpected desc.dwFlags 0x%08x\n", desc.dwFlags);
    ok(desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM) ||
       desc.ddsCaps.dwCaps == (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_HWCODEC),
       "Unexpected desc.ddsCaps.dwCaps 0x%08x\n", desc.ddsCaps.dwCaps);
    ok(desc.dwWidth == 256 && desc.dwHeight == 256, "Expected size 256x256, got %ux%u\n",
       desc.dwWidth, desc.dwHeight);
    /* The overlay pitch seems to have 256 byte alignment */
    ok((U1(desc).lPitch & 0xff) == 0, "Expected 256 byte aligned pitch, got %u\n", U1(desc).lPitch);

    /* Fill the surface with some data for the blit test */
    base = desc.lpSurface;
    /* Luminance */
    for (y = 0; y < desc.dwHeight; y++)
    {
        memset(base + U1(desc).lPitch * y, 0x10, desc.dwWidth);
    }
    /* V */
    for (; y < desc.dwHeight + desc.dwHeight / 4; y++)
    {
        memset(base + U1(desc).lPitch * y, 0x20, desc.dwWidth);
    }
    /* U */
    for (; y < desc.dwHeight + desc.dwHeight / 2; y++)
    {
        memset(base + U1(desc).lPitch * y, 0x30, desc.dwWidth);
    }

    hr = IDirectDrawSurface7_Unlock(surface, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_Unlock returned 0x%08x, expected DD_OK\n", hr);

    /* YV12 uses 2x2 blocks with 6 bytes per block(4*Y, 1*U, 1*V). Unlike other block-based formats like DXT
     * the entire Y channel is stored in one big chunk of memory, followed by the chroma channels. So
     * partial locks do not really make sense. Show that they are allowed nevertheless and the offset points
     * into the luminance data */
    hr = IDirectDrawSurface7_Lock(surface, &rect, &desc, 0, NULL);
    ok(hr == DD_OK, "Partial lock of a YV12 surface returned 0x%08x, expected DD_OK\n", hr);
    offset = ((const char *) desc.lpSurface - base);
    ok(offset == rect.top * U1(desc).lPitch + rect.left, "Expected %u byte offset from partial lock, got %u\n",
            rect.top * U1(desc).lPitch + rect.left, offset);
    hr = IDirectDrawSurface7_Unlock(surface, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_Unlock returned 0x%08x, expected DD_OK\n", hr);

    dst = create_overlay(256, 256, MAKEFOURCC('Y','V','1','2'));
    if (!dst)
    {
        /* Windows XP with a Radeon X1600 GPU refuses to create a second overlay surface,
         * DDERR_NOOVERLAYHW, making the blit tests moot */
        skip("Could not create a second YV12 surface, skipping blit test\n");
        goto cleanup;
    }

    hr = IDirectDrawSurface7_Blt(dst, NULL, surface, NULL, 0, NULL);
    /* VMware rejects YV12 blits. This behavior has not been seen on real hardware yet, so mark it broken */
    ok(hr == DD_OK || broken(hr == E_NOTIMPL),
            "IDirectDrawSurface7_Blt returned 0x%08x, expected DD_OK\n", hr);

    if (SUCCEEDED(hr))
    {
        memset(&desc, 0, sizeof(desc));
        desc.dwSize = sizeof(desc);
        hr = IDirectDrawSurface7_Lock(dst, NULL, &desc, 0, NULL);
        ok(hr == DD_OK, "IDirectDrawSurface7_Lock returned 0x%08x, expected DD_OK\n", hr);

        base = desc.lpSurface;
        ok(base[0] == 0x10, "Y data is 0x%02x, expected 0x10\n", base[0]);
        base += desc.dwHeight * U1(desc).lPitch;
        todo_wine ok(base[0] == 0x20, "V data is 0x%02x, expected 0x20\n", base[0]);
        base += desc.dwHeight / 4 * U1(desc).lPitch;
        todo_wine ok(base[0] == 0x30, "U data is 0x%02x, expected 0x30\n", base[0]);

        hr = IDirectDrawSurface7_Unlock(dst, NULL);
        ok(hr == DD_OK, "IDirectDrawSurface7_Unlock returned 0x%08x, expected DD_OK\n", hr);
    }

    IDirectDrawSurface7_Release(dst);
cleanup:
    IDirectDrawSurface7_Release(surface);
}

START_TEST(overlay)
{
    if(CreateDirectDraw() == FALSE) {
        skip("Failed to initialize ddraw\n");
        return;
    }

    rectangle_settings();
    offscreen_test();
    yv12_test();

    if(primary) IDirectDrawSurface7_Release(primary);
    if(ddraw) IDirectDraw7_Release(ddraw);
}
