1 /**
  2  * @author Gillis Haasnoot <gillis.haasnoot@gmail.com>
  3  * @package Banana.Util
  4  * @summary ArrayBiCollection
  5  */
  6 
  7 goog.provide('Banana.Util.ArrayUniCollection');
  8 
  9 /**
 10  * Array uni collection is a wrapper class maintaining quick access to data from index and vica versa.
 11  * Use this class if have arrays with non numeric indices and quick index lookup 
 12  * 
 13  * @constructor
 14  */
 15 Banana.Util.ArrayUniCollection = function()
 16 {
 17 	this.data = {};
 18 	this.indexKey = [];	
 19 
 20 	/**
 21 	 * Adds new item to the collection. Key in string or int format.
 22 	 * @param {String} key
 23 	 * @param {mixed} item
 24 	 */
 25 	this.addItem = function(key, value)
 26 	{
 27 		this.data[key] = value;
 28 		this.indexKey[this.indexKey.length] = key;
 29 	}
 30 
 31 	/**
 32 	 * Modifies item. Only if key already exists
 33 	 * 
 34 	 * @param {String} key
 35 	 * @param {mixed} value
 36 	 */
 37 	this.alterItem = function(key,value)
 38 	{
 39 		if (!this.data[key])
 40 		{
 41 			return;
 42 		}
 43 		
 44 		this.data[key] = value;
 45 	}
 46 
 47 	/**
 48 	 * Gets data by key
 49 	 * @param {String} key
 50 	 * @return {mixed} 
 51 	 */
 52 	this.getItem = function(key)
 53 	{
 54 		return this.data[key];
 55 	}
 56 
 57 	/**
 58 	 * gets indexed array with elements containing the data
 59 	 * @return {Array}
 60 	 */
 61 	this.getArray = function()
 62 	{
 63 		var a = [];
 64 
 65 		this.each(function(i,d)
 66 		{
 67 			a.push(d);
 68 		});
 69 
 70 		return a;
 71 	}
 72 	
 73 	/**
 74 	 * @ignore
 75 	 */
 76 	this.getItems = function()
 77 	{
 78 		return this.data;
 79 	}
 80 
 81 	/**
 82 	 * Gets item by index
 83 	 * @param {int} index
 84 	 * @return {mixed} 
 85 	 */
 86 	this.getItemByIndex = function(index)
 87 	{
 88 		return this.getItem(this.indexKey[index]);
 89 	}
 90 
 91 	/**
 92 	 * Gets key by index
 93 	 * @param {int} index
 94 	 * @return {String}
 95 	 */
 96 	this.getKeyByIndex = function(index)
 97 	{
 98 		return this.indexKey[index];
 99 	}
100 
101 	/**
102 	 * gets length of the collection
103 	 * @return {int}
104 	 */
105 	this.getLength = function()
106 	{
107 		return this.indexKey.length;
108 	}
109 
110 	/**
111 	 * Removes item by index
112 	 * @param {int} index
113 	 */
114 	this.removeByIndex = function(index)
115 	{
116 		removeByKey(this.indexKey[index],this);
117 		this.indexKey.splice(index,1);
118 
119 	}
120 	
121 	/**
122 	 * checks if given key exists in the collection
123 	 * @param {String} key
124 	 * @return {boolean} true if found
125 	 */
126 	this.isset = function(key)
127 	{
128 		return (this.data[key] != undefined);
129 	}
130 
131 	/**
132 	 * Clones the collection
133 	 * @return {Banana.Util.ArrayBiCollection}
134 	 */
135 	this.clone = function()
136 	{
137 		c = new MFArrayUniCollection();
138 		c.data = eval(uneval(this.data)); // Objectclone
139 		c.indexKey = this.indexKey.slice(); // Arrayclone
140 		return c;
141 	}
142 
143 	this.sortedKeys = function(fn)
144 	{
145 		fn = fn || function (a, b) {return parseInt(a) > parseInt(b);};
146 		var copiedIndex = this.indexKey.slice(); // clone
147 		copiedIndex.sort(fn);
148 		return copiedIndex;
149 	}
150 	
151 	/**
152 	 * Walks over the collection
153 	 * @param {Function} f
154 	 * @param {mixed} userdata
155 	 */
156 	this.each = function(f,userdata)
157 	{
158 		var len = this.getLength();
159 		for (var i = 0; i < len; i++)
160 		{
161 			f(i,this.getItemByIndex(i),userdata);
162 		}
163 	}
164 
165 	/**
166 	 * @ignore
167 	 */
168 	this.remove = function(key)
169 	{
170 		//TODO
171 	}
172 
173 	/**
174 	 * @ignore
175 	 * @param {String} key
176 	 * @param {mixed} obj
177 	 */
178 	function removeByKey(key,obj)
179 	{
180 		delete obj.data[key];
181 	}
182 }