

/**
 * Fonction anonyme de déclaration de classe(s)
 * ev.Hashtable.
 * Certaines classes/fonctions ne sont visible que par
 * la(es) classe(s) concernée(s) (déclarée(s) ici).
 * Ce mécanisme de fonction anonyme permet de reproduire
 * un système d'encapsulation digne d'un langage de
 * programmation évolué (comme le Java).
 */
(function() {
	//'use strict';
	var WIN = this,
			EASY = WIN.ev,
			HASHTABLE;

	// Si les namespaces/classes nécessaires ne sont pas chargées : exception
	if (!EASY) { throw 'Hashtable#<init>: Le namespace ev doit exister'; }

	// Si la classe ev.Hashtable est déjà définie, on sort
	if (EASY.Hashtable) { return; }

	/**
	 * Private class designed to hold simultaneously a key and a value.
	 * @param {!string} key The key.
	 * @param {!*} value The value.
	 * @constructor
	 */
	function Entry(key, value) {
		this.key = key;
		this.value = value;
	}

	/**
	 * This private method retrieves a entry instance
	 * (@see Entry) from the given entry array.
	 * @param {!Array.<Object>} array The entry array to search by.
	 * @param {!string} key The key associated with the entry to retrieve.
	 * @return {?*} The Entry object to retrieve, or null if the key is not present.
	 */
	function getEntry(array, key) {
		var i;
		for (i = 0; i < array.length; i++) {
			if (array[i].key === key || array[i].key.equals(key)) {
				return array[i];
			}
		}
		return null;
	}

	/**
	 * Hashtable class is a classical hashtable mechanism,
	 * designed to store values associated with a key.
	 */
	HASHTABLE = (EASY.Hashtable = function() {
		/**
		 * This private property holds all the entries
		 * stored in this hashtable.
		 */
		var entries = [];

		/**
		 * This method retrieves a value from the hashtable.
		 * @param {!string} key The key associated with the value to retrieve.
		 * @return {?*} The value to retrieve, or null if the key is not present.
		 * throw If key is undefined.
		 * throw If key is null.
		 */
		this.get = function(key) {
			if (key === undefined) { throw 'Hashtable#get(): key is undefined'; }
			if (key === null) { throw 'Hashtable#get(): key is null'; }
			var entry = getEntry(entries, key);
			if (entry === null) {return null;}
			return entry.value;
		};

		/**
		 * This method sets a value in the hashtable.
		 * @param {!string} key The key associated with the entry to store.
		 * @param {!*} value The value to store.
		 * throw If key is undefined.
		 * throw If key is null.
		 * throw If value is undefined.
		 * throw If value is null.
		 */
		this.put = function(key,value) {
			if (key === undefined) { throw 'Hashtable#put(): key is undefined'; }
			if (key === null) { throw 'Hashtable#put(): key is null'; }
			if (value === undefined) { throw 'Hashtable#put(): value is undefined'; }
			if (value === null) { throw 'Hashtable#put(): value is null'; }
			var entry = getEntry(entries, key);
			if (entry !== null) {
				//ev.log.info("mod entry in map : "+key+"="+value);
				entry.value = value;
			}
			else {
				//ev.log.info("new entry in map : "+key+"="+value);
				entry = new Entry(key, value);
				entries.push(entry);
			}
		};
	});

	EASY.log.debug('Hashtable#<init>: ok');
}()); // exécution de la fonction anonyme, ici

