P.module('filters', function () {
	var _cache = {},
		$tags,
		$rippleNodes,
		ripples = [];
		
	function cache (tagArr, $ripples) {
		var key = tagArr.sort().join('-') + '-' + $('input:radio[name="logic"]:checked').val();
		if (!$ripples) {
			return _cache[key];
		} else if (!_cache[key]) {
			_cache[key] = {
				selected: $ripples,
				hidden: $rippleNodes.not($ripples)
			};
		}
		return false;
	}
	
	function filterRipples () {
		var isOr = $('input:radio[name="logic"]:checked').val() === 'OR',
			tagArr = function () {
				var _tags = [];
				$('#tag_cloud a.selected').each(function (i) {
					_tags[i] = $(this).text();
				});
				return _tags;
			}(),
			cachedResult = tagArr.length > 0? cache(tagArr): false;
			if (tagArr.length === 0) {
				$('#ripples > li').removeClass('hidden');
			} else if (cachedResult) {
				cachedResult.selected.removeClass('hidden');
				cachedResult.hidden.addClass('hidden');
			} else {
				$.each(ripples, function () {
					var ripple = this,
						isHidden = isOr,
						i, hasTag;
					for (i = 0; i < tagArr.length; i++) {
						if (isOr) {
							if (ripple.hasTag(tagArr[i])) {
								isHidden = false;
								break;
							}
						} else {
							if (!ripple.hasTag(tagArr[i])) {
								isHidden = true;
							}
						
						/*
						isHidden = !(isOr === ripple.hasTag(tagArr[i]));
						if (isOr && !isHidden) break;
						*/
                                                }
                                           
					}
					ripple.el[isHidden? 'addClass': 'removeClass']('hidden');
				});
				cache(tagArr, $rippleNodes.not('.hidden'));
			}
			P.fitSlidebox();
	}
	
	function Ripple (node) {
                var tagArr = $(node).clone(true).find('.tags > span').text().split(', ');
		return {
			tags: tagArr,
			el: $(node),
			hasTag: function (tag) {
				var i;
				for (i = 0; i < tagArr.length; i++) {
					if (tagArr[i] == tag) {
						return true;
					}
				}
				return false;
			}
		};
	}
	
	function populateRipples () {
		$tags = $('#tag_cloud a');
		$rippleNodes = $('#ripples > li');
		$rippleNodes.each(function (i) {
			ripples[i] = Ripple(this);
		});
	}
	
	return {
		execute: filterRipples,
		gatherData: populateRipples,
		init: function () {
			$(function () {
				$('input[name=logic]').change(filterRipples);
			});
			return true;
		}()
	};
	
});
