(function($)
{
	Array.prototype.contains = function(predicate)
	{
		if (!$.isFunction(predicate))
		{
			return false;
		}
		
		for (var i = 0; i < this.length; i++)
		{
			if (predicate(this[i]))
			{
				return true;
			}
		}
		
		return false;
	};
	
	$.fn.defaultText = function(options)
	{
		options = $.extend({ }, $.fn.defaultText.defaults, options);
		return this.each(function()
		{
			$this = $(this);
			$this.data('is-default', true);
			$this.data('class-name', options.className);
			$this.data('default-text', typeof options.defaultText != 'undefined' ? options.defaultText : $this.val());
			$this.addClass(options.className).val($this.data('default-text'));
			$this.focus(function()
			{
				var $this = $(this);
				$this.data('is-default', false).removeClass(options.className)
				if ($this.val() == $this.data('default-text'))
				{
					$this.val('');
				}
			}).blur(function()
			{
				var $this = $(this);
				if ($this.val() == '')
				{
					$this.data('is-default', true);
					$this.addClass(options.className).val($this.data('default-text'));
				}
			});
		});
	}
	
	$.fn.actualVal = function()
	{
		return this.data('is-default') ? '' : this.val();
	}
	
	$.fn.defaultText.defaults =
	{
		className: 'default-text'
	};
	
	$.fix = function(f)
	{
		if (!$.isFunction(f))
		{
			return null;
		}
		
		return function()
		{
			f($.fix(f))();
		};
	}
	
	$.contains = function(object, predicate)
	{
		if (typeof predicate !== 'function')
		{
			return false;
		}
		
		if (typeof object == 'Array')
		{
			for (var i = 0; i < this.length; i++)
			{
				if (predicate(this[i]))
				{
					return true;
				}
			}
		}
		else if ($.isFunction(object.each))
		{
			var isMatched = false;
			object.each(function()
			{
				if (predicate($(this)))
				{
					isMatched = true;
				}
			});
			return isMatched;
		}
		else
		{
			for (var key in object)
			{
				if (predicate(object[key]))
				{
					return true;
				}
			}
		}
		
		return false;
	};
	
	$.fn.totalWidth = function()
	{
		$this = $(this);
		var width = $this.width();
		width += getPixelCount($this.css('padding-left')) + getPixelCount($this.css('padding-right'));
		width += getPixelCount($this.css('margin-left')) + getPixelCount($this.css('margin-right'));
		width += getPixelCount($this.css('border-left-width')) + getPixelCount($this.css('border-right-width'));
		return width;
	};
	
	$.fn.totalHeight = function()
	{
		$this = $(this);
		var height = $this.height();
		height += getPixelCount($this.css('padding-top')) + getPixelCount($this.css('padding-bottom'));
		height += getPixelCount($this.css('margin-top')) + getPixelCount($this.css('margin-bottom'));
		height += getPixelCount($this.css('border-top-width')) + getPixelCount($this.css('border-bottom-width'));
		return height;
	}
	
	function getPixelCount(string)
	{
		return parseInt(string.match(/((\d*\.)?\d+)px/i)[1]);
	}
	
	// Filters a list of elements to a single element using an index, selector, jQuery object, or DOM element.
	$.fn.dynamicFilter = function(item)
	{
		$this = $(this);
		switch (typeof item)
		{
			case 'number':
				// Get the item at the specified index.
				item = $this.eq(item);
				break;
			case 'string':
				// Get the items matching the given expression.
				item = $this.filter(item);
				break;
			default:
				// Ensure that the item is a jQuery object.
				item = $(item);
				
				// Check that the item is in the given context.
				if ($this.index(item) < 0)
				{
					item = $([]);
				}
				
				break;
		}
		
		// Make sure there's only one being returned.
		return item.eq(0);
	}
})(jQuery);