/*
 * Copyright 2016 Andrey Gusev
 *
 * 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 "d3d10_1.h"
#include "d3dx10.h"
#include "d3dx10core.h"
#include "d3dcompiler.h"

#include "wine/debug.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3dx);

struct asyncdataloader
{
    ID3DX10DataLoader ID3DX10DataLoader_iface;

    union
    {
        struct
        {
            WCHAR *path;
        } file;
        struct
        {
            HMODULE module;
            HRSRC rsrc;
        } resource;
    } u;
    void *data;
    SIZE_T size;
};

static inline struct asyncdataloader *impl_from_ID3DX10DataLoader(ID3DX10DataLoader *iface)
{
    return CONTAINING_RECORD(iface, struct asyncdataloader, ID3DX10DataLoader_iface);
}

static HRESULT WINAPI memorydataloader_Load(ID3DX10DataLoader *iface)
{
    TRACE("iface %p.\n", iface);
    return S_OK;
}

static HRESULT WINAPI memorydataloader_Decompress(ID3DX10DataLoader *iface, void **data, SIZE_T *size)
{
    struct asyncdataloader *loader = impl_from_ID3DX10DataLoader(iface);

    TRACE("iface %p, data %p, size %p.\n", iface, data, size);

    *data = loader->data;
    *size = loader->size;

    return S_OK;
}

static HRESULT WINAPI memorydataloader_Destroy(ID3DX10DataLoader *iface)
{
    struct asyncdataloader *loader = impl_from_ID3DX10DataLoader(iface);

    TRACE("iface %p.\n", iface);

    HeapFree(GetProcessHeap(), 0, loader);
    return S_OK;
}

static const ID3DX10DataLoaderVtbl memorydataloadervtbl =
{
    memorydataloader_Load,
    memorydataloader_Decompress,
    memorydataloader_Destroy
};

static HRESULT WINAPI filedataloader_Load(ID3DX10DataLoader *iface)
{
    struct asyncdataloader *loader = impl_from_ID3DX10DataLoader(iface);
    DWORD size, read_len;
    HANDLE file;
    void *data;
    BOOL ret;

    TRACE("iface %p.\n", iface);

    /* Always buffer file contents, even if Load() was already called. */
    file = CreateFileW(loader->u.file.path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (file == INVALID_HANDLE_VALUE)
        return D3D10_ERROR_FILE_NOT_FOUND;

    size = GetFileSize(file, NULL);
    data = HeapAlloc(GetProcessHeap(), 0, size);
    if (!data)
    {
        CloseHandle(file);
        return E_OUTOFMEMORY;
    }

    ret = ReadFile(file, data, size, &read_len, NULL);
    CloseHandle(file);
    if (!ret)
    {
        ERR("Failed to read file contents.\n");
        HeapFree(GetProcessHeap(), 0, data);
        return E_FAIL;
    }

    HeapFree(GetProcessHeap(), 0, loader->data);
    loader->data = data;
    loader->size = size;

    return S_OK;
}

static HRESULT WINAPI filedataloader_Decompress(ID3DX10DataLoader *iface, void **data, SIZE_T *size)
{
    struct asyncdataloader *loader = impl_from_ID3DX10DataLoader(iface);

    TRACE("iface %p, data %p, size %p.\n", iface, data, size);

    if (!loader->data)
        return E_FAIL;

    *data = loader->data;
    *size = loader->size;

    return S_OK;
}

static HRESULT WINAPI filedataloader_Destroy(ID3DX10DataLoader *iface)
{
    struct asyncdataloader *loader = impl_from_ID3DX10DataLoader(iface);

    TRACE("iface %p.\n", iface);

    HeapFree(GetProcessHeap(), 0, loader->u.file.path);
    HeapFree(GetProcessHeap(), 0, loader->data);
    HeapFree(GetProcessHeap(), 0, loader);

    return S_OK;
}

static const ID3DX10DataLoaderVtbl filedataloadervtbl =
{
    filedataloader_Load,
    filedataloader_Decompress,
    filedataloader_Destroy
};

static HRESULT WINAPI resourcedataloader_Load(ID3DX10DataLoader *iface)
{
    struct asyncdataloader *loader = impl_from_ID3DX10DataLoader(iface);
    HGLOBAL hglobal;

    TRACE("iface %p.\n", iface);

    if (loader->data)
        return S_OK;

    hglobal = LoadResource(loader->u.resource.module, loader->u.resource.rsrc);
    if (!hglobal)
    {
        ERR("Failed to load resource.\n");
        return E_FAIL;
    }

    loader->data = LockResource(hglobal);
    loader->size = SizeofResource(loader->u.resource.module, loader->u.resource.rsrc);

    return S_OK;
}

static HRESULT WINAPI resourcedataloader_Decompress(ID3DX10DataLoader *iface, void **data, SIZE_T *size)
{
    struct asyncdataloader *loader = impl_from_ID3DX10DataLoader(iface);

    TRACE("iface %p, data %p, size %p.\n", iface, data, size);

    if (!loader->data)
        return E_FAIL;

    *data = loader->data;
    *size = loader->size;

    return S_OK;
}

static HRESULT WINAPI resourcedataloader_Destroy(ID3DX10DataLoader *iface)
{
    struct asyncdataloader *loader = impl_from_ID3DX10DataLoader(iface);

    TRACE("iface %p.\n", iface);

    HeapFree(GetProcessHeap(), 0, loader);

    return S_OK;
}

static const ID3DX10DataLoaderVtbl resourcedataloadervtbl =
{
    resourcedataloader_Load,
    resourcedataloader_Decompress,
    resourcedataloader_Destroy
};

HRESULT WINAPI D3DX10CompileFromMemory(const char *data, SIZE_T data_size, const char *filename,
        const D3D10_SHADER_MACRO *defines, ID3D10Include *include, const char *entry_point,
        const char *target, UINT sflags, UINT eflags, ID3DX10ThreadPump *pump, ID3D10Blob **shader,
        ID3D10Blob **error_messages, HRESULT *hresult)
{
    TRACE("data %s, data_size %lu, filename %s, defines %p, include %p, entry_point %s, target %s, "
            "sflags %#x, eflags %#x, pump %p, shader %p, error_messages %p, hresult %p.\n",
            debugstr_an(data, data_size), data_size, debugstr_a(filename), defines, include,
            debugstr_a(entry_point), debugstr_a(target), sflags, eflags, pump, shader,
            error_messages, hresult);

    if (pump)
        FIXME("Unimplemented ID3DX10ThreadPump handling.\n");

    return D3DCompile(data, data_size, filename, defines, include, entry_point, target,
            sflags, eflags, shader, error_messages);
}

HRESULT WINAPI D3DX10CreateEffectPoolFromFileA(const char *filename, const D3D10_SHADER_MACRO *defines,
        ID3D10Include *include, const char *profile, UINT hlslflags, UINT fxflags, ID3D10Device *device,
        ID3DX10ThreadPump *pump, ID3D10EffectPool **effectpool, ID3D10Blob **errors, HRESULT *hresult)
{
    FIXME("filename %s, defines %p, include %p, profile %s, hlslflags %#x, fxflags %#x, device %p, "
            "pump %p, effectpool %p, errors %p, hresult %p, stub!\n",
            debugstr_a(filename), defines, include, debugstr_a(profile), hlslflags, fxflags, device,
            pump, effectpool, errors, hresult);

    return E_NOTIMPL;
}

HRESULT WINAPI D3DX10CreateEffectPoolFromFileW(const WCHAR *filename, const D3D10_SHADER_MACRO *defines,
        ID3D10Include *include, const char *profile, UINT hlslflags, UINT fxflags, ID3D10Device *device,
        ID3DX10ThreadPump *pump, ID3D10EffectPool **effectpool, ID3D10Blob **errors, HRESULT *hresult)
{
    FIXME("filename %s, defines %p, include %p, profile %s, hlslflags %#x, fxflags %#x, device %p, "
            "pump %p, effectpool %p, errors %p, hresult %p, stub!\n",
            debugstr_w(filename), defines, include, debugstr_a(profile), hlslflags, fxflags, device,
            pump, effectpool, errors, hresult);

    return E_NOTIMPL;
}

HRESULT WINAPI D3DX10CreateAsyncMemoryLoader(const void *data, SIZE_T data_size, ID3DX10DataLoader **loader)
{
    struct asyncdataloader *object;

    TRACE("data %p, data_size %lu, loader %p.\n", data, data_size, loader);

    if (!data || !loader)
        return E_FAIL;

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

    object->ID3DX10DataLoader_iface.lpVtbl = &memorydataloadervtbl;
    object->data = (void *)data;
    object->size = data_size;

    *loader = &object->ID3DX10DataLoader_iface;

    return S_OK;
}

HRESULT WINAPI D3DX10CreateAsyncFileLoaderA(const char *filename, ID3DX10DataLoader **loader)
{
    WCHAR *filename_w;
    HRESULT hr;
    int len;

    TRACE("filename %s, loader %p.\n", debugstr_a(filename), loader);

    if (!filename || !loader)
        return E_FAIL;

    len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
    filename_w = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*filename_w));
    MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_w, len);

    hr = D3DX10CreateAsyncFileLoaderW(filename_w, loader);

    HeapFree(GetProcessHeap(), 0, filename_w);

    return hr;
}

HRESULT WINAPI D3DX10CreateAsyncFileLoaderW(const WCHAR *filename, ID3DX10DataLoader **loader)
{
    struct asyncdataloader *object;

    TRACE("filename %s, loader %p.\n", debugstr_w(filename), loader);

    if (!filename || !loader)
        return E_FAIL;

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

    object->ID3DX10DataLoader_iface.lpVtbl = &filedataloadervtbl;
    object->u.file.path = HeapAlloc(GetProcessHeap(), 0, (strlenW(filename) + 1) * sizeof(WCHAR));
    if (!object->u.file.path)
    {
        HeapFree(GetProcessHeap(), 0, object);
        return E_OUTOFMEMORY;
    }
    strcpyW(object->u.file.path, filename);
    object->data = NULL;
    object->size = 0;

    *loader = &object->ID3DX10DataLoader_iface;

    return S_OK;
}

HRESULT WINAPI D3DX10CreateAsyncResourceLoaderA(HMODULE module, const char *resource, ID3DX10DataLoader **loader)
{
    struct asyncdataloader *object;
    HRSRC rsrc;

    TRACE("module %p, resource %s, loader %p.\n", module, debugstr_a(resource), loader);

    if (!loader)
        return E_FAIL;

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

    if (!(rsrc = FindResourceA(module, resource, (const char *)RT_RCDATA)))
    {
        ERR("Failed to find resource.\n");
        HeapFree(GetProcessHeap(), 0, object);
        return D3DX10_ERR_INVALID_DATA;
    }

    object->ID3DX10DataLoader_iface.lpVtbl = &resourcedataloadervtbl;
    object->u.resource.module = module;
    object->u.resource.rsrc = rsrc;
    object->data = NULL;
    object->size = 0;

    *loader = &object->ID3DX10DataLoader_iface;

    return S_OK;
}

HRESULT WINAPI D3DX10CreateAsyncResourceLoaderW(HMODULE module, const WCHAR *resource, ID3DX10DataLoader **loader)
{
    struct asyncdataloader *object;
    HRSRC rsrc;

    TRACE("module %p, resource %s, loader %p.\n", module, debugstr_w(resource), loader);

    if (!loader)
        return E_FAIL;

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

    if (!(rsrc = FindResourceW(module, resource, (const WCHAR *)RT_RCDATA)))
    {
        ERR("Failed to find resource.\n");
        HeapFree(GetProcessHeap(), 0, object);
        return D3DX10_ERR_INVALID_DATA;
    }

    object->ID3DX10DataLoader_iface.lpVtbl = &resourcedataloadervtbl;
    object->u.resource.module = module;
    object->u.resource.rsrc = rsrc;
    object->data = NULL;
    object->size = 0;

    *loader = &object->ID3DX10DataLoader_iface;

    return S_OK;
}
