/*
 * XML Element implementation
 *
 * Copyright 2007 James Hawkins
 *
 * 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
 */

#define COBJMACROS

#include "config.h"

#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "msxml2.h"
#include "ocidl.h"

#include "wine/debug.h"

#include "msxml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(msxml);

#ifdef HAVE_LIBXML2

/**********************************************************************
 * IXMLElement
 */
typedef struct _xmlelem
{
    const IXMLElementVtbl *lpVtbl;
    LONG ref;
    xmlNodePtr node;
} xmlelem;

static inline xmlelem *impl_from_IXMLElement(IXMLElement *iface)
{
    return (xmlelem *)((char*)iface - FIELD_OFFSET(xmlelem, lpVtbl));
}

static HRESULT WINAPI xmlelem_QueryInterface(IXMLElement *iface, REFIID riid, void** ppvObject)
{
    xmlelem *This = impl_from_IXMLElement(iface);

    TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);

    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IXMLElement))
    {
        *ppvObject = iface;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IXMLElement_AddRef(iface);

    return S_OK;
}

static ULONG WINAPI xmlelem_AddRef(IXMLElement *iface)
{
    xmlelem *This = impl_from_IXMLElement(iface);
    TRACE("%p\n", This);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI xmlelem_Release(IXMLElement *iface)
{
    xmlelem *This = impl_from_IXMLElement(iface);
    LONG ref;

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

    ref = InterlockedDecrement(&This->ref);
    if (ref == 0)
    {
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI xmlelem_GetTypeInfoCount(IXMLElement *iface, UINT* pctinfo)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI xmlelem_GetTypeInfo(IXMLElement *iface, UINT iTInfo,
                                          LCID lcid, ITypeInfo** ppTInfo)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI xmlelem_GetIDsOfNames(IXMLElement *iface, REFIID riid,
                                            LPOLESTR* rgszNames, UINT cNames,
                                            LCID lcid, DISPID* rgDispId)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI xmlelem_Invoke(IXMLElement *iface, DISPID dispIdMember,
                                     REFIID riid, LCID lcid, WORD wFlags,
                                     DISPPARAMS* pDispParams, VARIANT* pVarResult,
                                     EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static inline BSTR str_dup_upper(BSTR str)
{
    INT len = (lstrlenW(str) + 1) * sizeof(WCHAR);
    BSTR p = SysAllocStringLen(NULL, len);
    if (p)
    {
        memcpy(p, str, len);
        CharUpperW(p);
    }
    return p;
}

static HRESULT WINAPI xmlelem_get_tagName(IXMLElement *iface, BSTR *p)
{
    xmlelem *This = impl_from_IXMLElement(iface);
    BSTR temp;

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

    if (!p)
        return E_INVALIDARG;

    temp = bstr_from_xmlChar(This->node->name);
    *p = str_dup_upper(temp);
    SysFreeString(temp);

    TRACE("returning %s\n", debugstr_w(*p));

    return S_OK;
}

static HRESULT WINAPI xmlelem_put_tagName(IXMLElement *iface, BSTR p)
{
    FIXME("(%p, %p): stub\n", iface, p);

    if (!p)
        return E_INVALIDARG;

    return E_NOTIMPL;
}

static HRESULT WINAPI xmlelem_get_parent(IXMLElement *iface, IXMLElement **parent)
{
    xmlelem *This = impl_from_IXMLElement(iface);

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

    if (!parent)
        return E_INVALIDARG;

    *parent = NULL;

    if (!This->node->parent)
        return S_FALSE;

    return XMLElement_create((IUnknown *)iface, This->node->parent, (LPVOID *)parent);
}

static HRESULT WINAPI xmlelem_setAttribute(IXMLElement *iface, BSTR strPropertyName,
                                            VARIANT PropertyValue)
{
    xmlelem *This = impl_from_IXMLElement(iface);
    xmlChar *name, *value;
    xmlAttrPtr attr;

    TRACE("(%p, %s)\n", iface, debugstr_w(strPropertyName));

    if (!strPropertyName || V_VT(&PropertyValue) != VT_BSTR)
        return E_INVALIDARG;

    name = xmlChar_from_wchar(strPropertyName);
    value = xmlChar_from_wchar(V_BSTR(&PropertyValue));
    attr = xmlSetProp(This->node, name, value);

    HeapFree(GetProcessHeap(), 0, name);
    HeapFree(GetProcessHeap(), 0, value);
    return (attr) ? S_OK : S_FALSE;
}

static HRESULT WINAPI xmlelem_getAttribute(IXMLElement *iface, BSTR strPropertyName,
                                           VARIANT *PropertyValue)
{
    xmlelem *This = impl_from_IXMLElement(iface);
    xmlChar *val = NULL, *name;
    xmlAttrPtr ptr;

    TRACE("(%p, %s, %p)\n", iface, debugstr_w(strPropertyName), PropertyValue);

    if (!PropertyValue)
        return E_INVALIDARG;

    VariantInit(PropertyValue);
    V_BSTR(PropertyValue) = NULL;

    if (!strPropertyName)
        return E_INVALIDARG;

    name = xmlChar_from_wchar(strPropertyName);
    ptr = This->node->properties;
    while (ptr)
    {
        if (!lstrcmpiA((LPSTR)name, (LPCSTR)ptr->name))
        {
            val = xmlNodeListGetString(ptr->doc, ptr->children, 1);
            break;
        }

        ptr = ptr->next;
    }

    if (val)
    {
        V_VT(PropertyValue) = VT_BSTR;
        V_BSTR(PropertyValue) = bstr_from_xmlChar(val);
    }

    HeapFree(GetProcessHeap(), 0, name);
    xmlFree(val);
    TRACE("returning %s\n", debugstr_w(V_BSTR(PropertyValue)));
    return (val) ? S_OK : S_FALSE;
}

static HRESULT WINAPI xmlelem_removeAttribute(IXMLElement *iface, BSTR strPropertyName)
{
    xmlelem *This = impl_from_IXMLElement(iface);
    xmlChar *name;
    xmlAttrPtr attr;
    int res;
    HRESULT hr = S_FALSE;

    TRACE("(%p, %s)\n", iface, debugstr_w(strPropertyName));

    if (!strPropertyName)
        return E_INVALIDARG;

    name = xmlChar_from_wchar(strPropertyName);
    attr = xmlHasProp(This->node, name);
    if (!attr)
        goto done;

    res = xmlRemoveProp(attr);

    if (res == 0)
        hr = S_OK;

done:
    HeapFree(GetProcessHeap(), 0, name);
    return hr;
}

static HRESULT WINAPI xmlelem_get_children(IXMLElement *iface, IXMLElementCollection **p)
{
    xmlelem *This = impl_from_IXMLElement(iface);

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

    if (!p)
        return E_INVALIDARG;

    return XMLElementCollection_create((IUnknown *)iface, This->node->children, (LPVOID *)p);
}

static long type_libxml_to_msxml(xmlElementType type)
{
    switch (type)
    {
        case XML_ELEMENT_NODE:
            return XMLELEMTYPE_ELEMENT;
        case XML_TEXT_NODE:
            return XMLELEMTYPE_TEXT;
        case XML_COMMENT_NODE:
            return XMLELEMTYPE_COMMENT;
        case XML_DOCUMENT_NODE:
            return XMLELEMTYPE_DOCUMENT;
        case XML_DTD_NODE:
            return XMLELEMTYPE_DTD;
        case XML_PI_NODE:
            return XMLELEMTYPE_PI;
        default:
            break;
    }

    return XMLELEMTYPE_OTHER;
}

static HRESULT WINAPI xmlelem_get_type(IXMLElement *iface, long *p)
{
    xmlelem *This = impl_from_IXMLElement(iface);

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

    if (!p)
        return E_INVALIDARG;

    *p = type_libxml_to_msxml(This->node->type);
    TRACE("returning %ld\n", *p);
    return S_OK;
}

static HRESULT WINAPI xmlelem_get_text(IXMLElement *iface, BSTR *p)
{
    xmlelem *This = impl_from_IXMLElement(iface);
    xmlChar *content;

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

    if (!p)
        return E_INVALIDARG;

    content = xmlNodeGetContent(This->node);
    *p = bstr_from_xmlChar(content);
    TRACE("returning %s\n", debugstr_w(*p));

    xmlFree(content);
    return S_OK;
}

static HRESULT WINAPI xmlelem_put_text(IXMLElement *iface, BSTR p)
{
    xmlelem *This = impl_from_IXMLElement(iface);
    xmlChar *content;

    TRACE("(%p, %s)\n", iface, debugstr_w(p));

    /* FIXME: test which types can be used */
    if (This->node->type == XML_ELEMENT_NODE)
        return E_NOTIMPL;

    content = xmlChar_from_wchar(p);
    xmlNodeSetContent(This->node, content);

    HeapFree( GetProcessHeap(), 0, content);

    return S_OK;
}

static HRESULT WINAPI xmlelem_addChild(IXMLElement *iface, IXMLElement *pChildElem,
                                        long lIndex, long lreserved)
{
    xmlelem *This = impl_from_IXMLElement(iface);
    xmlelem *childElem = impl_from_IXMLElement(pChildElem);
    xmlNodePtr child;

    TRACE("(%p, %p, %ld, %ld)\n", iface, pChildElem, lIndex, lreserved);

    if (lIndex == 0)
        child = xmlAddChild(This->node, childElem->node);
    else
        child = xmlAddNextSibling(This->node, childElem->node->last);

    return (child) ? S_OK : S_FALSE;
}

static HRESULT WINAPI xmlelem_removeChild(IXMLElement *iface, IXMLElement *pChildElem)
{
    FIXME("(%p, %p): stub\n", iface, pChildElem);
    return E_NOTIMPL;
}

static const struct IXMLElementVtbl xmlelem_vtbl =
{
    xmlelem_QueryInterface,
    xmlelem_AddRef,
    xmlelem_Release,
    xmlelem_GetTypeInfoCount,
    xmlelem_GetTypeInfo,
    xmlelem_GetIDsOfNames,
    xmlelem_Invoke,
    xmlelem_get_tagName,
    xmlelem_put_tagName,
    xmlelem_get_parent,
    xmlelem_setAttribute,
    xmlelem_getAttribute,
    xmlelem_removeAttribute,
    xmlelem_get_children,
    xmlelem_get_type,
    xmlelem_get_text,
    xmlelem_put_text,
    xmlelem_addChild,
    xmlelem_removeChild
};

HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj)
{
    xmlelem *elem;

    TRACE("(%p,%p)\n", pUnkOuter, ppObj);

    if (!ppObj)
        return E_INVALIDARG;

    *ppObj = NULL;

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

    elem->lpVtbl = &xmlelem_vtbl;
    elem->ref = 1;
    elem->node = node;

    *ppObj = &elem->lpVtbl;

    TRACE("returning iface %p\n", *ppObj);
    return S_OK;
}

/************************************************************************
 * IXMLElementCollection
 */
typedef struct _xmlelem_collection
{
    const IXMLElementCollectionVtbl *lpVtbl;
    const IEnumVARIANTVtbl          *lpvtblIEnumVARIANT;
    LONG ref;
    LONG length;
    xmlNodePtr node;

    /* IEnumVARIANT members */
    xmlNodePtr current;
} xmlelem_collection;

static inline xmlelem_collection *impl_from_IXMLElementCollection(IXMLElementCollection *iface)
{
    return (xmlelem_collection *)((char*)iface - FIELD_OFFSET(xmlelem_collection, lpVtbl));
}

static inline xmlelem_collection *impl_from_IEnumVARIANT(IEnumVARIANT *iface)
{
    return (xmlelem_collection *)((char*)iface - FIELD_OFFSET(xmlelem_collection, lpvtblIEnumVARIANT));
}

static HRESULT WINAPI xmlelem_collection_QueryInterface(IXMLElementCollection *iface, REFIID riid, void** ppvObject)
{
    xmlelem_collection *This = impl_from_IXMLElementCollection(iface);

    TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);

    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IXMLElementCollection))
    {
        *ppvObject = iface;
    }
    else if (IsEqualGUID(riid, &IID_IEnumVARIANT))
    {
        *ppvObject = (IEnumVARIANT *)&(This->lpvtblIEnumVARIANT);
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IXMLElementCollection_AddRef(iface);

    return S_OK;
}

static ULONG WINAPI xmlelem_collection_AddRef(IXMLElementCollection *iface)
{
    xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
    TRACE("%p\n", This);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI xmlelem_collection_Release(IXMLElementCollection *iface)
{
    xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
    LONG ref;

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

    ref = InterlockedDecrement(&This->ref);
    if (ref == 0)
    {
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI xmlelem_collection_GetTypeInfoCount(IXMLElementCollection *iface, UINT* pctinfo)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI xmlelem_collection_GetTypeInfo(IXMLElementCollection *iface, UINT iTInfo,
                                                     LCID lcid, ITypeInfo** ppTInfo)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI xmlelem_collection_GetIDsOfNames(IXMLElementCollection *iface, REFIID riid,
                                                       LPOLESTR* rgszNames, UINT cNames,
                                                       LCID lcid, DISPID* rgDispId)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI xmlelem_collection_Invoke(IXMLElementCollection *iface, DISPID dispIdMember,
                                                REFIID riid, LCID lcid, WORD wFlags,
                                                DISPPARAMS* pDispParams, VARIANT* pVarResult,
                                                EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI xmlelem_collection_put_length(IXMLElementCollection *iface, long v)
{
    TRACE("(%p, %ld)\n", iface, v);
    return E_FAIL;
}

static HRESULT WINAPI xmlelem_collection_get_length(IXMLElementCollection *iface, long *p)
{
    xmlelem_collection *This = impl_from_IXMLElementCollection(iface);

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

    if (!p)
        return E_INVALIDARG;

    *p = This->length;
    return S_OK;
}

static HRESULT WINAPI xmlelem_collection_get__newEnum(IXMLElementCollection *iface, IUnknown **ppUnk)
{
    xmlelem_collection *This = impl_from_IXMLElementCollection(iface);

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

    if (!ppUnk)
        return E_INVALIDARG;

    *ppUnk = (IUnknown *)This;
    IUnknown_AddRef(*ppUnk);
    return S_OK;
}

static HRESULT WINAPI xmlelem_collection_item(IXMLElementCollection *iface, VARIANT var1,
                                              VARIANT var2, IDispatch **ppDisp)
{
    xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
    xmlNodePtr ptr = This->node;
    int index, i;

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

    if (!ppDisp)
        return E_INVALIDARG;

    *ppDisp = NULL;

    index = V_I4(&var1);
    if (index < 0)
        return E_INVALIDARG;
    if (index >= This->length)
        return E_FAIL;

    for (i = 0; i < index; i++)
        ptr = ptr->next;

    return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)ppDisp);
}

static const struct IXMLElementCollectionVtbl xmlelem_collection_vtbl =
{
    xmlelem_collection_QueryInterface,
    xmlelem_collection_AddRef,
    xmlelem_collection_Release,
    xmlelem_collection_GetTypeInfoCount,
    xmlelem_collection_GetTypeInfo,
    xmlelem_collection_GetIDsOfNames,
    xmlelem_collection_Invoke,
    xmlelem_collection_put_length,
    xmlelem_collection_get_length,
    xmlelem_collection_get__newEnum,
    xmlelem_collection_item
};

/************************************************************************
 * xmlelem_collection implementation of IEnumVARIANT.
 */
static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_QueryInterface(
    IEnumVARIANT *iface, REFIID riid, LPVOID *ppvObj)
{
    xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
    return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
}

static ULONG WINAPI xmlelem_collection_IEnumVARIANT_AddRef(
    IEnumVARIANT *iface)
{
    xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
    return IXMLDocument_AddRef((IXMLDocument *)this);
}

static ULONG WINAPI xmlelem_collection_IEnumVARIANT_Release(
    IEnumVARIANT *iface)
{
    xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
    return IXMLDocument_Release((IXMLDocument *)this);
}

static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next(
    IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
{
    xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
    xmlNodePtr ptr = This->current;

    TRACE("(%p, %d, %p, %p)\n", iface, celt, rgVar, pCeltFetched);

    if (!rgVar)
        return E_INVALIDARG;

    /* FIXME: handle celt */
    if (pCeltFetched)
        *pCeltFetched = 1;

    This->current = This->current->next;

    V_VT(rgVar) = VT_DISPATCH;
    return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)&V_DISPATCH(rgVar));
}

static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip(
    IEnumVARIANT *iface, ULONG celt)
{
    FIXME("(%p, %d): stub\n", iface, celt);
    return E_NOTIMPL;
}

static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Reset(
    IEnumVARIANT *iface)
{
    xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
    This->current = This->node;
    return S_OK;
}

static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Clone(
    IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
{
    FIXME("(%p, %p): stub\n", iface, ppEnum);
    return E_NOTIMPL;
}

static const struct IEnumVARIANTVtbl xmlelem_collection_IEnumVARIANTvtbl =
{
    xmlelem_collection_IEnumVARIANT_QueryInterface,
    xmlelem_collection_IEnumVARIANT_AddRef,
    xmlelem_collection_IEnumVARIANT_Release,
    xmlelem_collection_IEnumVARIANT_Next,
    xmlelem_collection_IEnumVARIANT_Skip,
    xmlelem_collection_IEnumVARIANT_Reset,
    xmlelem_collection_IEnumVARIANT_Clone
};

HRESULT XMLElementCollection_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj)
{
    xmlelem_collection *collection;
    xmlNodePtr ptr;

    TRACE("(%p,%p)\n", pUnkOuter, ppObj);

    *ppObj = NULL;

    if (!node)
        return S_FALSE;

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

    collection->lpVtbl = &xmlelem_collection_vtbl;
    collection->lpvtblIEnumVARIANT = &xmlelem_collection_IEnumVARIANTvtbl;
    collection->ref = 1;
    collection->length = 0;
    collection->node = node;
    collection->current = node;

    ptr = node;
    while (ptr)
    {
        collection->length++;
        ptr = ptr->next;
    }

    *ppObj = &collection->lpVtbl;

    TRACE("returning iface %p\n", *ppObj);
    return S_OK;
}

#endif
