/*global window, ev */

/**
 * 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(){
	// Si les namespaces/classes nécessaires ne sont pas chargées : exception
	if(!window.ev){throw new Error("Le namespace 'ev' doit exister");}
	// Si la classe ev.Hashtable est déjà définie, on sort
	if(ev.Hashtable){return;}

	/**
	 * Private class designed to hold simultaneously a key and a value.
	 * @param key The key.
	 * @param value The value.
	 */
	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 The entry array to search by.
	 * @param 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){
		for(var 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.
	 */
	ev.Hashtable=function(){
		/**
		 * This private property holds all the entries
		 * stored in this hashtable.
		 */
		var entries=[];

		/**
		 * This method retrieves a value from the hashtable.
		 * @param 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 new Error("key is undefined");}
			if(key===null){throw new Error("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 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 new Error("key is undefined");}
			if(key===null){throw new Error("key is null");}
			if(value===undefined){throw new Error("value is undefined");}
			if(value===null){throw new Error("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);
			}
		};
	};

	ev.log.debug('ev.Hashtable ok');
	ev.tools.onFileLoad('hashtable.js');
})(); // exécution de la fonction anonyme, ici