/*
 *    ParseError implementation
 *
 * Copyright 2005 Huw Davies
 *
 * 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 "winerror.h"
#include "winuser.h"
#include "ole2.h"
#include "msxml6.h"

#include "msxml_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(msxml);

typedef struct
{
    IXMLDOMParseError IXMLDOMParseError_iface;
    LONG ref;
    LONG code, line, linepos, filepos;
    BSTR url, reason, srcText;
} parse_error_t;

static inline parse_error_t *impl_from_IXMLDOMParseError( IXMLDOMParseError *iface )
{
    return CONTAINING_RECORD(iface, parse_error_t, IXMLDOMParseError_iface);
}

static HRESULT WINAPI parseError_QueryInterface(
    IXMLDOMParseError *iface,
    REFIID riid,
    void** ppvObject )
{
    TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);

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

    IXMLDOMParseError_AddRef( iface );

    return S_OK;
}

static ULONG WINAPI parseError_AddRef(
    IXMLDOMParseError *iface )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    ULONG ref = InterlockedIncrement( &This->ref );
    TRACE("(%p) ref now %d\n", This, ref);
    return ref;
}

static ULONG WINAPI parseError_Release(
    IXMLDOMParseError *iface )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    ULONG ref;

    ref = InterlockedDecrement( &This->ref );
    TRACE("(%p) ref now %d\n", This, ref);
    if ( ref == 0 )
    {
        SysFreeString(This->url);
        SysFreeString(This->reason);
        SysFreeString(This->srcText);
        heap_free( This );
    }

    return ref;
}

static HRESULT WINAPI parseError_GetTypeInfoCount(
    IXMLDOMParseError *iface,
    UINT* pctinfo )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );

    TRACE("(%p)->(%p)\n", This, pctinfo);

    *pctinfo = 1;

    return S_OK;
}

static HRESULT WINAPI parseError_GetTypeInfo(
    IXMLDOMParseError *iface,
    UINT iTInfo,
    LCID lcid,
    ITypeInfo** ppTInfo )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    HRESULT hr;

    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);

    hr = get_typeinfo(IXMLDOMParseError_tid, ppTInfo);

    return hr;
}

static HRESULT WINAPI parseError_GetIDsOfNames(
    IXMLDOMParseError *iface,
    REFIID riid,
    LPOLESTR* rgszNames,
    UINT cNames,
    LCID lcid,
    DISPID* rgDispId )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
          lcid, rgDispId);

    if(!rgszNames || cNames == 0 || !rgDispId)
        return E_INVALIDARG;

    hr = get_typeinfo(IXMLDOMParseError_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI parseError_Invoke(
    IXMLDOMParseError *iface,
    DISPID dispIdMember,
    REFIID riid,
    LCID lcid,
    WORD wFlags,
    DISPPARAMS* pDispParams,
    VARIANT* pVarResult,
    EXCEPINFO* pExcepInfo,
    UINT* puArgErr )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
          lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IXMLDOMParseError_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, &This->IXMLDOMParseError_iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI parseError_get_errorCode(
    IXMLDOMParseError *iface,
    LONG *code )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    TRACE("(%p)->(%p)\n", This, code);

    *code = This->code;

    if(This->code == 0)
        return S_FALSE;

    return S_OK;
}

static HRESULT WINAPI parseError_get_url(
    IXMLDOMParseError *iface,
    BSTR *url )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    FIXME("(%p)->(%p)\n", This, url);
    return E_NOTIMPL;
}

static HRESULT WINAPI parseError_get_reason(
    IXMLDOMParseError *iface,
    BSTR *reason )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    TRACE("(%p)->(%p)\n", This, reason);
    
    if(!This->reason)
    {
        *reason = NULL;
        return S_FALSE;
    }
    *reason = SysAllocString(This->reason);
    return S_OK;
}

static HRESULT WINAPI parseError_get_srcText(
    IXMLDOMParseError *iface,
    BSTR *srcText )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    FIXME("(%p)->(%p)\n", This, srcText);
    return E_NOTIMPL;
}

static HRESULT WINAPI parseError_get_line(
    IXMLDOMParseError *iface,
    LONG *line )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    FIXME("(%p)->(%p)\n", This, line);
    return E_NOTIMPL;
}

static HRESULT WINAPI parseError_get_linepos(
    IXMLDOMParseError *iface,
    LONG *linepos )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    FIXME("(%p)->(%p)\n", This, linepos);
    return E_NOTIMPL;
}

static HRESULT WINAPI parseError_get_filepos(
    IXMLDOMParseError *iface,
    LONG *filepos )
{
    parse_error_t *This = impl_from_IXMLDOMParseError( iface );
    FIXME("(%p)->(%p)\n", This, filepos);
    return E_NOTIMPL;
}

static const struct IXMLDOMParseErrorVtbl parseError_vtbl =
{
    parseError_QueryInterface,
    parseError_AddRef,
    parseError_Release,
    parseError_GetTypeInfoCount,
    parseError_GetTypeInfo,
    parseError_GetIDsOfNames,
    parseError_Invoke,
    parseError_get_errorCode,
    parseError_get_url,
    parseError_get_reason,
    parseError_get_srcText,
    parseError_get_line,
    parseError_get_linepos,
    parseError_get_filepos
};

IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText,
                                      LONG line, LONG linepos, LONG filepos )
{
    parse_error_t *This;

    This = heap_alloc( sizeof(*This) );
    if ( !This )
        return NULL;

    This->IXMLDOMParseError_iface.lpVtbl = &parseError_vtbl;
    This->ref = 1;

    This->code = code;
    This->url = url;
    This->reason = reason;
    This->srcText = srcText;
    This->line = line;
    This->linepos = linepos;
    This->filepos = filepos;

    return &This->IXMLDOMParseError_iface;
}
