/* Generated by nsgenbind
 *
 * nsgenbind is published under the MIT Licence.
 * nsgenbind is similar to a compiler is a purely transformative tool which
 * explicitly makes no copyright claim on this generated output
 */

/* DukTape JavaScript bindings for NetSurf browser
 *
 * Copyright 2015 Vincent Sanders <vince@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
 */

#include <dom/dom.h>

#include "utils/log.h"
#include "utils/nsurl.h"

#include "javascript/duktape/duktape.h"

struct browser_window;
struct html_content;
struct dom_node;
struct dom_element;
struct dom_document;
struct dom_html_element;
struct dom_node_character_data;
struct dom_node_text;
struct dom_node_list;
struct dom_node_comment;
struct dom_html_collection;
struct dom_html_br_element;


#include "build/Linux-gtk3/duktape/binding.h"
#include "build/Linux-gtk3/duktape/private.h"
#include "build/Linux-gtk3/duktape/prototype.h"

#include "javascript/duktape/dukky.h"
#line 17 "Location.bnd"

#include "netsurf/browser_window.h"
#line 46 "location.c"

static void dukky_location___init(duk_context *ctx, location_private_t *priv, nsurl *url)
{
#line 22 "Location.bnd"

	priv->url = url;
	nsurl_ref(url);
#line 54 "location.c"
}

static void dukky_location___fini(duk_context *ctx, location_private_t *priv)
{

	nsurl_unref(priv->url);
}

static duk_ret_t dukky_location___constructor(duk_context *ctx)
{
	/* create private data and attach to instance */
	location_private_t *priv = calloc(1, sizeof(*priv));
	if (priv == NULL) return 0;
	duk_push_pointer(ctx, priv);
	duk_put_prop_string(ctx, 0, dukky_magic_string_private);

	dukky_location___init(ctx, priv, duk_get_pointer(ctx, 1));
	duk_set_top(ctx, 1);
	return 1;
}

static duk_ret_t dukky_location___destructor(duk_context *ctx)
{
	location_private_t *priv;
	duk_get_prop_string(ctx, 0, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop(ctx);
	if (priv == NULL) return 0;

	dukky_location___fini(ctx, priv);
	free(priv);
	return 0;
}

static duk_ret_t dukky_location_assign(duk_context *ctx)
{
	/* ensure the parameters are present */
	duk_idx_t dukky_argc = duk_get_top(ctx);
	if (dukky_argc < 1) {
		/* not enough arguments */
		return duk_error(ctx, DUK_RET_TYPE_ERROR, dukky_error_fmt_argument, 1, dukky_argc);
	} else if (dukky_argc > 1) {
		/* remove extraneous parameters */
		duk_set_top(ctx, 1);
	}

	/* check types of passed arguments are correct */
	if (dukky_argc > 0) {
		if (!duk_is_string(ctx, 0)) {
			duk_to_string(ctx, 0);
		}
	}
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 49 "Location.bnd"

	/* retrieve the private data from the root object (window) */
	duk_push_global_object(ctx);
	duk_get_prop_string(ctx, -1, PRIVATE_MAGIC);
	window_private_t *priv_win = duk_get_pointer(ctx, -1);
	duk_pop(ctx);

	if (priv_win == NULL || priv_win->win == NULL) {
		NSLOG(netsurf, INFO, "failed to get browser context");
		return 0;
	}

	nsurl *joined;
	duk_size_t slen;
	const char *url = duk_safe_to_lstring(ctx, 0, &slen);

	nsurl_join(priv->url, url, &joined);
	browser_window_navigate(priv_win->win,
				joined,
				NULL,
				BW_NAVIGATE_HISTORY,
				NULL,
				NULL,
				NULL);
	nsurl_unref(joined);
	return 0;
#line 144 "location.c"
}

static duk_ret_t dukky_location_replace(duk_context *ctx)
{
	/* ensure the parameters are present */
	duk_idx_t dukky_argc = duk_get_top(ctx);
	if (dukky_argc < 1) {
		/* not enough arguments */
		return duk_error(ctx, DUK_RET_TYPE_ERROR, dukky_error_fmt_argument, 1, dukky_argc);
	} else if (dukky_argc > 1) {
		/* remove extraneous parameters */
		duk_set_top(ctx, 1);
	}

	/* check types of passed arguments are correct */
	if (dukky_argc > 0) {
		if (!duk_is_string(ctx, 0)) {
			duk_to_string(ctx, 0);
		}
	}
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 78 "Location.bnd"

	/* retrieve the private data from the root object (window) */
	duk_push_global_object(ctx);
	duk_get_prop_string(ctx, -1, PRIVATE_MAGIC);
	window_private_t *priv_win = duk_get_pointer(ctx, -1);
	duk_pop(ctx);

	if (priv_win == NULL || priv_win->win == NULL) {
		NSLOG(netsurf, INFO, "failed to get browser context");
		return 0;
	}

	nsurl *joined;
	duk_size_t slen;
	const char *url = duk_safe_to_lstring(ctx, 0, &slen);

	nsurl_join(priv->url, url, &joined);
	browser_window_navigate(priv_win->win,
				joined,
				NULL,
				BW_NAVIGATE_NONE,
				NULL,
				NULL,
				NULL);
	nsurl_unref(joined);
	return 0;
#line 202 "location.c"
}

static duk_ret_t dukky_location_reload(duk_context *ctx)
{
	/* ensure the parameters are present */
	duk_idx_t dukky_argc = duk_get_top(ctx);
	if (dukky_argc > 0) {
		/* remove extraneous parameters */
		duk_set_top(ctx, 0);
	}

	/* check types of passed arguments are correct */
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 33 "Location.bnd"

	/* retrieve the private data from the root object (window) */
	duk_push_global_object(ctx);
	duk_get_prop_string(ctx, -1, PRIVATE_MAGIC);
	window_private_t *priv_win = duk_get_pointer(ctx, -1);
	duk_pop(ctx);

	if (priv_win->win != NULL) {
		browser_window_reload(priv_win->win, false);
	} else {
		NSLOG(netsurf, INFO, "failed to get browser context");
	}
	return 0;
#line 239 "location.c"
}

static duk_ret_t dukky_location_ancestorOrigins_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}

static duk_ret_t dukky_location_href_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 107 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_COMPLETE, &url_s, &url_l);
	if (url_s == NULL) {
		return 0;
	}

	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 286 "location.c"
}

static duk_ret_t dukky_location_href_setter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 126 "Location.bnd"

	/* retrieve the private data from the root object (window) */
	duk_push_global_object(ctx);
	duk_get_prop_string(ctx, -1, PRIVATE_MAGIC);
	window_private_t *priv_win = duk_get_pointer(ctx, -1);
	duk_pop(ctx);

	if (priv_win == NULL || priv_win->win == NULL) {
		NSLOG(netsurf, INFO, "failed to get browser context");
		return 0;
	}

	nsurl *joined;
	duk_size_t slen;
	const char *url = duk_safe_to_lstring(ctx, 0, &slen);

	nsurl_join(priv->url, url, &joined);
	browser_window_navigate(priv_win->win,
				joined,
				NULL,
				BW_NAVIGATE_HISTORY,
				NULL,
				NULL,
				NULL);
	nsurl_unref(joined);
	return 0;
#line 328 "location.c"
}

static duk_ret_t dukky_location_origin_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 155 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_SCHEME | NSURL_HOST | NSURL_PORT, &url_s, &url_l);

	/* if url_s is NULL duk_push_lstring pushes an empty string
	 * which is correct for this API
	 */
	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 360 "location.c"
}

static duk_ret_t dukky_location_protocol_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 174 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_SCHEME, &url_s, &url_l);

	/* if url_s is NULL duk_push_lstring pushes an empty string
	 * which is correct for this API
	 */
	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 392 "location.c"
}

static duk_ret_t dukky_location_protocol_setter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}

static duk_ret_t dukky_location_username_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 194 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_USERNAME, &url_s, &url_l);

	/* if url_s is NULL duk_push_lstring pushes an empty string
	 * which is correct for this API
	 */
	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 439 "location.c"
}

static duk_ret_t dukky_location_username_setter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}

static duk_ret_t dukky_location_password_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 214 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_PASSWORD, &url_s, &url_l);

	/* if url_s is NULL duk_push_lstring pushes an empty string
	 * which is correct for this API
	 */
	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 486 "location.c"
}

static duk_ret_t dukky_location_password_setter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}

static duk_ret_t dukky_location_host_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 234 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_HOST, &url_s, &url_l);

	/* if url_s is NULL duk_push_lstring pushes an empty string
	 * which is correct for this API
	 */
	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 533 "location.c"
}

static duk_ret_t dukky_location_host_setter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}

static duk_ret_t dukky_location_hostname_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 254 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_HOST, &url_s, &url_l);

	/* if url_s is NULL duk_push_lstring pushes an empty string
	 * which is correct for this API
	 */
	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 580 "location.c"
}

static duk_ret_t dukky_location_hostname_setter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}

static duk_ret_t dukky_location_port_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 275 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_PORT, &url_s, &url_l);

	/* if url_s is NULL duk_push_lstring pushes an empty string
	 * which is correct for this API
	 */
	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 627 "location.c"
}

static duk_ret_t dukky_location_port_setter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}

static duk_ret_t dukky_location_pathname_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 295 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_PATH, &url_s, &url_l);

	/* if url_s is NULL duk_push_lstring pushes an empty string
	 * which is correct for this API
	 */
	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 674 "location.c"
}

static duk_ret_t dukky_location_pathname_setter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}

static duk_ret_t dukky_location_search_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 315 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_QUERY, &url_s, &url_l);

	/* if url_s is NULL duk_push_lstring pushes an empty string
	 * which is correct for this API
	 */
	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 721 "location.c"
}

static duk_ret_t dukky_location_search_setter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}

static duk_ret_t dukky_location_hash_getter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

#line 335 "Location.bnd"

	char *url_s = NULL;
	size_t url_l;

	nsurl_get(priv->url, NSURL_FRAGMENT, &url_s, &url_l);

	/* if url_s is NULL duk_push_lstring pushes an empty string
	 * which is correct for this API
	 */
	duk_push_lstring(ctx, url_s, url_l);

	if (url_s != NULL) {
		free(url_s);
	}

	return 1;
#line 768 "location.c"
}

static duk_ret_t dukky_location_hash_setter(duk_context *ctx)
{
	/* Get private data for method */
	location_private_t *priv = NULL;
	duk_push_this(ctx);
	duk_get_prop_string(ctx, -1, dukky_magic_string_private);
	priv = duk_get_pointer(ctx, -1);
	duk_pop_2(ctx);
	if (priv == NULL) {
		return 0; /* can do? No can do. */
	}

	return 0;
}

duk_ret_t dukky_location___proto(duk_context *ctx, void *udata)
{
	/* Add a method */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "assign");
	duk_push_c_function(ctx, dukky_location_assign, DUK_VARARGS);
	duk_def_prop(ctx, -3,
		     DUK_DEFPROP_HAVE_VALUE |
		     DUK_DEFPROP_HAVE_WRITABLE |
		     DUK_DEFPROP_HAVE_ENUMERABLE |
		     DUK_DEFPROP_ENUMERABLE |
		     DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add a method */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "replace");
	duk_push_c_function(ctx, dukky_location_replace, DUK_VARARGS);
	duk_def_prop(ctx, -3,
		     DUK_DEFPROP_HAVE_VALUE |
		     DUK_DEFPROP_HAVE_WRITABLE |
		     DUK_DEFPROP_HAVE_ENUMERABLE |
		     DUK_DEFPROP_ENUMERABLE |
		     DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add a method */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "reload");
	duk_push_c_function(ctx, dukky_location_reload, DUK_VARARGS);
	duk_def_prop(ctx, -3,
		     DUK_DEFPROP_HAVE_VALUE |
		     DUK_DEFPROP_HAVE_WRITABLE |
		     DUK_DEFPROP_HAVE_ENUMERABLE |
		     DUK_DEFPROP_ENUMERABLE |
		     DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add readonly property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "ancestorOrigins");
	duk_push_c_function(ctx, dukky_location_ancestorOrigins_getter, 0);
	duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "href");
	duk_push_c_function(ctx, dukky_location_href_getter, 0);
	duk_push_c_function(ctx, dukky_location_href_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add readonly property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "origin");
	duk_push_c_function(ctx, dukky_location_origin_getter, 0);
	duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "protocol");
	duk_push_c_function(ctx, dukky_location_protocol_getter, 0);
	duk_push_c_function(ctx, dukky_location_protocol_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "username");
	duk_push_c_function(ctx, dukky_location_username_getter, 0);
	duk_push_c_function(ctx, dukky_location_username_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "password");
	duk_push_c_function(ctx, dukky_location_password_getter, 0);
	duk_push_c_function(ctx, dukky_location_password_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "host");
	duk_push_c_function(ctx, dukky_location_host_getter, 0);
	duk_push_c_function(ctx, dukky_location_host_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "hostname");
	duk_push_c_function(ctx, dukky_location_hostname_getter, 0);
	duk_push_c_function(ctx, dukky_location_hostname_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "port");
	duk_push_c_function(ctx, dukky_location_port_getter, 0);
	duk_push_c_function(ctx, dukky_location_port_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "pathname");
	duk_push_c_function(ctx, dukky_location_pathname_getter, 0);
	duk_push_c_function(ctx, dukky_location_pathname_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "search");
	duk_push_c_function(ctx, dukky_location_search_getter, 0);
	duk_push_c_function(ctx, dukky_location_search_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Add read/write property */
	duk_dup(ctx, 0);
	duk_push_string(ctx, "hash");
	duk_push_c_function(ctx, dukky_location_hash_getter, 0);
	duk_push_c_function(ctx, dukky_location_hash_setter, 1);
	duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |
		DUK_DEFPROP_HAVE_SETTER |
		DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |
		DUK_DEFPROP_HAVE_CONFIGURABLE);
	duk_pop(ctx);

	/* Set the destructor */
	duk_dup(ctx, 0);
	duk_push_c_function(ctx, dukky_location___destructor, 1);
	duk_set_finalizer(ctx, -2);
	duk_pop(ctx);

	/* Set the constructor */
	duk_dup(ctx, 0);
	duk_push_c_function(ctx, dukky_location___constructor, 2);
	duk_put_prop_string(ctx, -2, "\xFF\xFFNETSURF_DUKTAPE_INIT");
	duk_pop(ctx);

	return 1; /* The prototype object */
}


