/*
 * Copyright (C) 2012 Christian Costa
 *
 * 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 "wine/debug.h"

#define COBJMACROS
#include "d3dx9.h"
#include "d3dx9xof.h"
#undef MAKE_DDHRESULT
#include "dxfile.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3dx);

static HRESULT error_dxfile_to_d3dxfile(HRESULT error)
{
    switch (error)
    {
        case DXFILEERR_BADFILETYPE:
            return D3DXFERR_BADFILETYPE;
        case DXFILEERR_BADFILEVERSION:
            return D3DXFERR_BADFILEVERSION;
        case DXFILEERR_BADFILEFLOATSIZE:
            return D3DXFERR_BADFILEFLOATSIZE;
        case DXFILEERR_PARSEERROR:
            return D3DXFERR_PARSEERROR;
        case DXFILEERR_BADVALUE:
            return D3DXFERR_BADVALUE;
        default:
            FIXME("Cannot map error %#x\n", error);
            return E_FAIL;
    }
}

struct d3dx9_file
{
    ID3DXFile ID3DXFile_iface;
    LONG ref;
    IDirectXFile *dxfile;
};

struct d3dx9_file_enum_object
{
    ID3DXFileEnumObject ID3DXFileEnumObject_iface;
    LONG ref;
    ULONG nb_children;
    ID3DXFileData **children;
};

struct d3dx9_file_data
{
    ID3DXFileData ID3DXFileData_iface;
    LONG ref;
    BOOL reference;
    IDirectXFileData *dxfile_data;
    ULONG nb_children;
    ID3DXFileData **children;
};

static inline struct d3dx9_file *impl_from_ID3DXFile(ID3DXFile *iface)
{
    return CONTAINING_RECORD(iface, struct d3dx9_file, ID3DXFile_iface);
}

static inline struct d3dx9_file_enum_object *impl_from_ID3DXFileEnumObject(ID3DXFileEnumObject *iface)
{
    return CONTAINING_RECORD(iface, struct d3dx9_file_enum_object, ID3DXFileEnumObject_iface);
}

static inline struct d3dx9_file_data *impl_from_ID3DXFileData(ID3DXFileData *iface)
{
    return CONTAINING_RECORD(iface, struct d3dx9_file_data, ID3DXFileData_iface);
}

static HRESULT WINAPI d3dx9_file_data_QueryInterface(ID3DXFileData *iface, REFIID riid, void **out)
{
    TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);

    if (IsEqualGUID(riid, &IID_ID3DXFileData)
            || IsEqualGUID(riid, &IID_IUnknown))
    {
        iface->lpVtbl->AddRef(iface);
        *out = iface;
        return S_OK;
    }

    WARN("Interface %s not found.\n", debugstr_guid(riid));

    *out = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI d3dx9_file_data_AddRef(ID3DXFileData *iface)
{
    struct d3dx9_file_data *file_data = impl_from_ID3DXFileData(iface);
    ULONG refcount = InterlockedIncrement(&file_data->ref);

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

    return refcount;
}

static ULONG WINAPI d3dx9_file_data_Release(ID3DXFileData *iface)
{
    struct d3dx9_file_data *file_data = impl_from_ID3DXFileData(iface);
    ULONG refcount = InterlockedDecrement(&file_data->ref);

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

    if (!refcount)
    {
        ULONG i;

        for (i = 0; i < file_data->nb_children; ++i)
        {
            ID3DXFileData *child = file_data->children[i];
            child->lpVtbl->Release(child);
        }
        HeapFree(GetProcessHeap(), 0, file_data->children);
        IDirectXFileData_Release(file_data->dxfile_data);
        HeapFree(GetProcessHeap(), 0, file_data);
    }

    return refcount;
}

static HRESULT WINAPI d3dx9_file_data_GetEnum(ID3DXFileData *iface, ID3DXFileEnumObject **enum_object)
{
    FIXME("iface %p, enum_object %p stub!\n", iface, enum_object);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3dx9_file_data_GetName(ID3DXFileData *iface, char *name, SIZE_T *size)
{
    struct d3dx9_file_data *file_data = impl_from_ID3DXFileData(iface);
    DWORD dxfile_size;
    HRESULT ret;

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

    if (!size)
        return D3DXFERR_BADVALUE;

    dxfile_size = *size;

    ret = IDirectXFileData_GetName(file_data->dxfile_data, name, &dxfile_size);
    if (ret != DXFILE_OK)
        return error_dxfile_to_d3dxfile(ret);

    if (!dxfile_size)
    {
        /* Contrary to d3dxof, d3dx9_36 returns an empty string with a null byte when no name is available.
         * If the input size is 0, it returns a length of 1 without touching the buffer */
        dxfile_size = 1;
        if (name && *size)
            name[0] = 0;
    }

    *size = dxfile_size;

    return S_OK;
}

static HRESULT WINAPI d3dx9_file_data_GetId(ID3DXFileData *iface, GUID *guid)
{
    struct d3dx9_file_data *file_data = impl_from_ID3DXFileData(iface);
    HRESULT ret;

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

    if (!guid)
        return E_POINTER;

    ret = IDirectXFileData_GetId(file_data->dxfile_data, guid);
    if (ret != DXFILE_OK)
        return error_dxfile_to_d3dxfile(ret);

    return S_OK;
}

static HRESULT WINAPI d3dx9_file_data_Lock(ID3DXFileData *iface, SIZE_T *size, const void **data)
{
    struct d3dx9_file_data *file_data = impl_from_ID3DXFileData(iface);
    DWORD dxfile_size;
    HRESULT ret;

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

    if (!size || !data)
        return E_POINTER;

    ret = IDirectXFileData_GetData(file_data->dxfile_data, NULL, &dxfile_size, (void **)data);
    if (ret != DXFILE_OK)
        return error_dxfile_to_d3dxfile(ret);

    *size = dxfile_size;

    return S_OK;
}

static HRESULT WINAPI d3dx9_file_data_Unlock(ID3DXFileData *iface)
{
    TRACE("iface %p.\n", iface);

    /* Nothing to do */

    return S_OK;
}

static HRESULT WINAPI d3dx9_file_data_GetType(ID3DXFileData *iface, GUID *guid)
{
    struct d3dx9_file_data *file_data = impl_from_ID3DXFileData(iface);
    const GUID *dxfile_guid;
    HRESULT ret;

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

    ret = IDirectXFileData_GetType(file_data->dxfile_data, &dxfile_guid);
    if (ret != DXFILE_OK)
        return error_dxfile_to_d3dxfile(ret);

    *guid = *dxfile_guid;

    return S_OK;
}

static BOOL WINAPI d3dx9_file_data_IsReference(ID3DXFileData *iface)
{
    struct d3dx9_file_data *file_data = impl_from_ID3DXFileData(iface);

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

    return file_data->reference;
}

static HRESULT WINAPI d3dx9_file_data_GetChildren(ID3DXFileData *iface, SIZE_T *children)
{
    struct d3dx9_file_data *file_data = impl_from_ID3DXFileData(iface);

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

    if (!children)
        return E_POINTER;

    *children = file_data->nb_children;

    return S_OK;
}

static HRESULT WINAPI d3dx9_file_data_GetChild(ID3DXFileData *iface, SIZE_T id, ID3DXFileData **object)
{
    struct d3dx9_file_data *file_data = impl_from_ID3DXFileData(iface);

    TRACE("iface %p, id %#lx, object %p.\n", iface, id, object);

    if (!object)
        return E_POINTER;

    *object = file_data->children[id];
    (*object)->lpVtbl->AddRef(*object);

    return S_OK;
}

static const ID3DXFileDataVtbl d3dx9_file_data_vtbl =
{
    d3dx9_file_data_QueryInterface,
    d3dx9_file_data_AddRef,
    d3dx9_file_data_Release,
    d3dx9_file_data_GetEnum,
    d3dx9_file_data_GetName,
    d3dx9_file_data_GetId,
    d3dx9_file_data_Lock,
    d3dx9_file_data_Unlock,
    d3dx9_file_data_GetType,
    d3dx9_file_data_IsReference,
    d3dx9_file_data_GetChildren,
    d3dx9_file_data_GetChild,
};

static HRESULT d3dx9_file_data_create(IDirectXFileObject *dxfile_object, ID3DXFileData **ret_iface)
{
    struct d3dx9_file_data *object;
    IDirectXFileObject *data_object;
    unsigned int children_array_size = 0;
    HRESULT ret;

    TRACE("dxfile_object %p, ret_iface %p.\n", dxfile_object, ret_iface);

    *ret_iface = NULL;

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

    object->ID3DXFileData_iface.lpVtbl = &d3dx9_file_data_vtbl;
    object->ref = 1;

    ret = IDirectXFileObject_QueryInterface(dxfile_object, &IID_IDirectXFileData, (void **)&object->dxfile_data);
    if (FAILED(ret))
    {
        IDirectXFileDataReference *reference;

        ret = IDirectXFileObject_QueryInterface(dxfile_object, &IID_IDirectXFileDataReference, (void **)&reference);
        if (SUCCEEDED(ret))
        {
            ret = IDirectXFileDataReference_Resolve(reference, &object->dxfile_data);
            IUnknown_Release(reference);
            if (FAILED(ret))
            {
                HeapFree(GetProcessHeap(), 0, object);
                return E_FAIL;
            }
            object->reference = TRUE;
        }
        else
        {
            FIXME("Don't know what to do with binary object\n");
            HeapFree(GetProcessHeap(), 0, object);
            return E_FAIL;
        }
    }

    while (SUCCEEDED(ret = IDirectXFileData_GetNextObject(object->dxfile_data, &data_object)))
    {
        if (object->nb_children >= children_array_size)
        {
            ID3DXFileData **new_children;

            if (object->children)
            {
                children_array_size *= 2;
                new_children = HeapReAlloc(GetProcessHeap(), 0, object->children,
                        sizeof(*object->children) * children_array_size);
            }
            else
            {
                children_array_size = 4;
                new_children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children) * children_array_size);
            }
            if (!new_children)
            {
                ret = E_OUTOFMEMORY;
                break;
            }
            object->children = new_children;
        }
        ret = d3dx9_file_data_create(data_object, &object->children[object->nb_children]);
        IUnknown_Release(data_object);
        if (FAILED(ret))
            break;
        object->nb_children++;
    }
    if (ret != DXFILEERR_NOMOREOBJECTS)
    {
        (&object->ID3DXFileData_iface)->lpVtbl->Release(&object->ID3DXFileData_iface);
        return ret;
    }
    if (object->children)
    {
        ID3DXFileData **new_children;

        new_children = HeapReAlloc(GetProcessHeap(), 0, object->children,
                sizeof(*object->children) * object->nb_children);
        if (new_children)
            object->children = new_children;
    }

    TRACE("Found %u children\n", object->nb_children);

    *ret_iface = &object->ID3DXFileData_iface;

    return S_OK;
}

static HRESULT WINAPI d3dx9_file_enum_object_QueryInterface(ID3DXFileEnumObject *iface, REFIID riid, void **out)
{
    TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);

    if (IsEqualGUID(riid, &IID_ID3DXFileEnumObject)
            || IsEqualGUID(riid, &IID_IUnknown))
    {
        iface->lpVtbl->AddRef(iface);
        *out = iface;
        return S_OK;
    }

    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));

    *out = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI d3dx9_file_enum_object_AddRef(ID3DXFileEnumObject *iface)
{
    struct d3dx9_file_enum_object *file_enum = impl_from_ID3DXFileEnumObject(iface);
    ULONG refcount = InterlockedIncrement(&file_enum->ref);

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

    return refcount;
}

static ULONG WINAPI d3dx9_file_enum_object_Release(ID3DXFileEnumObject *iface)
{
    struct d3dx9_file_enum_object *file_enum = impl_from_ID3DXFileEnumObject(iface);
    ULONG refcount = InterlockedDecrement(&file_enum->ref);

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

    if (!refcount)
    {
        ULONG i;

        for (i = 0; i < file_enum->nb_children; ++i)
        {
            ID3DXFileData *child = file_enum->children[i];
            child->lpVtbl->Release(child);
        }
        HeapFree(GetProcessHeap(), 0, file_enum->children);
        HeapFree(GetProcessHeap(), 0, file_enum);
    }

    return refcount;
}

static HRESULT WINAPI d3dx9_file_enum_object_GetFile(ID3DXFileEnumObject *iface, ID3DXFile **file)
{
    FIXME("iface %p, file %p stub!\n", iface, file);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3dx9_file_enum_object_GetChildren(ID3DXFileEnumObject *iface, SIZE_T *children)
{
    struct d3dx9_file_enum_object *file_enum = impl_from_ID3DXFileEnumObject(iface);

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

    if (!children)
        return E_POINTER;

    *children = file_enum->nb_children;

    return S_OK;
}

static HRESULT WINAPI d3dx9_file_enum_object_GetChild(ID3DXFileEnumObject *iface, SIZE_T id, ID3DXFileData **object)
{
    struct d3dx9_file_enum_object *file_enum = impl_from_ID3DXFileEnumObject(iface);

    TRACE("iface %p, id %#lx, object %p.\n", iface, id, object);

    if (!object)
        return E_POINTER;

    *object = file_enum->children[id];
    (*object)->lpVtbl->AddRef(*object);

    return S_OK;
}

static HRESULT WINAPI d3dx9_file_enum_object_GetDataObjectById(ID3DXFileEnumObject *iface,
        REFGUID guid, ID3DXFileData **object)
{
    FIXME("iface %p, guid %s, object %p stub!\n", iface, debugstr_guid(guid), object);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3dx9_file_enum_object_GetDataObjectByName(ID3DXFileEnumObject *iface,
        const char *name, ID3DXFileData **object)
{
    FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);

    return E_NOTIMPL;
}

static const ID3DXFileEnumObjectVtbl d3dx9_file_enum_object_vtbl =
{
    d3dx9_file_enum_object_QueryInterface,
    d3dx9_file_enum_object_AddRef,
    d3dx9_file_enum_object_Release,
    d3dx9_file_enum_object_GetFile,
    d3dx9_file_enum_object_GetChildren,
    d3dx9_file_enum_object_GetChild,
    d3dx9_file_enum_object_GetDataObjectById,
    d3dx9_file_enum_object_GetDataObjectByName,
};

static HRESULT WINAPI d3dx9_file_QueryInterface(ID3DXFile *iface, REFIID riid, void **out)
{
    TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);

    if (IsEqualGUID(riid, &IID_ID3DXFile)
            || IsEqualGUID(riid, &IID_IUnknown))
    {
        iface->lpVtbl->AddRef(iface);
        *out = iface;
        return S_OK;
    }

    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));

    *out = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI d3dx9_file_AddRef(ID3DXFile *iface)
{
    struct d3dx9_file *file = impl_from_ID3DXFile(iface);
    ULONG refcount = InterlockedIncrement(&file->ref);

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

    return refcount;
}

static ULONG WINAPI d3dx9_file_Release(ID3DXFile *iface)
{
    struct d3dx9_file *file = impl_from_ID3DXFile(iface);
    ULONG refcount = InterlockedDecrement(&file->ref);

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

    if (!refcount)
    {
        IDirectXFile_Release(file->dxfile);
        HeapFree(GetProcessHeap(), 0, file);
    }

    return refcount;
}

static HRESULT WINAPI d3dx9_file_CreateEnumObject(ID3DXFile *iface, const void *source,
        D3DXF_FILELOADOPTIONS options, ID3DXFileEnumObject **enum_object)
{
    struct d3dx9_file *file = impl_from_ID3DXFile(iface);
    struct d3dx9_file_enum_object *object;
    IDirectXFileEnumObject *dxfile_enum_object;
    void *dxfile_source;
    DXFILELOADOPTIONS dxfile_options;
    DXFILELOADRESOURCE dxfile_resource;
    DXFILELOADMEMORY dxfile_memory;
    IDirectXFileData *data_object;
    unsigned children_array_size = 0;
    HRESULT ret;

    TRACE("iface %p, source %p, options %#x, enum_object %p.\n", iface, source, options, enum_object);

    if (!enum_object)
        return E_POINTER;

    *enum_object = NULL;

    if (options == D3DXF_FILELOAD_FROMFILE)
    {
        dxfile_source = (void*)source;
        dxfile_options = DXFILELOAD_FROMFILE;
    }
    else if (options == D3DXF_FILELOAD_FROMRESOURCE)
    {
        D3DXF_FILELOADRESOURCE *resource = (D3DXF_FILELOADRESOURCE*)source;

        dxfile_resource.hModule = resource->hModule;
        dxfile_resource.lpName = resource->lpName;
        dxfile_resource.lpType = resource->lpType;
        dxfile_source = &dxfile_resource;
        dxfile_options = DXFILELOAD_FROMRESOURCE;
    }
    else if (options == D3DXF_FILELOAD_FROMMEMORY)
    {
        D3DXF_FILELOADMEMORY *memory = (D3DXF_FILELOADMEMORY*)source;

        dxfile_memory.lpMemory = memory->lpMemory;
        dxfile_memory.dSize = memory->dSize;
        dxfile_source = &dxfile_memory;
        dxfile_options = DXFILELOAD_FROMMEMORY;
    }
    else
    {
        FIXME("Source type %u is not handled yet\n", options);
        return E_NOTIMPL;
    }

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

    object->ID3DXFileEnumObject_iface.lpVtbl = &d3dx9_file_enum_object_vtbl;
    object->ref = 1;

    ret = IDirectXFile_CreateEnumObject(file->dxfile, dxfile_source, dxfile_options, &dxfile_enum_object);

    if (ret != S_OK)
    {
        HeapFree(GetProcessHeap(), 0, object);
        return ret;
    }

    /* Fill enum object with top level data objects */
    while (SUCCEEDED(ret = IDirectXFileEnumObject_GetNextDataObject(dxfile_enum_object, &data_object)))
    {
        if (object->nb_children >= children_array_size)
        {
            ID3DXFileData **new_children;

            if (object->children)
            {
                children_array_size *= 2;
                new_children = HeapReAlloc(GetProcessHeap(), 0, object->children,
                        sizeof(*object->children) * children_array_size);
            }
            else
            {
                children_array_size = 4;
                new_children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children) * children_array_size);
            }
            if (!new_children)
            {
                ret = E_OUTOFMEMORY;
                break;
            }
            object->children = new_children;
        }
        ret = d3dx9_file_data_create((IDirectXFileObject*)data_object,
                &object->children[object->nb_children]);
        IUnknown_Release(data_object);
        if (FAILED(ret))
            break;
        object->nb_children++;
    }
    if (object->children)
    {
        ID3DXFileData **new_children;

        new_children = HeapReAlloc(GetProcessHeap(), 0, object->children,
                sizeof(*object->children) * object->nb_children);
        if (new_children)
            object->children = new_children;
    }

    IDirectXFileEnumObject_Release(dxfile_enum_object);

    if (ret != DXFILEERR_NOMOREOBJECTS)
        WARN("Cannot get all top level data objects\n");

    TRACE("Found %u children\n", object->nb_children);

    *enum_object = &object->ID3DXFileEnumObject_iface;

    return S_OK;
}

static HRESULT WINAPI d3dx9_file_CreateSaveObject(ID3DXFile *iface, const void *data,
        D3DXF_FILESAVEOPTIONS options, D3DXF_FILEFORMAT format, ID3DXFileSaveObject **save_object)
{
    FIXME("iface %p, data %p, options %#x, format %#x, save_object %p stub!\n",
            iface, data, options, format, save_object);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3dx9_file_RegisterTemplates(ID3DXFile *iface, const void *data, SIZE_T size)
{
    struct d3dx9_file *file = impl_from_ID3DXFile(iface);
    HRESULT ret;

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

    ret = IDirectXFile_RegisterTemplates(file->dxfile, (void *)data, size);
    if (ret != DXFILE_OK)
    {
        WARN("Error %#x\n", ret);
        return error_dxfile_to_d3dxfile(ret);
    }

    return S_OK;
}

static HRESULT WINAPI d3dx9_file_RegisterEnumTemplates(ID3DXFile *iface, ID3DXFileEnumObject *enum_object)
{
    FIXME("iface %p, enum_object %p stub!\n", iface, enum_object);

    return E_NOTIMPL;
}

static const ID3DXFileVtbl d3dx9_file_vtbl =
{
    d3dx9_file_QueryInterface,
    d3dx9_file_AddRef,
    d3dx9_file_Release,
    d3dx9_file_CreateEnumObject,
    d3dx9_file_CreateSaveObject,
    d3dx9_file_RegisterTemplates,
    d3dx9_file_RegisterEnumTemplates,
};

HRESULT WINAPI D3DXFileCreate(ID3DXFile **d3dxfile)
{
    struct d3dx9_file *object;
    HRESULT ret;

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

    if (!d3dxfile)
        return E_POINTER;

    *d3dxfile = NULL;

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

    ret = DirectXFileCreate(&object->dxfile);
    if (ret != S_OK)
    {
        HeapFree(GetProcessHeap(), 0, object);
        if (ret == E_OUTOFMEMORY)
            return ret;
        return E_FAIL;
    }

    object->ID3DXFile_iface.lpVtbl = &d3dx9_file_vtbl;
    object->ref = 1;

    *d3dxfile = &object->ID3DXFile_iface;

    return S_OK;
}
