/**
 * filters a list of elements based on a unique id and tags assigned to each
 * @class Filter
 * @namespace INTRIGO
 * @requires INTRIGO
 */
INTRIGO.Filter = function(){
	this._items = {};
	this._searchTags = [];
}
INTRIGO.Filter.prototype = {
	_items: null,
	_searchTags: null,

	/**
	 * adds an item to the list
	 * @param {String} id: a unique id identifying the Dom element associated with this item
	 * @param {String|Hash|Array} tags: tags to search for
	 * @return {INTRIGO.Filter} instance of self
	 */
	addItem: function(id, tags) {
		this._items[id] = new INTRIGO.Filter.Item(id, tags);
		return this;
	},
	
	/**
	 * retrieves an item based on a dom id
	 * @param {String} id
	 * @return Filter.Item if found false if not
	 */
	getItemById: function(id){
		if (this._items[id])
			return this._items[id];
		else return false;
	},
	
	/**
	 * adds a tag to search for
	 * @param {Object} tag
	 */
	addSearchTag: function(tag) {
		this._searchTags[this._searchTags.length] = tag;
		this.searchTags();
	},
	
	/**
	 * removes a tag from search
	 * @param {Object} tag
	 */
	removeSearchTag: function(tag) {
		var tmp = [];
		for (var i = 0; i < this._searchTags.length; i++) {
			if (this._searchTags[i] != tag) {
				tmp[tmp.length] = this._searchTags[i];
			}
		}
		this._searchTags = tmp;
		this.searchTags();
	},
	
	/**
	 * searchs for tags
	 */
	searchTags: function() {
		var tags = this._searchTags;
		for (var i in this._items) {
			var found = 0;
			for (var j = 0; j < tags.length; j++) {
				if (this._items[i].searchForTag(tags[j]) > -1) {
					found++;
				}
			}
			if (found == tags.length)
				this._items[i].show();
			else this._items[i].hide();
		}
	},
	
	/**
	 * clears search
	 */
	reset: function(){
		this._searchTags = [];
		this.searchTags();
	}
};
/**
 * The item is a logical link to a DOM element. It is made of display logic and searchable tags
 * @class Filter.Item
 * @namespace INTRIGO
 * @requires INTRIGO
 * @param {Object} id: the id of the dom element associated with this item
 * @param {Hash|Array} tags (optional): pass tags for quick addition
 */
INTRIGO.Filter.Item = function(id, tags){
	this._id = id;
	this._tags = [];

	if (typeof(tags) == 'object') {
		//if array
		if (tags.length) {
			for (var i = 0; i < tags.length; i++) {
				this.addTag(tags[i]);
			}
		}
		else {
			for (var i in tags) {
				this.addTag(tags[i]);
			}
		}
	}
	else if (typeof(tags) == 'string') {
		this.addTag(tags);
	}
}
INTRIGO.Filter.Item.prototype = {
	_id: null,
	_tags: null,
	
	/**
	 * adds a tag to the search list
	 * @param {String} value: tag
	 * @return instance of self;
	 */
	addTag: function(value) {
		this._tags[this._tags.length] = value;
		return this;
	},
	
	/**
	 * searches the tags associated with this item and returns its position
	 * @param {String} value: the value you'd like to search for
	 * @return {Integer}: -1 if not found
	 */
	searchForTag: function(value) {
		for (var i = 0; i < this._tags.length; i++) {
			if (this._tags[i] == value) {
				return i;
			}
		}
		return -1;
	},
	
	/**
	 * displays the associated element
	 */
	show: function() {
		this.getElement().style.display = '';
	},
	/**
	 * hides the associated element
	 */
	hide: function() {
		this.getElement().style.display = 'none';
	},
	
	/**
	 * @return {DOM} returns a DOM object associated with this ID
	 */
	getElement: function() {
		return document.getElementById(this._id);
	}
};