/**
 * Handy HTTP utilities
 *
 * Requires:
 *   none
 */
(function (utils) {
	"use strict";

	// the inverse of decodeParameterValue
	// BUG: the encodeURIComponent function encodes spaces as %20
	//      so there won't be any spaces left to further encode
	utils.encodeParameterValue = function (value) {
		return encodeURIComponent(value).replace(/ /g, '+');
	}

	// the inverse of encodeParameterValue
	utils.decodeParameterValue = function (value) {
		return decodeURIComponent(value.replace(/\+/g, ' '));
	}

	// get the named parameter value from the given link object
	utils.getParameterByName = function (linkObj, name) {
		var regex = new RegExp('[?&]' + name + '=([^&]*)');
		var match = regex.exec(linkObj.search);
		return match && utils.decodeParameterValue(match[1]);
	};

	// get the basename of the path associated with the given URL
	// (deprecated) (why?)
	utils.getBasenameFromURL = function (url) {
		var match = /\/([^\/]+)$/.exec(url);
		return match && match[1];
	};

	// get the host associated with the given URL
	utils.getHostFromURL = function (url) {
		var match = /^https?:\/\/([^\/]+)/.exec(url);
		return match && match[1];
	};

	// initialize a query string with the given parameter
	utils.initQueryString = function (name, value) {
		var encodedValue = utils.encodeParameterValue(value);
		return '?' + name + '=' + encodedValue;
	}

	// remove the given parameter from the query string
	utils.removeParameter = function (search, name) {
		if (!/^\?[^#]*$/.test(search)) {
			return search;  // if invalid search string, do nothing
		}

		var regex = new RegExp('([?&]' + name + '=[^&]*)');
		return search.replace(regex, "");
	};

	// append the given parameter to the query string
	utils.appendParameter = function (search, name, value) {
		if (!/^\?[^#]*$/.test(search)) {
			return search;  // if invalid search string, do nothing
		}

		var encodedValue = utils.encodeParameterValue(value);
		// test for at least one HTTP parameter
		if (/^\?[^=]+=[^&]*/.test(search)) {
			return search + '&' + name + '=' + encodedValue;
		} else {
			return search + name + '=' + encodedValue;
		}
	};

	// replace the named parameter value in the query string
	utils.replaceParameter = function (search, name, value) {
		if (!/^\?[^#]*$/.test(search)) {
			return search;  // if invalid search string, do nothing
		}

		var regex = new RegExp('([?&]' + name + '=)[^&]*');

		// if named parameter exists, replace it, otherwise append
		if (regex.test(search)) {
			var encodedValue = utils.encodeParameterValue(value);
			return search.replace(regex, "$1" + encodedValue);
		} else {
			return utils.appendParameter(search, name, value);
		}
	};

}(window.utils = window.utils || {}));