(function($) {
	$.fn.filterList = function(selector, options) {
		var defaults = {
			speed: 500,
			li_height: null,
			li_width: null,
			item_tag: 'li',
			effect: 'fade',
			move: true
		};
		
		var options = $.extend(defaults, options);  
		
		return this.each(function() {
			var list = $(this);

			var li_height  = options.li_height == null ? list.find(options.item_tag + ':first').outerHeight() : options.li_height;
			var li_width   = options.li_width == null ? list.find(options.item_tag + ':first').outerWidth() : options.li_width;
			var per_line   = Math.floor(list.outerWidth() / li_width);
			var filtered_i = 0;

			list.find(options.item_tag).each(function(i, el) {
				el = $(el);
				
				if (!el.is(selector)) {
					el.addClass('currently_fading');
					
					if (options.effect == 'fade') {
						el.fadeOut(options.speed, function() { el.removeClass('currently_fading') });
					} else if (options.effect == 'slide') {
						el.slideUp(options.speed);
					}
				} else {
					var new_y = li_height * Math.floor(filtered_i / per_line);
					var new_x = li_width * (filtered_i % per_line);
					
					var needs_move = options.move && (el.css('left') != new_x || el.css('top') != new_y);
					
					if (el.is(':hidden') || el.hasClass('currently_fading')) {
						if (needs_move) {
							el.css({
								top: new_y,
								left: new_x
							});
						}
						
						if (options.effect == 'fade') {
							el.fadeIn(options.speed);
						} else if (options.effect == 'slide') {
							el.slideDown(options.speed);
						}
					} else if (needs_move) {
						el.animate({
							top: new_y,
							left: new_x
						}, options.speed);
					}

					filtered_i++;
				}
			});
		});
	}
})(jQuery);