package net.flashpunk.utils
{
	import flash.net.SharedObject;
	
	/**
	 * Static helper class used for saving and loading data from stored cookies.
	 */
	public class Data 
	{
		/**
		 * If you want to share data between different SWFs on the same host, use this id.
		 */
		public static var id:String = "";
		
		/**
		 * Overwrites the current data with the file.
		 * @param	file		The filename to load.
		 */
		public static function load(file:String = ""):void
		{
			var data:Object = loadData(file);
			_data = { };
			for (var i:String in data) _data[i] = data[i];
		}
		
		/**
		 * Overwrites the file with the current data. The current data will not be saved until this function is called.
		 * @param	file		The filename to save.
		 */
		public static function save(file:String = ""):void
		{
			if (_shared) _shared.clear();
			var data:Object = loadData(file);
			for (var i:String in _data) data[i] = _data[i];
			_shared.flush(SIZE);
		}
		
		/**
		 * Reads an int from the current data.
		 * @param	name			Property to read.
		 * @param	defaultValue	Default value.
		 * @return	The property value, or defaultValue if the property is not assigned.
		 */
		public static function readInt(name:String, defaultValue:int = 0):int
		{
			return int(read(name, defaultValue));
		}
		
		/**
		 * Reads a uint from the current data.
		 * @param	name			Property to read.
		 * @param	defaultValue	Default value.
		 * @return	The property value, or defaultValue if the property is not assigned.
		 */
		public static function readUint(name:String, defaultValue:uint = 0):uint
		{
			return uint(read(name, defaultValue));
		}
		
		/**
		 * Reads a Boolean from the current data.
		 * @param	name			Property to read.
		 * @param	defaultValue	Default value.
		 * @return	The property value, or defaultValue if the property is not assigned.
		 */
		public static function readBool(name:String, defaultValue:Boolean = true):Boolean
		{
			return Boolean(read(name, defaultValue));
		}
		
		/**
		 * Reads a String from the current data.
		 * @param	name			Property to read.
		 * @param	defaultValue	Default value.
		 * @return	The property value, or defaultValue if the property is not assigned.
		 */
		public static function readString(name:String, defaultValue:String = ""):String
		{
			return String(read(name, defaultValue));
		}
		
		/**
		 * Writes an int to the current data.
		 * @param	name		Property to write.
		 * @param	value		Value to write.
		 */
		public static function writeInt(name:String, value:int = 0):void
		{
			_data[name] = value;
		}
		
		/**
		 * Writes a uint to the current data.
		 * @param	name		Property to write.
		 * @param	value		Value to write.
		 */
		public static function writeUint(name:String, value:uint = 0):void
		{
			_data[name] = value;
		}
		
		/**
		 * Writes a Boolean to the current data.
		 * @param	name		Property to write.
		 * @param	value		Value to write.
		 */
		public static function writeBool(name:String, value:Boolean = true):void
		{
			_data[name] = value;
		}
		
		/**
		 * Writes a String to the current data.
		 * @param	name		Property to write.
		 * @param	value		Value to write.
		 */
		public static function writeString(name:String, value:String = ""):void
		{
			_data[name] = value;
		}
		
		/** @private Reads a property from the data object. */
		private static function read(name:String, defaultValue:*):*
		{
			if (_data.hasOwnProperty(name)) return _data[name];
			return defaultValue;
		}
		
		/** @private Loads the data file, or return it if you're loading the same one. */
		private static function loadData(file:String):Object
		{
			if (!file) file = DEFAULT_FILE;
			if (id) _shared = SharedObject.getLocal(PREFIX + "/" + id + "/" + file, "/");
			else _shared = SharedObject.getLocal(PREFIX + "/" + file);
			return _shared.data;
		}
		
		// Data information.
		/** @private */ private static var _shared:SharedObject;
		/** @private */ private static var _dir:String;
		/** @private */ private static var _data:Object = { };
		/** @private */ private static const PREFIX:String = "FlashPunk";
		/** @private */ private static const DEFAULT_FILE:String = "_file";
		/** @private */ private static const SIZE:uint = 10000;
	}
}