/*
 * Copyright 2015 Alex Henrie
 *
 * 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 <stdarg.h>
#include <assert.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"

#include "wine/debug.h"

#include "mshtml_private.h"
#include "htmlevent.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

struct HTMLAreaElement {
    HTMLElement element;

    IHTMLAreaElement IHTMLAreaElement_iface;

    nsIDOMHTMLAreaElement *nsarea;
};

static inline HTMLAreaElement *impl_from_IHTMLAreaElement(IHTMLAreaElement *iface)
{
    return CONTAINING_RECORD(iface, HTMLAreaElement, IHTMLAreaElement_iface);
}

static HRESULT WINAPI HTMLAreaElement_QueryInterface(IHTMLAreaElement *iface, REFIID riid, void **ppv)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);

    return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
}

static ULONG WINAPI HTMLAreaElement_AddRef(IHTMLAreaElement *iface)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);

    return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
}

static ULONG WINAPI HTMLAreaElement_Release(IHTMLAreaElement *iface)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);

    return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
}

static HRESULT WINAPI HTMLAreaElement_GetTypeInfoCount(IHTMLAreaElement *iface, UINT *pctinfo)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo);
}

static HRESULT WINAPI HTMLAreaElement_GetTypeInfo(IHTMLAreaElement *iface, UINT iTInfo,
                                              LCID lcid, ITypeInfo **ppTInfo)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid,
            ppTInfo);
}

static HRESULT WINAPI HTMLAreaElement_GetIDsOfNames(IHTMLAreaElement *iface, REFIID riid,
                                                LPOLESTR *rgszNames, UINT cNames,
                                                LCID lcid, DISPID *rgDispId)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames,
            cNames, lcid, rgDispId);
}

static HRESULT WINAPI HTMLAreaElement_Invoke(IHTMLAreaElement *iface, DISPID dispIdMember,
                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid,
            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}

static HRESULT WINAPI HTMLAreaElement_put_shape(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_shape(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_coords(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_coords(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_href(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_href(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_target(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_target(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_alt(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_alt(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_noHref(IHTMLAreaElement *iface, VARIANT_BOOL v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%i)\n", This, v);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_noHref(IHTMLAreaElement *iface, VARIANT_BOOL *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_host(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_host(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_hostname(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_hostname(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_pathname(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_pathname(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_port(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_port(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_protocol(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_protocol(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_search(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_search(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_hash(IHTMLAreaElement *iface, BSTR v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_hash(IHTMLAreaElement *iface, BSTR *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_onblur(IHTMLAreaElement *iface, VARIANT v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, &v);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_onblur(IHTMLAreaElement *iface, VARIANT *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_onfocus(IHTMLAreaElement *iface, VARIANT v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, &v);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_onfocus(IHTMLAreaElement *iface, VARIANT *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_put_tabIndex(IHTMLAreaElement *iface, short v)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%i)\n", This, v);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_get_tabIndex(IHTMLAreaElement *iface, short *p)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_focus(IHTMLAreaElement *iface)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLAreaElement_blur(IHTMLAreaElement *iface)
{
    HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static const IHTMLAreaElementVtbl HTMLAreaElementVtbl = {
    HTMLAreaElement_QueryInterface,
    HTMLAreaElement_AddRef,
    HTMLAreaElement_Release,
    HTMLAreaElement_GetTypeInfoCount,
    HTMLAreaElement_GetTypeInfo,
    HTMLAreaElement_GetIDsOfNames,
    HTMLAreaElement_Invoke,
    HTMLAreaElement_put_shape,
    HTMLAreaElement_get_shape,
    HTMLAreaElement_put_coords,
    HTMLAreaElement_get_coords,
    HTMLAreaElement_put_href,
    HTMLAreaElement_get_href,
    HTMLAreaElement_put_target,
    HTMLAreaElement_get_target,
    HTMLAreaElement_put_alt,
    HTMLAreaElement_get_alt,
    HTMLAreaElement_put_noHref,
    HTMLAreaElement_get_noHref,
    HTMLAreaElement_put_host,
    HTMLAreaElement_get_host,
    HTMLAreaElement_put_hostname,
    HTMLAreaElement_get_hostname,
    HTMLAreaElement_put_pathname,
    HTMLAreaElement_get_pathname,
    HTMLAreaElement_put_port,
    HTMLAreaElement_get_port,
    HTMLAreaElement_put_protocol,
    HTMLAreaElement_get_protocol,
    HTMLAreaElement_put_search,
    HTMLAreaElement_get_search,
    HTMLAreaElement_put_hash,
    HTMLAreaElement_get_hash,
    HTMLAreaElement_put_onblur,
    HTMLAreaElement_get_onblur,
    HTMLAreaElement_put_onfocus,
    HTMLAreaElement_get_onfocus,
    HTMLAreaElement_put_tabIndex,
    HTMLAreaElement_get_tabIndex,
    HTMLAreaElement_focus,
    HTMLAreaElement_blur
};

static inline HTMLAreaElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
{
    return CONTAINING_RECORD(iface, HTMLAreaElement, element.node);
}

static HRESULT HTMLAreaElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
{
    HTMLAreaElement *This = impl_from_HTMLDOMNode(iface);

    *ppv = NULL;

    if(IsEqualGUID(&IID_IHTMLAreaElement, riid)) {
        TRACE("(%p)->(IID_IHTMLAreaElement %p)\n", This, ppv);
        *ppv = &This->IHTMLAreaElement_iface;
    }else {
        return HTMLElement_QI(&This->element.node, riid, ppv);
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static HRESULT HTMLAreaElement_handle_event(HTMLDOMNode *iface, eventid_t eid, nsIDOMEvent *event, BOOL *prevent_default)
{
    HTMLAreaElement *This = impl_from_HTMLDOMNode(iface);
    nsAString href_str, target_str;
    nsresult nsres;

    if(eid == EVENTID_CLICK) {
        nsAString_Init(&href_str, NULL);
        nsres = nsIDOMHTMLAreaElement_GetHref(This->nsarea, &href_str);
        if (NS_FAILED(nsres)) {
            ERR("Could not get area href: %08x\n", nsres);
            goto fallback;
        }

        nsAString_Init(&target_str, NULL);
        nsres = nsIDOMHTMLAreaElement_GetTarget(This->nsarea, &target_str);
        if (NS_FAILED(nsres)) {
            ERR("Could not get area target: %08x\n", nsres);
            goto fallback;
        }

        return handle_link_click_event(&This->element, &href_str, &target_str, event, prevent_default);

fallback:
        nsAString_Finish(&href_str);
        nsAString_Finish(&target_str);
    }

    return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default);
}

static const NodeImplVtbl HTMLAreaElementImplVtbl = {
    &CLSID_HTMLAreaElement,
    HTMLAreaElement_QI,
    HTMLElement_destructor,
    HTMLElement_cpc,
    HTMLElement_clone,
    HTMLAreaElement_handle_event,
    HTMLElement_get_attr_col
};

static const tid_t HTMLAreaElement_iface_tids[] = {
    HTMLELEMENT_TIDS,
    IHTMLAreaElement_tid,
    0
};
static dispex_static_data_t HTMLAreaElement_dispex = {
    NULL,
    DispHTMLAreaElement_tid,
    HTMLAreaElement_iface_tids,
    HTMLElement_init_dispex_info
};

HRESULT HTMLAreaElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
{
    HTMLAreaElement *ret;
    nsresult nsres;

    ret = heap_alloc_zero(sizeof(HTMLAreaElement));
    if(!ret)
        return E_OUTOFMEMORY;

    ret->IHTMLAreaElement_iface.lpVtbl = &HTMLAreaElementVtbl;
    ret->element.node.vtbl = &HTMLAreaElementImplVtbl;

    HTMLElement_Init(&ret->element, doc, nselem, &HTMLAreaElement_dispex);

    nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLAreaElement, (void**)&ret->nsarea);
    assert(nsres == NS_OK);

    *elem = &ret->element;
    return S_OK;
}
