// Extensions to Core JS 
// and jQuery methods and objects

/**
 * Easy access in Arrays to jQuerys $.each-function.
 */
Array.prototype.each = function (method) {
	$.each(this, method);
};

/**
 * Format-function to format a string.
 * Arguments: Unlimited, replaces {0} with first argument, {1} with second argument, and so forth
 * Ex: "Hello {0}, this is {1}".format("world", "nice");
 * Returns: "Hello world, this is nice"
 */
String.prototype.format = function() {
	var args = arguments;
	return this.replace(/{(\d+)}/g, function(o, m) {
		return args[m];
	});
};

String.prototype.capitalize = function() {
	return this.substring(0, 1).toUpperCase() + this.substring(1).toLowerCase();
};

String.prototype.isOneOf = function () {
	return $.inArray(this.toString(), arguments) > -1;
};


// Extend the document object
document.getLayout = function () {
	var _layout,
	    regex = /layout-\d+/i;
	function getLayout() {
		var result;
		if (!_layout) {
			result = regex.exec($('body').attr('class'));
			_layout = result ? result[0] : null;
		}
		return _layout;
	}
	return getLayout;
}();
document.hasLayout = function (layout) {
	return document.getLayout() === layout;
};
document.getPageType = function () {
	var _pagetype;
	function getPageType() {
		_pagetype = _pagetype || $('body').attr('id');
		return _pagetype;
	}
	return getPageType;
}();
document.hasPageType = function (type) {
	return document.getPageType() === type;
};
document.isStartPage = function () {
	return document.hasPageType('home');
};
document.isSubSectionPage = function () {
	return document.hasPageType('sub-section');
};

/**
 * Article functions
 * @requires jQuery
 * Add article functions, e.g., 'Print' or 'Tell a friend'.
 */
document.articleFunctions = function() {
	var ul;
	function getUl() {
		if (!ul) {
			var funcs = $('#article-functions');
			if (funcs.length) {
				ul = $('ul', funcs);
				if (!ul.length) {
					ul = $('<ul></ul>').prependTo(funcs);
				}
			}
		}
		return ul;
	}
	/**
 	 * Add an item
	 * @param  options  Object  An object with options
	 */
	function addItem(options) {
		var li, a;
		options = jQuery.extend({
			// Link html
			text: '',
			// Link (or li) class
			className: '',
			// Link (or li) id
			id: '',
			// Callback to execute on click
			callback: null,
			// An element to append the link to, bypassing the regular ul
			insertInto: null
		}, options || {});
		
		if (getUl() || options.insertInto) {
			// Create link
			a = $('<a href="#"></a>');
			a.html(options.text);
			a.click(options.callback);
			if (!options.insertInto) {
				// If no insertInto-element is specified,
				// append the link to an li and add it to the ul
				li = $('<li>');
				// Add class and id to the li
				li.attr({
					'class': options.className,
					'id': options.id
				});
				a.appendTo(li);
				li.appendTo(ul);
			} else {
				// Add class and id to the link
				a.attr({
					'class': options.className,
					'id': options.id
				});
				a.appendTo($(options.insertInto));
			}
			return a;
		}
	}
	return {
		addItem: addItem
	};
}();

// Extend jQuery
(function ($) {

	var defaultValueClassName = 'default-value-set';

	$.extend($.fn, {
		rememberDefaultValue: function() {
			$(this).each(function () {
				var t = $(this);
				t.data('defaultValue', t.attr('title'));
				if (t.data('defaultValue')) {
					t.resetDefaultValue();
					t.focus(function(e) {
						$(this).removeDefaultValue();
					});
					t.blur(function(e) {
						$(this).resetDefaultValue();
					});
					t.closest('form').submit(function () {
						if (t.valueIsDefault()) {
							t.removeDefaultValue();
						}
					});
				}
			});
			return this;
		},
		valueIsDefault: function () {
			return $(this).val() === $(this).data('defaultValue');
		},
		removeDefaultValue: function () {
			$(this).each(function () {
				var t = $(this);
				if (t.valueIsDefault()) {
					t.val('');
					t.removeClass(defaultValueClassName);
				}
			});
			return this;
		},
		resetDefaultValue: function () {
			$(this).each(function () {
				var t = $(this);
				if (t.val() === '' || t.valueIsDefault()) {
					t.addClass(defaultValueClassName);
					t.val(t.data('defaultValue'));
				}
			});
			return this;
		},
		isExternal: function () {
			// Is it a link to begin with?
			if (this.attr('tagName').toLowerCase() == "a") {
				// A mailto link is not external
				if (this.attr('protocol') != "mailto:") {
					// If the second-level domain matches the current one, it's not an external link
					if (document.location.hostname.search(/\w+\.\w+$/) != this.attr('hostname').search(/\w+\.\w+$/)) {
						// If the hostname matches any of the specified internal domains, it's not an external link
						if ($.inArray(this.attr('hostname'), SolnaStad.InternalDomains) == -1) {
							return true;
						}
					}
				}
			}
			return false;
		},
		getLabel: function() {
			var label;
			if (this.attr('tagName').toLowerCase().isOneOf('input', 'select', 'textarea') && this.attr('id')) {
				label = $('label[for=' + this.attr('id') + ']');
				return label;
			}
		}
	});
})(jQuery);

/**
* A simple querystring parser.
* Example usage: var q = $.parseQuery(); q.foo returns  "bar" if query contains "?foo=bar"; multiple values are added to an array. 
* Values are unescaped by default and plus signs replaced with spaces, or an alternate processing function can be passed in the params object .
* http://actingthemaggot.com/jquery
*
* Copyright (c) 2008 Michael Manning (http://actingthemaggot.com)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
**/
jQuery.parseQuery = function(qs, options) {
	var q = (typeof qs === 'string' ? qs : window.location.search), o = { 'f': function(v) { return unescape(v).replace(/\+/g, ' '); } }, options = (typeof qs === 'object' && typeof options === 'undefined') ? qs : options, o = jQuery.extend({}, o, options), params = {};
	jQuery.each(q.match(/^\??(.*)$/)[1].split('&'), function(i, p) {
		p = p.split('=');
		p[1] = o.f(p[1]);
		params[p[0]] = params[p[0]] ? ((params[p[0]] instanceof Array) ? (params[p[0]].push(p[1]), params[p[0]]) : [params[p[0]], p[1]]) : p[1];
	});
	return params;
};