/*              DirectDraw - IDirectPalette base interface
 *
 * Copyright 1997-2000 Marcus Meissner
 * Copyright 2000-2001 TransGaming Technologies Inc.
 * Copyright 2006 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
 */
#include "config.h"
#include "wine/port.h"
#include "wined3d_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3d);

ULONG CDECL wined3d_palette_incref(struct wined3d_palette *palette)
{
    ULONG refcount = InterlockedIncrement(&palette->ref);

    TRACE("%p increasing refcount to %u.\n", palette, refcount);

    return refcount;
}

ULONG CDECL wined3d_palette_decref(struct wined3d_palette *palette)
{
    ULONG refcount = InterlockedDecrement(&palette->ref);

    TRACE("%p decreasing refcount to %u.\n", palette, refcount);

    if (!refcount)
        HeapFree(GetProcessHeap(), 0, palette);

    return refcount;
}

HRESULT CDECL wined3d_palette_get_entries(const struct wined3d_palette *palette,
        DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries)
{
    unsigned int i;
    TRACE("palette %p, flags %#x, start %u, count %u, entries %p.\n",
            palette, flags, start, count, entries);

    if (flags)
        return WINED3DERR_INVALIDCALL; /* unchecked */
    if (start > palette->size || count > palette->size - start)
        return WINED3DERR_INVALIDCALL;

    if (palette->flags & WINED3D_PALETTE_8BIT_ENTRIES)
    {
        BYTE *entry = (BYTE *)entries;

        for (i = start; i < count + start; ++i)
            *entry++ = palette->colors[i].rgbRed;
    }
    else
    {
        for (i = 0; i < count; ++i)
        {
            entries[i].peRed = palette->colors[i + start].rgbRed;
            entries[i].peGreen = palette->colors[i + start].rgbGreen;
            entries[i].peBlue = palette->colors[i + start].rgbBlue;
            entries[i].peFlags = palette->colors[i + start].rgbReserved;
        }
    }

    return WINED3D_OK;
}

void CDECL wined3d_palette_apply_to_dc(const struct wined3d_palette *palette, HDC dc)
{
    if (SetDIBColorTable(dc, 0, 256, palette->colors) != 256)
        ERR("Failed to set DIB color table.\n");
}

HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette,
        DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries)
{
    unsigned int i;

    TRACE("palette %p, flags %#x, start %u, count %u, entries %p.\n",
            palette, flags, start, count, entries);
    TRACE("Palette flags: %#x.\n", palette->flags);

    if (palette->flags & WINED3D_PALETTE_8BIT_ENTRIES)
    {
        const BYTE *entry = (const BYTE *)entries;

        for (i = start; i < count + start; ++i)
            palette->colors[i].rgbRed = *entry++;
    }
    else
    {
        for (i = 0; i < count; ++i)
        {
            palette->colors[i + start].rgbRed = entries[i].peRed;
            palette->colors[i + start].rgbGreen = entries[i].peGreen;
            palette->colors[i + start].rgbBlue = entries[i].peBlue;
            palette->colors[i + start].rgbReserved = entries[i].peFlags;
        }

        /* When WINEDDCAPS_ALLOW256 isn't set we need to override entry 0 with black and 255 with white */
        if (!(palette->flags & WINED3D_PALETTE_ALLOW_256))
        {
            TRACE("WINED3D_PALETTE_ALLOW_256 not set, overriding palette entry 0 with black and 255 with white.\n");
            palette->colors[0].rgbRed = 0;
            palette->colors[0].rgbGreen = 0;
            palette->colors[0].rgbBlue = 0;

            palette->colors[255].rgbRed = 255;
            palette->colors[255].rgbGreen = 255;
            palette->colors[255].rgbBlue = 255;
        }
    }

    return WINED3D_OK;
}

static HRESULT wined3d_palette_init(struct wined3d_palette *palette, struct wined3d_device *device,
        DWORD flags, unsigned int entry_count, const PALETTEENTRY *entries)
{
    HRESULT hr;

    palette->ref = 1;
    palette->device = device;
    palette->flags = flags;
    palette->size = entry_count;

    if (FAILED(hr = wined3d_palette_set_entries(palette, 0, 0, entry_count, entries)))
    {
        WARN("Failed to set palette entries, hr %#x.\n", hr);
        return hr;
    }

    return WINED3D_OK;
}

HRESULT CDECL wined3d_palette_create(struct wined3d_device *device, DWORD flags,
        unsigned int entry_count, const PALETTEENTRY *entries, struct wined3d_palette **palette)
{
    struct wined3d_palette *object;
    HRESULT hr;

    TRACE("device %p, flags %#x, entry_count %u, entries %p, palette %p.\n",
            device, flags, entry_count, entries, palette);

    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    if (!object)
        return E_OUTOFMEMORY;

    if (FAILED(hr = wined3d_palette_init(object, device, flags, entry_count, entries)))
    {
        WARN("Failed to initialize palette, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }

    TRACE("Created palette %p.\n", object);
    *palette = object;

    return WINED3D_OK;
}
