/* Event binding for browser using duktape and libdom
 *
 * Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
 * Copyright 2015 Daniel Silverstone <dsilvers@netsurf-browser.org>
 *
 * This file is part of NetSurf, http://www.netsurf-browser.org/
 *
 * Released under the terms of the MIT License,
 *         http://www.opensource.org/licenses/mit-license
 */

class Event {
      private dom_event *evt;
};

init Event (struct dom_event *evt)
%{
	priv->evt = evt;
	dom_event_ref(evt);
%}

fini Event ()
%{
	dom_event_unref(priv->evt);
%}

/* Note: many of these could be automatics once nsgenbind gets there. */

getter Event::type ()
%{
	dom_string *ret;
	dom_exception exc;

	exc = dom_event_get_type(priv->evt, &ret);
	if (exc != DOM_NO_ERR) return 0;
	if (ret == NULL) {
		duk_push_lstring(ctx, "", 0);
	} else {
		duk_push_lstring(ctx, dom_string_data(ret),
				dom_string_length(ret));
		dom_string_unref(ret);
	}

	return 1;
%}

getter Event::target ()
%{
	/** @todo Decide HTF this works wrt. Window as an event target */
	dom_node *et;
	dom_exception exc;

	exc = dom_event_get_target(priv->evt, &et);
	if (exc != DOM_NO_ERR) return 0;

	dukky_push_node(ctx, et);

	dom_node_unref(et);
	return 1;
%}

getter Event::currentTarget ()
%{
	/** @todo Decide HTF this works wrt. Window as an event target */
	dom_node *et;
	dom_exception exc;

	exc = dom_event_get_current_target(priv->evt, &et);
	if (exc != DOM_NO_ERR) return 0;

	dukky_push_node(ctx, et);

	dom_node_unref(et);
	return 1;
%}

getter Event::eventPhase ()
%{
	dom_exception exc;
	dom_event_flow_phase phase;

	exc = dom_event_get_event_phase(priv->evt, &phase);
	if (exc != DOM_NO_ERR) return 0;

	duk_push_uint(ctx, phase);
	return 1;
%}

method Event::stopPropagation ()
%{
	dom_exception exc;

	exc = dom_event_stop_propagation(priv->evt);
	if (exc != DOM_NO_ERR) return 0;

	return 0;
%}

method Event::stopImmediatePropagation ()
%{
	dom_exception exc;

	exc = dom_event_stop_immediate_propagation(priv->evt);
	if (exc != DOM_NO_ERR) return 0;

	return 0;
%}

getter Event::bubbles ()
%{
	dom_exception exc;
	bool ret;

	exc = dom_event_get_bubbles(priv->evt, &ret);
	if (exc != DOM_NO_ERR) return 0;

	duk_push_boolean(ctx, ret);
	return 1;
%}

getter Event::cancelable ()
%{
	dom_exception exc;
	bool ret;

	exc = dom_event_get_cancelable(priv->evt, &ret);
	if (exc != DOM_NO_ERR) return 0;

	duk_push_boolean(ctx, ret);
	return 1;
%}

method Event::preventDefault ()
%{
	dom_exception exc;

	exc = dom_event_prevent_default(priv->evt);
	if (exc != DOM_NO_ERR) return 0;

	return 0;
%}

getter Event::defaultPrevented ()
%{
	dom_exception exc;
	bool ret;

	exc = dom_event_is_default_prevented(priv->evt, &ret);
	if (exc != DOM_NO_ERR) return 0;

	duk_push_boolean(ctx, ret);
	return 1;
%}

getter Event::isTrusted ()
%{
	dom_exception exc;
	bool ret;

	exc = dom_event_get_is_trusted(priv->evt, &ret);
	if (exc != DOM_NO_ERR) return 0;

	duk_push_boolean(ctx, ret);
	return 1;
%}


method Event::initEvent ()
%{
	dom_exception exc;
	bool bubbles;
	bool cancellable;

	duk_size_t text_len;
	const char *text = duk_safe_to_lstring(ctx, 0, &text_len);
	dom_string *text_str;

	exc = dom_string_create((const uint8_t*)text, text_len, &text_str);
	if (exc != DOM_NO_ERR) return 0; /* coerced to undefined */

	bubbles = duk_get_boolean(ctx, 1);
	cancellable = duk_get_boolean(ctx, 2);

	exc = dom_event_init(priv->evt, text_str, bubbles, cancellable);
	if (exc != DOM_NO_ERR) {
		dom_string_unref(text_str);
		return 0;
	}

	return 0;
%}
