1 include(bbq.util.BBQUtil);
  2 
  3 bbq.domain.Repository = new Class.create(/** @lends bbq.domain.Repository.prototype */ {
  4 	_entities: null,
  5 	options: null,
  6 
  7 	/**
  8 	 * Holds domain objects.
  9 	 *
 10 	 * @constructs
 11 	 * @param {Object} options
 12 	 * @param {Object} type The type of object - should be a child class of bbq.domain.Entity
 13 	 * @param {Array} [options.entities] Entities to pre-populate with
 14 	 */
 15 	initialize: function(options) {
 16 		this.options = options ? options : {};
 17 		this._entities = [];
 18 
 19 		if(Object.isArray(this.options.entities)) {
 20 			this.options.entities.each(function(entity) {
 21 				this.add(entity);
 22 			}.bind(this));
 23 		}
 24 	},
 25 
 26 	/**
 27 	 * @return {Number} number of elements in object array
 28 	 */
 29 	size: function() {
 30 		return this._entities.length;
 31 	},
 32 
 33 	/**
 34 	 * @param {Number} index
 35 	 */
 36 	get: function(index) {
 37 		return this._entities[index];
 38 	},
 39 
 40 	/**
 41 	 * @param {Object} entity An object or a id
 42 	 * @return {Number}
 43 	 */
 44 	indexOf: function(entity) {
 45 		entity = this._createEntity(entity);
 46 
 47 		for(var i = 0; i < this._entities.length; i++) {
 48 			if(this._entities[i].equals(entity)) {
 49 				return i;
 50 			}
 51 		}
 52 
 53 		return -1;
 54 	},
 55 
 56 	/**
 57 	 * @return {Array} All entities contained in this Repository
 58 	 */
 59 	getAll: function() {
 60 		return $A(this._entities);
 61 	},
 62 
 63 	/**
 64 	 * Adds an Entity to this repository.  Pass either an identifier, object data or a domain object.
 65 	 *
 66 	 * @param {Object} entity
 67 	 * @returns {Object} The domain object
 68 	 */
 69 	add: function(entity) {
 70 		entity = this._createEntity(entity);
 71 
 72 		if(this.indexOf(entity) == -1) {
 73 			this.put(entity, this._entities.length);
 74 		}
 75 
 76 		return entity;
 77 	},
 78 
 79 	/**
 80 	 * @param {Object} entity
 81 	 * @param {Number} index
 82 	 */
 83 	put: function(entity, index) {
 84 		entity = this._createEntity(entity);
 85 
 86 		this._entities[index] = entity;
 87 
 88 		return entity;
 89 	},
 90 
 91 	/**
 92 	 * Removes the passed entity
 93 	 *
 94 	 * @param {Object} An entity of the same type contained in this list, data object or an id
 95 	 */
 96 	remove: function(entity) {
 97 		var index = this.indexOf(entity);
 98 
 99 		if(index == -1) {
100 			return;
101 		}
102 
103 		this._entities.splice(index, 1);
104 	},
105 
106 	_createEntity: function(data) {
107 		if(data instanceof this.options.type) {
108 			// passed domain object
109 		} else if(Object.isString(data) || Object.isNumber(data)) {
110 			// passed identifier
111 			data = new this.options.type({data: {id: data}});
112 		} else {
113 			// passed object data
114 			data = new this.options.type({data: data});
115 		}
116 
117 		// make sure domain object does not exist in this repository already
118 		for(var i = 0; i < this._entities.length; i++) {
119 			if(this._entities[i].equals(data)) {
120 				// object has been stored before
121 				data = this.get(i);
122 				data.processData(data.options.data);
123 
124 				break;
125 			}
126 		}
127 
128 		return data;
129 	},
130 
131 	/**
132 	 * removes all elements
133 	 */
134 	empty: function() {
135 		this._entities = [];
136 	}
137 });
138