'use strict';

var URL = require('../../../_virtual/URL.js');
var index = require('../../webidl-conversions/lib/index.js');
var utils = require('./utils.js');
require('./URL-impl.js');
var URLImpl = require('../../../_virtual/URL-impl.js');

(function (module) {

	const conversions = index.lib;
	const utils$1 = utils.utilsExports;
	const Impl = URLImpl.__exports;

	const impl = utils$1.implSymbol;

	function URL(url) {
	  if (!this || this[impl] || !(this instanceof URL)) {
	    throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function.");
	  }
	  if (arguments.length < 1) {
	    throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present.");
	  }
	  const args = [];
	  for (let i = 0; i < arguments.length && i < 2; ++i) {
	    args[i] = arguments[i];
	  }
	  args[0] = conversions["USVString"](args[0]);
	  if (args[1] !== undefined) {
	  args[1] = conversions["USVString"](args[1]);
	  }

	  module.exports.setup(this, args);
	}

	URL.prototype.toJSON = function toJSON() {
	  if (!this || !module.exports.is(this)) {
	    throw new TypeError("Illegal invocation");
	  }
	  const args = [];
	  for (let i = 0; i < arguments.length && i < 0; ++i) {
	    args[i] = arguments[i];
	  }
	  return this[impl].toJSON.apply(this[impl], args);
	};
	Object.defineProperty(URL.prototype, "href", {
	  get() {
	    return this[impl].href;
	  },
	  set(V) {
	    V = conversions["USVString"](V);
	    this[impl].href = V;
	  },
	  enumerable: true,
	  configurable: true
	});

	URL.prototype.toString = function () {
	  if (!this || !module.exports.is(this)) {
	    throw new TypeError("Illegal invocation");
	  }
	  return this.href;
	};

	Object.defineProperty(URL.prototype, "origin", {
	  get() {
	    return this[impl].origin;
	  },
	  enumerable: true,
	  configurable: true
	});

	Object.defineProperty(URL.prototype, "protocol", {
	  get() {
	    return this[impl].protocol;
	  },
	  set(V) {
	    V = conversions["USVString"](V);
	    this[impl].protocol = V;
	  },
	  enumerable: true,
	  configurable: true
	});

	Object.defineProperty(URL.prototype, "username", {
	  get() {
	    return this[impl].username;
	  },
	  set(V) {
	    V = conversions["USVString"](V);
	    this[impl].username = V;
	  },
	  enumerable: true,
	  configurable: true
	});

	Object.defineProperty(URL.prototype, "password", {
	  get() {
	    return this[impl].password;
	  },
	  set(V) {
	    V = conversions["USVString"](V);
	    this[impl].password = V;
	  },
	  enumerable: true,
	  configurable: true
	});

	Object.defineProperty(URL.prototype, "host", {
	  get() {
	    return this[impl].host;
	  },
	  set(V) {
	    V = conversions["USVString"](V);
	    this[impl].host = V;
	  },
	  enumerable: true,
	  configurable: true
	});

	Object.defineProperty(URL.prototype, "hostname", {
	  get() {
	    return this[impl].hostname;
	  },
	  set(V) {
	    V = conversions["USVString"](V);
	    this[impl].hostname = V;
	  },
	  enumerable: true,
	  configurable: true
	});

	Object.defineProperty(URL.prototype, "port", {
	  get() {
	    return this[impl].port;
	  },
	  set(V) {
	    V = conversions["USVString"](V);
	    this[impl].port = V;
	  },
	  enumerable: true,
	  configurable: true
	});

	Object.defineProperty(URL.prototype, "pathname", {
	  get() {
	    return this[impl].pathname;
	  },
	  set(V) {
	    V = conversions["USVString"](V);
	    this[impl].pathname = V;
	  },
	  enumerable: true,
	  configurable: true
	});

	Object.defineProperty(URL.prototype, "search", {
	  get() {
	    return this[impl].search;
	  },
	  set(V) {
	    V = conversions["USVString"](V);
	    this[impl].search = V;
	  },
	  enumerable: true,
	  configurable: true
	});

	Object.defineProperty(URL.prototype, "hash", {
	  get() {
	    return this[impl].hash;
	  },
	  set(V) {
	    V = conversions["USVString"](V);
	    this[impl].hash = V;
	  },
	  enumerable: true,
	  configurable: true
	});


	module.exports = {
	  is(obj) {
	    return !!obj && obj[impl] instanceof Impl.implementation;
	  },
	  create(constructorArgs, privateData) {
	    let obj = Object.create(URL.prototype);
	    this.setup(obj, constructorArgs, privateData);
	    return obj;
	  },
	  setup(obj, constructorArgs, privateData) {
	    if (!privateData) privateData = {};
	    privateData.wrapper = obj;

	    obj[impl] = new Impl.implementation(constructorArgs, privateData);
	    obj[impl][utils$1.wrapperSymbol] = obj;
	  },
	  interface: URL,
	  expose: {
	    Window: { URL: URL },
	    Worker: { URL: URL }
	  }
	}; 
} (URL.__module));

var URLExports = URL.__module.exports;

exports.URLExports = URLExports;
