/**
 * Wraps the HTML5 localStorage container to support storage of objects.
 *
 * @copyright SiteCrafting, Inc.
 * @author Nick Williams
 * @version 1.0.0
 */
SC.LocalData = {
	_defaults: {},
	_data: {},
	
	/**
	  * Initializes the localData object with the specified data. Omitting the
	  * data parameter will re-initialize the localData object with whatever
	  * data is currently available in localStorage.
	  *
	  * @param Object data the data to be used (will replace any existing stored data)
	  */
	 init: function(data) {
		if(data) {
			this._data = $.extend(this._defaults, data);
		}
		else {
			this._data = $.extend({}, this._defaults);
			this.reload();
		}

		this.save(false);
	 },

	/**
	 * Retrieves the specified item from local storage, or an empty object if it
	 * doesn't already exist.
	 *
	 * @param mixed key the key associated with the item
	 */
	getItem: function(key) {
		if(!this._data[key]) {
			this.reloadItem(key);
		}

		return this._data[key];
	},

	/**
	 * Stores the specified value in local storage.
	 *
	 * @param mixed key the key to be associated with the value
	 * @param mixed value the associated value to be stored
	 */
	setItem: function(key, value) {
		localStorage.setItem(key, JSON.stringify(value));
		this.reloadItem(key);
	},

	/**
	 * Removes the specified item from local storage.
	 *
	 * @param mixed key the key for the item to be removed
	 */
	removeItem: function(key) {
		localStorage.removeItem(key);
		this.splice(key, 1);
	},

	/**
	 * Writes the specified item to local storage, including any modifications
	 * made since its last retrieval from localStorage.
	 *
	 * @param string key the key associated with the data to be saved
	 * @param boolean shouldReload whether or not listening UI elements should reload themselves
	 */
	saveItem: function(key, shouldReload) {
		this.setItem(key, this._data[key]);

		this.triggerDataChanged(key, shouldReload);

		this.setItem('updated', new Date());
	},

	/**
	 * Reloads the specified item with the data currently stored in local
	 * storage.
	 *
	 * @param mixed key the key associated with the item to be reloaded
	 */
	reloadItem: function(key) {
		if(!localStorage.getItem(key) || localStorage.getItem(key) == 'undefined') {
			this.setItem(key, {});
		}
		else {
			this._data[key] = JSON.parse(localStorage.getItem(key));
		}
	},

	/**
	 * Writes all items to local storage, including any modifications
	 * made since their last retrieval from localStorage.
	 *
	 * @param boolean shouldReload whether or not listening UI elements should reload themselves
	 */
	save: function(shouldReload) {
		for(var key in this._data) {
			this.saveItem(key, shouldReload);
		}
	},

	/**
	 * Reloads all items with the data currently stored in local
	 * storage.
	 */
	reload: function() {
		for(var key in this._data) {
			this.reloadItem(key);
		}
	},

	/**
	 * Clears all data, preserving relevant containers and their structure.
	 */
	clear: function(key) {
		if(this._defaults[key] != undefined) {
			this._data[key] = $.extend({}, this._defaults[key]);
		}
		else {
			this._data[key] = $.extend({}, this._defaults[key]);
		}
	},

	/**
	 * Triggers the custom dataChanged event whena a value is modified.
	 *
	 * @param mixed the key for which the data has changed
	 * @param boolean whether or not any listening UI elements should reload themselves
	 */
	triggerDataChanged: function(key, shouldReload) {
		$(document).trigger('dataChanged', [key, shouldReload]);
	}
};
