// 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;
};


(function ($) {

	$.fn.extend({
		populateValue: function (options) {
			options = $.extend({
				// Whether to hide the input's associated label
				hideLabel: true,
				// Class to add to hide the label
				hiddenLabelClass: 'structural',
				// Whether to use the label text as value
				useLabelText: false,
				// Whether to use the input's title text as value
				useTitleText: true,
				// A value to use instead of title or label text
				value: null,
				// Whether to add a class to the input when the value is set (for example to change text color)
				originalClass: true
			}, options);
			this.each(function () {
				var valueText, 
				    node = $(this),
				    label = node.getLabel();
				// Make sure it's an input with type=text we're working with
				if (node.attr('type') === 'text') {
					valueText = options.value;
					if (!valueText) {
						if (options.useLabelText) {
							if (label) {
								// If value is not explicitly set, and we want to
								// use the label text and a label exist, let's use that. 
								valueText = label.text();
							}
						} else if (options.useTitleText) {
							// If no value is explicitly set, and we want to use the
							// title of the input, let's try that.
							valueText = node.attr('title');
						}
					}
					if (valueText) {
						// Set value
						node.val(valueText);
						node.focus(function () {
							if (node.val() === valueText) {
								node.val('');
								if (options.originalClass) {
									node.removeClass('original-value');
								}
								// Make input caret visible in IE
								node.select();
							}
						});
						node.blur(function () {
							if (node.val() === '') {
								node.val(valueText);
								if (options.originalClass) {
									node.addClass('original-value');
								}
							}
						});
						if (label && options.hideLabel) {
							// Hide label
							label.addClass(options.hiddenLabelClass);
						}
					}
				}
			});
			return this;
		},
		// Get an elements associated label(s)
		getLabel: function () {
			var label,
			    id = this.attr('id');
			if (id) {
				label = $('label[for=' + id + ']');
			}
			return label;
		},
		/**
		* Return or set the minimum height of an element
		*/
		minHeight: function(size) {
			// Explorer versions prior to IE7 needs to have height instead of min-height
			var type = ($.browser.msie && parseInt($.browser.version, 10) < 7)  ? "height" : "min-height";
			if (size == undefined) {
				// Get min-height for the first element
				return this.css(type);
			} else {
				// Set the min-height on all elements (default to pixels if value is unitless)
				this.css(type, size.toString().match(/^\d+$/) ? size + "px" : size);
				return this;
			}
		},
		/**
		* Justify elements
		*/
		justify: function() {
			var maxHeight = 0;
			// Get the height of the highest element
			this.each(function() {
				var el = $(this), height;
				el.minHeight(0);
				height = el.outerHeight();
				if (height > maxHeight) {
					maxHeight = height;
				}
			});
			// Set min-height for all elements
			this.each(function () {
				var el = $(this);
				el.minHeight(el.height() + maxHeight - el.outerHeight());
			});
			return this;
		}
	});

})(jQuery);
