'use strict';


	/**
	 * Crée un nouveau stockage et une nouvelle liste si elle n'existe pas déjà.
	 * @constructor
	 * @param {string} (name) Le nom de la base de données.
	 * @param {function} (callback) La foncion de rappel.
	 */
	function Store(name, callback) {
		callback = callback || function () {};

		this._dbName = name;

		if (!localStorage[name]) {
			var data = {
				todos: []
			};

			localStorage[name] = JSON.stringify(data);
		}

		callback.call(this, JSON.parse(localStorage[name]));
	}


	/**
	 * Trouve les éléments basés sur une requête donnée en tant qu'objet JS
	 * @param {object} (query) La requête à comparer (c'est-à-dire {foo: 'bar'})
	 * @param {function} (callback) La fonction de rappel après la requête.
	 *
	 * @example
	 * db.find({foo: 'bar', hello: 'world'}, function (data) {
	 *	 données retournera tous les éléments qui ont foo: bar et
	 *	 hello: world dans leurs propriétés
	 * });
	 */
	Store.prototype.find = function (query, callback) {
		if (!callback) {
			return;
		}

		var todos = JSON.parse(localStorage[this._dbName]).todos;

		callback.call(this, todos.filter(function (todo) {
			for (var q in query) {
				if (query[q] !== todo[q]) {
					return false;
				}
			}
			return true;
		}));
	};


	/**
	 * Récupère toutes les données.
	 * @param {function} (callback) La fonction de rappel après la récupération des données.
	 */
	Store.prototype.findAll = function (callback) {
		callback = callback || function () {};
		callback.call(this, JSON.parse(localStorage[this._dbName]).todos);
	};


	/**
	 * Sauvegarde les données données dans la base de données. Si aucun élément n'existe, un nouveau élément
	 *  sera créé, sinon une mise à jour des propriétés de l' élément existant sera réalisé
	 * @param {object} (updateData) Les données à sauvegarder dans la base de données.
	 * @param {function} (callback) La fonction de rappel après l'enregistrement.
	 * @param {number} (id) Un paramètre facultatif pour entrer l'ID d'un élément à mettre à jour.
	 */
	Store.prototype.save = function (updateData, callback, id) {
        var data = JSON.parse(localStorage[this._dbName]);
        var todos = data.todos;

        callback = callback || function () {};

		/**
		 * Génére un identifiant unique : Renvoie le nombre de millisecondes écoulées
		 * depuis le 1er Janvier 1970 00:00:00 UTC.
		 * @example
		 * return {number} 1519326977765
		 */
		var newId = Date.now();

		/**
		 * Si un ID a été donné, trouve l'élément et met à jour les propriétés
		 * @param  {number} (id) L'ID de l' élément.
		 */
		 if (id) {
 			for (var i = 0; i < todos.length; i++) {
 		  		if (todos[i].id === id) {
 		    		for (var key in updateData) {
 	      			todos[i][key] = updateData[key];
 		    		}
 		    		break;
 		  		}
 			}
			console.log('id : ' + id);
			localStorage[this._dbName] = JSON.stringify(data);
			callback.call(this, todos);
		} else {
			updateData.id = parseInt(newId);
			console.log('id : ' + newId + ' ok');
			todos.push(updateData);
			localStorage[this._dbName] = JSON.stringify(data);
			callback.call(this, [updateData]);
		}
    };


	/**
	 * Supprime un élément avec son ID.
	 * @param {number} (id) L'ID de l'objet à supprimer.
	 * @param {function} (callback) Le callback après la suppression.
	 */
	Store.prototype.remove = function (id, callback) {
		var data = JSON.parse(localStorage[this._dbName]);
		var todos = data.todos;
		var todoId;

		for (var i = 0; i < todos.length; i++) {
			if (todos[i].id == id) {
				todoId = todos[i].id;
			}
		}

		for (var i = 0; i < todos.length; i++) {
			if (todos[i].id == todoId) {
				todos.splice(i, 1);
			}
		}
		localStorage[this._dbName] = JSON.stringify(data);
		callback.call(this, todos);
	};


	/**
	 * Efface le stockage
	 * @param {function} (callback) La fonction de rappel après avoir effacé les données.
	 */
	Store.prototype.drop = function (callback) {
		var data = {todos: []};
		localStorage[this._dbName] = JSON.stringify(data);
		callback.call(this, data.todos);
	};

	window.app = window.app || {};
	window.app.Store = Store;