/*
 * Skin Info operations specific to D3DX9.
 *
 * Copyright (C) 2011 Dylan Smith
 *
 * 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"
#include "d3dx9_36_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3dx);

struct bone
{
    char *name;
    D3DXMATRIX transform;
    DWORD num_influences;
    DWORD *vertices;
    FLOAT *weights;
};

typedef struct ID3DXSkinInfoImpl
{
    ID3DXSkinInfo ID3DXSkinInfo_iface;
    LONG ref;

    DWORD fvf;
    D3DVERTEXELEMENT9 vertex_declaration[MAX_FVF_DECL_SIZE];
    DWORD num_vertices;
    DWORD num_bones;
    struct bone *bones;
} ID3DXSkinInfoImpl;

static inline struct ID3DXSkinInfoImpl *impl_from_ID3DXSkinInfo(ID3DXSkinInfo *iface)
{
    return CONTAINING_RECORD(iface, struct ID3DXSkinInfoImpl, ID3DXSkinInfo_iface);
}

static HRESULT WINAPI ID3DXSkinInfoImpl_QueryInterface(ID3DXSkinInfo *iface, REFIID riid, void **ppobj)
{
    TRACE("(%p, %s, %p)\n", iface, debugstr_guid(riid), ppobj);

    if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ID3DXSkinInfo))
    {
        IUnknown_AddRef(iface);
        *ppobj = iface;
        return D3D_OK;
    }

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

    return E_NOINTERFACE;
}

static ULONG WINAPI ID3DXSkinInfoImpl_AddRef(ID3DXSkinInfo *iface)
{
    struct ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("%p increasing refcount to %u\n", This, ref);

    return ref;
}

static ULONG WINAPI ID3DXSkinInfoImpl_Release(ID3DXSkinInfo *iface)
{
    struct ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("%p decreasing refcount to %u\n", This, ref);

    if (ref == 0) {
        int i;
        for (i = 0; i < This->num_bones; i++) {
            HeapFree(GetProcessHeap(), 0, This->bones[i].name);
            HeapFree(GetProcessHeap(), 0, This->bones[i].vertices);
            HeapFree(GetProcessHeap(), 0, This->bones[i].weights);
        }
        HeapFree(GetProcessHeap(), 0, This->bones);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_SetBoneInfluence(ID3DXSkinInfo *iface, DWORD bone_num, DWORD num_influences, CONST DWORD *vertices, CONST FLOAT *weights)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);
    struct bone *bone;
    DWORD *new_vertices = NULL;
    FLOAT *new_weights = NULL;

    TRACE("(%p, %u, %u, %p, %p)\n", This, bone_num, num_influences, vertices, weights);

    if (bone_num >= This->num_bones || !vertices || !weights)
        return D3DERR_INVALIDCALL;

    if (num_influences) {
        new_vertices = HeapAlloc(GetProcessHeap(), 0, num_influences * sizeof(*vertices));
        if (!new_vertices)
            return E_OUTOFMEMORY;
        new_weights = HeapAlloc(GetProcessHeap(), 0, num_influences * sizeof(*weights));
        if (!new_weights) {
            HeapFree(GetProcessHeap(), 0, new_vertices);
            return E_OUTOFMEMORY;
        }
        memcpy(new_vertices, vertices, num_influences * sizeof(*vertices));
        memcpy(new_weights, weights, num_influences * sizeof(*weights));
    }
    bone = &This->bones[bone_num];
    bone->num_influences = num_influences;
    HeapFree(GetProcessHeap(), 0, bone->vertices);
    HeapFree(GetProcessHeap(), 0, bone->weights);
    bone->vertices = new_vertices;
    bone->weights = new_weights;

    return D3D_OK;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_SetBoneVertexInfluence(ID3DXSkinInfo *iface, DWORD bone_num, DWORD influence_num, float weight)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %u, %u, %g): stub\n", This, bone_num, influence_num, weight);

    return E_NOTIMPL;
}

static DWORD WINAPI ID3DXSkinInfoImpl_GetNumBoneInfluences(ID3DXSkinInfo *iface, DWORD bone_num)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    TRACE("(%p, %u)\n", This, bone_num);

    if (bone_num >= This->num_bones)
        return 0;

    return This->bones[bone_num].num_influences;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_GetBoneInfluence(ID3DXSkinInfo *iface, DWORD bone_num, DWORD *vertices, FLOAT *weights)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);
    struct bone *bone;

    TRACE("(%p, %u, %p, %p)\n", This, bone_num, vertices, weights);

    if (bone_num >= This->num_bones || !vertices)
        return D3DERR_INVALIDCALL;

    bone = &This->bones[bone_num];
    if (!bone->num_influences)
        return D3D_OK;

    memcpy(vertices, bone->vertices, bone->num_influences * sizeof(*vertices));
    if (weights)
        memcpy(weights, bone->weights, bone->num_influences * sizeof(*weights));

    return D3D_OK;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_GetBoneVertexInfluence(ID3DXSkinInfo *iface, DWORD bone_num,
        DWORD influence_num, float *weight, DWORD *vertex_num)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %u, %u, %p, %p): stub\n", This, bone_num, influence_num, weight, vertex_num);

    return E_NOTIMPL;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_GetMaxVertexInfluences(ID3DXSkinInfo *iface, DWORD *max_vertex_influences)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %p): stub\n", This, max_vertex_influences);

    return E_NOTIMPL;
}

static DWORD WINAPI ID3DXSkinInfoImpl_GetNumBones(ID3DXSkinInfo *iface)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    TRACE("(%p)\n", This);

    return This->num_bones;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_FindBoneVertexInfluenceIndex(ID3DXSkinInfo *iface, DWORD bone_num,
        DWORD vertex_num, DWORD *influence_index)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %u, %u, %p): stub\n", This, bone_num, vertex_num, influence_index);

    return E_NOTIMPL;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_GetMaxFaceInfluences(ID3DXSkinInfo *iface, LPDIRECT3DINDEXBUFFER9 index_buffer, DWORD num_faces, DWORD *max_face_influences)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %p, %u, %p): stub\n", This, index_buffer, num_faces, max_face_influences);

    return E_NOTIMPL;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_SetMinBoneInfluence(ID3DXSkinInfo *iface, FLOAT min_influence)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %g): stub\n", This, min_influence);

    return E_NOTIMPL;
}

static FLOAT WINAPI ID3DXSkinInfoImpl_GetMinBoneInfluence(ID3DXSkinInfo *iface)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p): stub\n", This);

    return 0.0f;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_SetBoneName(ID3DXSkinInfo *iface, DWORD bone_num, LPCSTR name)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);
    char *new_name;
    size_t size;

    TRACE("(%p, %u, %s)\n", This, bone_num, debugstr_a(name));

    if (bone_num >= This->num_bones || !name)
        return D3DERR_INVALIDCALL;

    size = strlen(name) + 1;
    new_name = HeapAlloc(GetProcessHeap(), 0, size);
    if (!new_name)
        return E_OUTOFMEMORY;
    memcpy(new_name, name, size);
    HeapFree(GetProcessHeap(), 0, This->bones[bone_num].name);
    This->bones[bone_num].name = new_name;

    return D3D_OK;
}

static LPCSTR WINAPI ID3DXSkinInfoImpl_GetBoneName(ID3DXSkinInfo *iface, DWORD bone_num)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    TRACE("(%p, %u)\n", This, bone_num);

    if (bone_num >= This->num_bones)
        return NULL;

    return This->bones[bone_num].name;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_SetBoneOffsetMatrix(ID3DXSkinInfo *iface, DWORD bone_num, CONST D3DXMATRIX *bone_transform)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    TRACE("(%p, %u, %p)\n", This, bone_num, bone_transform);

    if (bone_num >= This->num_bones || !bone_transform)
        return D3DERR_INVALIDCALL;

    This->bones[bone_num].transform = *bone_transform;
    return D3D_OK;
}

static LPD3DXMATRIX WINAPI ID3DXSkinInfoImpl_GetBoneOffsetMatrix(ID3DXSkinInfo *iface, DWORD bone_num)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    TRACE("(%p, %u)\n", This, bone_num);

    if (bone_num >= This->num_bones)
        return NULL;

    return &This->bones[bone_num].transform;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_Clone(ID3DXSkinInfo *iface, LPD3DXSKININFO *skin_info)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %p): stub\n", This, skin_info);

    return E_NOTIMPL;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_Remap(ID3DXSkinInfo *iface, DWORD num_vertices, DWORD *vertex_remap)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %u, %p): stub\n", This, num_vertices, vertex_remap);

    return E_NOTIMPL;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_SetFVF(ID3DXSkinInfo *iface, DWORD fvf)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);
    HRESULT hr;
    D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE];

    TRACE("(%p, %x)\n", This, fvf);

    hr = D3DXDeclaratorFromFVF(fvf, declaration);
    if (FAILED(hr)) return hr;

    return iface->lpVtbl->SetDeclaration(iface, declaration);
}

static HRESULT WINAPI ID3DXSkinInfoImpl_SetDeclaration(ID3DXSkinInfo *iface, CONST D3DVERTEXELEMENT9 *declaration)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);
    HRESULT hr;
    int count;

    TRACE("(%p, %p)\n", This, declaration);

    if (!declaration)
        return D3DERR_INVALIDCALL;
    for (count = 0; declaration[count].Stream != 0xff; count++) {
        if (declaration[count].Stream != 0) {
            WARN("Invalid vertex element %u; contains non-zero stream %u\n",
                 count, declaration[count].Stream);
            return D3DERR_INVALIDCALL;
        }
    }
    count++;

    memcpy(This->vertex_declaration, declaration, count * sizeof(*declaration));

    hr = D3DXFVFFromDeclarator(This->vertex_declaration, &This->fvf);
    if (FAILED(hr))
        This->fvf = 0;

    return D3D_OK;
}

static DWORD WINAPI ID3DXSkinInfoImpl_GetFVF(ID3DXSkinInfo *iface)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    TRACE("(%p)\n", This);

    return This->fvf;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_GetDeclaration(ID3DXSkinInfo *iface, D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE])
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);
    UINT count = 0;

    TRACE("(%p)\n", This);

    while (This->vertex_declaration[count++].Stream != 0xff);
    memcpy(declaration, This->vertex_declaration, count * sizeof(declaration[0]));
    return D3D_OK;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_UpdateSkinnedMesh(ID3DXSkinInfo *iface, CONST D3DXMATRIX *bone_transforms,
        CONST D3DXMATRIX *bone_inv_transpose_transforms, LPCVOID vertices_src, PVOID vertices_dest)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %p, %p, %p, %p): stub\n", This, bone_transforms, bone_inv_transpose_transforms, vertices_src, vertices_dest);

    return E_NOTIMPL;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_ConvertToBlendedMesh(ID3DXSkinInfo *iface, LPD3DXMESH mesh_in,
        DWORD options, CONST DWORD *adjacency_in, LPDWORD adjacency_out, DWORD *face_remap,
        LPD3DXBUFFER *vertex_remap, DWORD *max_face_infl, DWORD *num_bone_combinations,
        LPD3DXBUFFER *bone_combination_table, LPD3DXMESH *mesh_out)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %p, %x, %p, %p, %p, %p, %p, %p, %p, %p): stub\n",
          This, mesh_in, options, adjacency_in, adjacency_out, face_remap, vertex_remap,
          max_face_infl, num_bone_combinations, bone_combination_table, mesh_out);

    return E_NOTIMPL;
}

static HRESULT WINAPI ID3DXSkinInfoImpl_ConvertToIndexedBlendedMesh(ID3DXSkinInfo *iface, LPD3DXMESH mesh_in,
        DWORD options, CONST DWORD *adjacency_in, LPDWORD adjacency_out, DWORD *face_remap,
        LPD3DXBUFFER *vertex_remap, DWORD *max_face_infl, DWORD *num_bone_combinations,
        LPD3DXBUFFER *bone_combination_table, LPD3DXMESH *mesh_out)
{
    ID3DXSkinInfoImpl *This = impl_from_ID3DXSkinInfo(iface);

    FIXME("(%p, %p, %x, %p, %p, %p, %p, %p, %p, %p, %p): stub\n",
          This, mesh_in, options, adjacency_in, adjacency_out, face_remap, vertex_remap,
          max_face_infl, num_bone_combinations, bone_combination_table, mesh_out);

    return E_NOTIMPL;
}

static const struct ID3DXSkinInfoVtbl ID3DXSkinInfoImpl_Vtbl =
{
    /* IUnknown methods */
    ID3DXSkinInfoImpl_QueryInterface,
    ID3DXSkinInfoImpl_AddRef,
    ID3DXSkinInfoImpl_Release,
    /* ID3DXSkinInfo */
    ID3DXSkinInfoImpl_SetBoneInfluence,
    ID3DXSkinInfoImpl_SetBoneVertexInfluence,
    ID3DXSkinInfoImpl_GetNumBoneInfluences,
    ID3DXSkinInfoImpl_GetBoneInfluence,
    ID3DXSkinInfoImpl_GetBoneVertexInfluence,
    ID3DXSkinInfoImpl_GetMaxVertexInfluences,
    ID3DXSkinInfoImpl_GetNumBones,
    ID3DXSkinInfoImpl_FindBoneVertexInfluenceIndex,
    ID3DXSkinInfoImpl_GetMaxFaceInfluences,
    ID3DXSkinInfoImpl_SetMinBoneInfluence,
    ID3DXSkinInfoImpl_GetMinBoneInfluence,
    ID3DXSkinInfoImpl_SetBoneName,
    ID3DXSkinInfoImpl_GetBoneName,
    ID3DXSkinInfoImpl_SetBoneOffsetMatrix,
    ID3DXSkinInfoImpl_GetBoneOffsetMatrix,
    ID3DXSkinInfoImpl_Clone,
    ID3DXSkinInfoImpl_Remap,
    ID3DXSkinInfoImpl_SetFVF,
    ID3DXSkinInfoImpl_SetDeclaration,
    ID3DXSkinInfoImpl_GetFVF,
    ID3DXSkinInfoImpl_GetDeclaration,
    ID3DXSkinInfoImpl_UpdateSkinnedMesh,
    ID3DXSkinInfoImpl_ConvertToBlendedMesh,
    ID3DXSkinInfoImpl_ConvertToIndexedBlendedMesh
};

HRESULT WINAPI D3DXCreateSkinInfo(DWORD num_vertices, CONST D3DVERTEXELEMENT9 *declaration,
                                  DWORD num_bones, LPD3DXSKININFO *skin_info)
{
    HRESULT hr;
    ID3DXSkinInfoImpl *object = NULL;
    static const D3DVERTEXELEMENT9 empty_declaration = D3DDECL_END();

    TRACE("(%u, %p, %u, %p)\n", num_vertices, declaration, num_bones, skin_info);

    if (!skin_info || !declaration)
        return D3DERR_INVALIDCALL;

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

    object->ID3DXSkinInfo_iface.lpVtbl = &ID3DXSkinInfoImpl_Vtbl;
    object->ref = 1;
    object->num_vertices = num_vertices;
    object->num_bones = num_bones;
    object->vertex_declaration[0] = empty_declaration;
    object->fvf = 0;

    object->bones = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, num_bones * sizeof(*object->bones));
    if (!object->bones) {
        hr = E_OUTOFMEMORY;
        goto error;
    }

    hr = ID3DXSkinInfoImpl_SetDeclaration(&object->ID3DXSkinInfo_iface, declaration);
    if (FAILED(hr)) goto error;

    *skin_info = &object->ID3DXSkinInfo_iface;

    return D3D_OK;
error:
    HeapFree(GetProcessHeap(), 0, object->bones);
    HeapFree(GetProcessHeap(), 0, object);
    return hr;
}

HRESULT WINAPI D3DXCreateSkinInfoFVF(DWORD num_vertices, DWORD fvf, DWORD num_bones, LPD3DXSKININFO *skin_info)
{
    HRESULT hr;
    D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE];

    TRACE("(%u, %x, %u, %p)\n", num_vertices, fvf, num_bones, skin_info);

    hr = D3DXDeclaratorFromFVF(fvf, declaration);
    if (FAILED(hr))
        return hr;

    return D3DXCreateSkinInfo(num_vertices, declaration, num_bones, skin_info);
}
