/**
 * $Workfile: atStateManager.js $
 * $Revision: 7 $
 *  $Modtime: 7/07/09 16:29 $
 *   $Author: Peter.goulborn $ 
 * 
 * Class: Astun.iSharemaps.StateManager
 * Gives iShareMaps the capability of saving settings to a store.  
 */

if (!Prototype) throw new Error('Dependent library not found');  // Needs to be nicer, possibly iSharemaps-wide library error?

if (!Astun) var Astun = {};
if (!Astun.iSharemaps) Astun.iSharemaps = {};
Astun.iSharemaps.StateManager = Class.create(
{
	/**
	 * Constructor: Astun.iSharemaps.StateManager
	 * Create a new state manager. This control saves settings to storage 
	 * 		on request and returns the values in the store when asked.
	 * 		When the control is created it watches for a custom event 
	 * 		(**astun:saveSetting**) fired on a number of elements.  
	 * 		If the **event.memo** object has both **setting** and 
	 * 		**value** properties and the setting name is a valid string 
	 * 		then these are used to call **saveSetting()**.  
	 * 		Otherwise the event is ignored.
	 *
	 * Parameters:
	 * eventElements: {Array} the HTML elements on which custom events will be
	 *		fired. 
	 * store : {String} the type of data store to be used.
	 * 		Defaults to 'cookie'.
	 */
	'initialize': function ( eventElements , storeType ) {
		var storeType = storeType || 'cookie';
		var settings = {};
		settings.initial = $H();
		settings.current = $H();
		switch (storeType) {
			case 'cookie':
				var store = new Astun.iSharemaps.StateStore.Cookie;
				break;
			default:
				return null;
		}
		
		this.flush = function() {
			var keys = settings.current.keys();
			while( keys.length ) {
				this.deleteSetting(keys.pop());
			}
		}
		
		this.deleteSetting = function( setting ){
			settings.current.unset(setting);
			store.deleteSetting(setting);
		};
		this.saveSetting = function(setting, value){
			if(!settings.initial.include(setting)) {
				settings.initial.set(setting, value);
			}
			settings.current.set(setting, value);
			if (value == '') {
				this.deleteSetting(setting);
			}
			else {
				store.saveSetting(setting, value);
			}
		};
		this.loadSettingFromStore = function (){};
		this.loadSetting = function(setting){
			return store.loadSetting(setting);
		};
		this.loadInitialSetting = function (){};
		
		var deleteSettingEvent = function (evt) {
			if (evt.memo && evt.memo.setting ) {
				this.deleteSetting(evt.memo.setting);
				Event.stop(evt);
				return false;
			}
		}
		var saveSettingEvent = function (evt) {
			if (evt.memo && evt.memo.setting && (typeof(evt.memo.value) === 'string')) {
				this.saveSetting(evt.memo.setting, evt.memo.value);
				Event.stop(evt);
				return false;
			}
		}
		var loadSettingEvent = function (evt) {
			if (evt.memo && evt.memo.setting && evt.memo.loadFunction) {
				var value = this.loadSetting(evt.memo.setting);
				evt.memo.loadFunction(value);
				Event.stop(evt);
				return false;
			}
		}
		
		if (!(eventElements instanceof Array)) {
			eventElements = [eventElements];			
		}
		while (eventElements.length){
			var element = eventElements.shift();
			if( !element.stateManager ) {
			    element.stateManager = this;
			    /* Set up event handlers for this stateManager */
			    Event.observe(element, 'astun:deleteSetting', deleteSettingEvent.bindAsEventListener(this));
			    Event.observe(element, 'astun:saveSetting', saveSettingEvent.bindAsEventListener(this));
			    Event.observe(element, 'astun:loadSetting', loadSettingEvent.bindAsEventListener(this));
			}
		}
	},
    CLASS_NAME: "Astun.iSharemaps.StateManager"
});

Astun.iSharemaps.StateStore = Class.create(
{
	/**
	 * Constructor: Astun.iSharemaps.StateStore
	 * Create a new state store, this is a generic class for specific store
	 * 		sub-classes to inherit from.
	 */
	'initialize': function (  ) {
		
	},
	'saveSetting' : function (key, value) {
		
	},
	'loadSetting' : function (key) {
		
	},
	'deleteSetting' : function (key) {
		
	},
    CLASS_NAME: "Astun.iSharemaps.StateStore"
});

Astun.iSharemaps.StateStore.Cookie = Class.create (
	/**
	 * Constructor: Astun.iSharemaps.StateStore.Cookie
	 * Create a new state store using cookies, a sub class of 
	 * 		<Astun.iSharemaps.StateStore>
	 */
	Astun.iSharemaps.StateStore,
	{
		'initialize' : function($super, overrides) {
			$super();
			this.cookieOptions = $H(
				{
					'domain': '',
					'path': '',
					'max-age': 31536000 //A year-ish					
				}
			);
			this.cookieOptions.each(function(option){
				if (!!overrides){
					var override = overrides[option.key];
					if (!!override) {
						this.cookieOptions.set(option.key, override);
					}	
				}
			});
			this.cookieOptions.toString = function(){
				var theString = '';
				this.each(function(option){
					if (option.value !== '') {
						theString += '; ' + option.key + '=' + encodeURIComponent(option.value);
					}	
				});
				return theString;
			}	
		},
		'saveSetting' : function ($super, key, value) {
			$super(key, value);
			document.cookie =  'astun:' + key + '='+ encodeURIComponent(value) + this.cookieOptions.toString(); 			
		},
		'loadSetting' : function ($super, key) {
			$super(key);
			if(document.cookie.match('astun:' + key + '=(.*?)(;|$)')){
				return decodeURIComponent(RegExp.$1);
			}
			return null;			
		},
		'deleteSetting' : function ($super, key) {
			$super(key);
			document.cookie = 'astun:' + key + '=; max-age=0';
		},
	    CLASS_NAME: "Astun.iSharemaps.StateStore.Cookie"
	}
);

