/* Location 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 Location {
	private nsurl *url;
};

prologue Location()
%{
#include "desktop/browser.h"
%}

init Location(nsurl *url)
%{
	priv->url = url;
	nsurl_ref(url);
%}

fini Location()
%{
	nsurl_unref(priv->url);
%}

method Location::reload()
%{
	/* 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 {
		LOG("failed to get browser context");
	}
	return 0;
%}

method Location::assign()
%{
	/* 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) {
		LOG("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;
%}

method Location::replace()
%{
	/* 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) {
		LOG("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;
%}

getter Location::href()
%{
	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;
%}

setter Location::href()
%{
	/* 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) {
		LOG("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;
%}

getter Location::origin()
%{
	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;
%}

getter Location::protocol()
%{
	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;
%}


getter Location::username()
%{
	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;
%}


getter Location::password()
%{
	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;
%}


getter Location::host()
%{
	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;
%}


getter Location::hostname()
%{
	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;
%}



getter Location::port()
%{
	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;
%}


getter Location::pathname()
%{
	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;
%}


getter Location::search()
%{
	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;
%}


getter Location::hash()
%{
	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;
%}