/**
 * Properties:
 * count
 * item
 * key
 * 
 * Methods:
 * add
 * exists
 * items
 * keys
 * remove
 * removeAll
 * 
 * @author Jon Ege Ronnenberg (LogicLAB)
 * @version 1.0
 */
var Dictionary = function(){
	//private vars/functions/objects goes here
	var _dict = {};
	// maintain count as variable to not be vulerable to prototyping of the Object class
	var _count = 0;
	return {
		count: function(){
			return _count
		},
		key: function(oldkey, newkey){
			_dict[newkey] = _dict[oldkey];
			this.remove(oldkey);
			_count++;
		},
		item: function(key, newitem){
			if(newitem){
				_dict[key] = newitem;
			}
			return _dict[key];
		},
		add: function(key, value){
			_dict[key] = value;
			_count++;
		},
		exists: function(key){
			return _dict[key] ? true : false;
		},		
		items: function(){
			var items = [];
			for (var key in _dict){
				items.push(_dict[key])
			}
			return items;
		},
		keys: function(){
			var keys = [];
			for (var key in _dict){
				keys.push(key);
			}
			return keys;
		},
		remove: function(key){
			eval ("delete _dict." + key + ";");
			_count--;
		},
		removeAll: function(){
			_dict = {};
			_count = 0;
		},
		/**
	     * Filter by a function. Returns a <i>new</i> collection that has been filtered.
	     * The passed function will be called with each object in the collection.
	     * If the function returns true, the value is included otherwise it is filtered.
	     * @param {Function} fn The function to be called, it will receive the args o (the object), k (the key)
	     * @param {Object} scope (optional) The scope of the function (defaults to this)
	     * @return {Dictionary} The new filtered collection
	     */
		filter: function(fn, scope){
			var filteredDict = new Dictionary();
			var k = this.keys(), it = this.items();
			for(var i = 0; i < this.count(); i++){
				if(fn.call(scope||this, it[i], k[i])){
					filteredDict.add(k[i], it[i]);
				}
			}
			return filteredDict;
		}
	}
};
