/*
 * Unit test suite for palettes
 *
 * Copyright 2005 Glenn Wurster
 *
 * 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 "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "mmsystem.h"

#include "wine/test.h"

static const PALETTEENTRY logpalettedata[8] = {
    { 0x10, 0x20, 0x30, PC_NOCOLLAPSE },
    { 0x20, 0x30, 0x40, PC_NOCOLLAPSE },
    { 0x30, 0x40, 0x50, PC_NOCOLLAPSE },
    { 0x40, 0x50, 0x60, PC_NOCOLLAPSE },
    { 0x50, 0x60, 0x70, PC_NOCOLLAPSE },
    { 0x60, 0x70, 0x80, PC_NOCOLLAPSE },
    { 0x70, 0x80, 0x90, PC_NOCOLLAPSE },
    { 0x80, 0x90, 0xA0, PC_NOCOLLAPSE },
};

static void test_DIB_PAL_COLORS(void) {
    HDC hdc = GetDC( NULL );
    HDC memhdc = CreateCompatibleDC( hdc );
    HBITMAP hbmp, hbmpOld;
    char bmpbuf[sizeof(BITMAPINFO) + 10 * sizeof(WORD)];
    PBITMAPINFO bmp = (PBITMAPINFO)bmpbuf;
    WORD * bmpPalPtr;
    char logpalettebuf[sizeof(LOGPALETTE) + sizeof(logpalettedata)];
    PLOGPALETTE logpalette = (PLOGPALETTE)logpalettebuf;
    HPALETTE hpal, hpalOld;
    COLORREF setColor, chkColor, getColor;
    int i;

    /* Initialize the logical palette with a few colours */
    logpalette->palVersion = 0x300;
    logpalette->palNumEntries = 8;
    memcpy( logpalette->palPalEntry, logpalettedata, sizeof(logpalettedata) );
    hpal = CreatePalette( logpalette ); 
    hpalOld = SelectPalette( memhdc, hpal, FALSE );
    ok( hpalOld != NULL, "error=%d\n", GetLastError() );

    /* Create a DIB BMP which references colours in the logical palette */
    memset( bmp, 0x00, sizeof(BITMAPINFO) );
    bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmp->bmiHeader.biWidth = 1;
    bmp->bmiHeader.biHeight = 1;
    bmp->bmiHeader.biPlanes = 1;
    bmp->bmiHeader.biBitCount = 8;
    bmp->bmiHeader.biCompression = BI_RGB;
    bmp->bmiHeader.biClrUsed = 10;
    bmp->bmiHeader.biClrImportant = 0;
    bmpPalPtr = (WORD *)&bmp->bmiColors;
    for( i = 0; i < 8; i++ ) {
        *bmpPalPtr++ = i;
    }
    *bmpPalPtr++ = 8; /* Pointer to logical palette index just outside range */
    *bmpPalPtr++ = 19; /* Pointer to bad logical palette index */

    hbmp = CreateDIBSection( memhdc, bmp, DIB_PAL_COLORS, 0, 0, 0 );
    ok( hbmp != NULL, "error=%d\n", GetLastError() );
    hbmpOld = SelectObject( memhdc, hbmp );
    ok( hbmpOld != NULL, "error=%d\n", GetLastError() );

    /* Test with a RGB to DIB_PAL_COLORS */
    setColor = RGB( logpalettedata[1].peRed, logpalettedata[1].peGreen, logpalettedata[1].peBlue );
    SetPixel( memhdc, 0, 0, setColor );
    chkColor = RGB( logpalettedata[1].peRed, logpalettedata[1].peGreen, logpalettedata[1].peBlue );
    getColor = GetPixel( memhdc, 0, 0 );
    ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor );

    /* Test with a valid DIBINDEX to DIB_PAL_COLORS */
    setColor = DIBINDEX( 2 );
    SetPixel( memhdc, 0, 0, setColor );
    chkColor = RGB( logpalettedata[2].peRed, logpalettedata[2].peGreen, logpalettedata[2].peBlue );
    getColor = GetPixel( memhdc, 0, 0 );
    ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor );

    /* Test with a invalid DIBINDEX to DIB_PAL_COLORS */
    setColor = DIBINDEX( 12 );
    SetPixel( memhdc, 0, 0, setColor );
    chkColor = RGB( 0, 0, 0 );
    getColor = GetPixel( memhdc, 0, 0 );
    ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor );

    /* Test for double wraparound on logical palette references from */
    /* DIBINDEX by DIB_PAL_COLORS. */
    setColor = DIBINDEX( 9 );
    SetPixel( memhdc, 0, 0, setColor );
    chkColor = RGB( logpalettedata[3].peRed, logpalettedata[3].peGreen, logpalettedata[3].peBlue );
    getColor = GetPixel( memhdc, 0, 0 );
    ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor );

    SelectPalette( memhdc, hpalOld, FALSE );
    DeleteObject( hpal );
    SelectObject( memhdc, hbmpOld );
    DeleteObject( hbmp );
    DeleteDC( memhdc );
    ReleaseDC( NULL, hdc );
}

static void test_palette_entries(void)
{
    char logpalettebuf[sizeof(LOGPALETTE) + sizeof(logpalettedata)];
    PLOGPALETTE logpalette = (PLOGPALETTE)logpalettebuf;
    HPALETTE hpal;
    UINT res=0;
    PALETTEENTRY palEntry = { 0x1, 0x2, 0x3, 0xff };
    PALETTEENTRY getEntryResult;

    /* Initialize the logical palette with a few colours */
    logpalette->palVersion = 0x300;
    logpalette->palNumEntries = 8;
    memcpy( logpalette->palPalEntry, logpalettedata, sizeof(logpalettedata) );
    hpal = CreatePalette( logpalette );

    /* Set a new entry with peFlags to 0xff */
    SetPaletteEntries(hpal, 0, 1, &palEntry);

    /* Retrieve the entry to see if GDI32 performs any filtering on peFlags */
    res = GetPaletteEntries(hpal, 0, 1, &getEntryResult);
    ok(res == 1, "GetPaletteEntries should have returned 1 but returned %d\n", res);

    ok( palEntry.peFlags == getEntryResult.peFlags, "palEntry.peFlags (%#x) != getEntryResult.peFlags (%#x)\n", palEntry.peFlags, getEntryResult.peFlags );
}

static void test_halftone_palette(void)
{
    HDC hdc;
    HPALETTE pal;
    PALETTEENTRY entries[256];
    PALETTEENTRY defpal[20];
    int i, count;

    hdc = GetDC(0);

    count = GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, defpal );
    ok( count == 20, "wrong size %u\n", count );

    pal = CreateHalftonePalette( hdc );
    count = GetPaletteEntries( pal, 0, 256, entries );
    ok( count == 256 || broken(count <= 20), /* nt 4 */
        "wrong size %u\n", count );

    /* first and last 10 match the default palette */
    if (count >= 20)
    {
        for (i = 0; i < 10; i++)
        {
            ok( entries[i].peRed   == defpal[i].peRed &&
                entries[i].peGreen == defpal[i].peGreen &&
                entries[i].peBlue  == defpal[i].peBlue &&
                !entries[i].peFlags,
                "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i,
                entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags,
                defpal[i].peRed, defpal[i].peGreen, defpal[i].peBlue );
        }
        for (i = count - 10; i < count; i++)
        {
            int idx = i - count + 20;
            ok( entries[i].peRed   == defpal[idx].peRed &&
                entries[i].peGreen == defpal[idx].peGreen &&
                entries[i].peBlue  == defpal[idx].peBlue &&
                !entries[i].peFlags,
                "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i,
                entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags,
                defpal[idx].peRed, defpal[idx].peGreen, defpal[idx].peBlue );
        }
    }
    DeleteObject( pal );
    ReleaseDC( 0, hdc );
}

START_TEST(palette)
{
    test_DIB_PAL_COLORS();
    test_palette_entries();
    test_halftone_palette();
}
