/**********************************************************************
* 
* Features:
*	- config
*		general config API
*	- localstorage-config
*		maintain configuration state in localStorage
*	- fs-config
*		maintain configuration state in file system
*
* XXX this module need refactoring...
*
*
**********************************************************************/
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
(function(require){ var module={} // make module AMD/node compatible...
/*********************************************************************/

var toggler = require('lib/toggler')
var actions = require('lib/actions')
var features = require('lib/features')

var core = require('features/core')



/*********************************************************************/

// XXX might be a good idea to add "sandbox" mode -- i.e. all settings 
// 		are saved to sessionStorage and a re-open will load the old settings...
// XXX might be a good idea to add a .configLoaded(..) and .configChanged(..) 
// 		events thought it's not clear how are we going to track changes...
var ConfigStoreActions = actions.Actions({
	config: {
		// XXX should this include path???
		// 		...there should be modes:
		// 			- 'read-only'	-- don't save...
		// 			- 'portable'	-- use APP dir
		// 			- 'normal'		-- use $HOME
		'config-fs-filename': '.ImageGrid.json',

		'config-auto-save-interval': 1000*5,

		'config-load-sequence': [
			// localStorage...
			'storage:${INSTANCE}/config',

			// FS...
			// XXX should we load both or just one???
			'fileSync:${APP}/.ImageGrid.json',
			'fileSync:${HOME}/.ImageGrid.json',

			// temporary config...
			// NOTE: this is active until we re-open the app...
			'session:${INSTANCE}/config',
		],
	},

	__config_base: null,
	__config_loaded_from: null,

	// XXX handle save order -- need to save to one location only...
	// 		...use: .__config_loaded_from in reverse order (stop on session:..)
	// XXX keep record of what we loaded...
	// XXX should we only support sync stores??? (current state)
	loadConfig: ['File/Load configuration',
		core.doc`

		NOTE: might need to reload after this.
		`,
		function(query){
			// store loaded...
			var loaded = this.__config_loaded_from = []

			this.resetConfig()

			// do the load...
			;(query ? 
					(query instanceof Array ? query : [query])
					: (this.config['config-load-sequence'] || ['storage:config']))
				.forEach(function(query){
					query = this.parseStoreQuery(query)
					var cfg = this.loadStore(query)

					// select store...
					cfg = query.store
						.map(function(store){ return cfg[store] })
						.filter(function(cfg){ return Object.keys(cfg).length > 0 })
						.shift() || {}
					// select key...
					cfg = query.key
						.map(function(key){ return cfg[key] })
						.filter(function(cfg){ return !!cfg })
						.shift()

					// merge the config...
					cfg 
						&& Object.assign(this.config, cfg)
						&& loaded.push(query.query)
				}.bind(this))
		}],
	storeConfig: ['File/Save configuration',
		function(query){
			// XXX
			this.saveStore(query || 'storage:${INSTANCE}/config') 
		}],
	// XXX this needs to be confirmed...
	resetConfig: ['File/Reset configuration',
		core.doc`

		NOTE: might need to reload after this.
		`,
		function(){
			var base = this.__config_base = this.__config_base || this.config
			this.config = Object.create(base)
		}],

	// XXX use timer events... (???)
	toggleConfigAutoStore: ['File/Auto-save configuration',
		toggler.Toggler(null, 
			function(_, state){ 
				var timer = 'config-auto-save-timer'

				if(state == null){
					return this.isPersistentInterval(timer) || 'none'

				} else {
					var that = this
					var interval = this.config['config-auto-save-interval']

					// no timer interval set...
					if(!interval){
						return false
					}

					// start/restart...
					if(state == 'running' && interval){
						this.setPersistentInterval(timer, 'storeConfig', interval*1000)

					// stop...
					} else {
						this.clearPersistentInterval(timer)
					}
				}
			},
			'running')],
	

	// XXX does not work yet... 
	toggleConfigSandbox: ['- File/',
		toggler.Toggler(null, 
			function(_, state){ 

				if(state == null){
					return Object.keys(this.store('session:${INSTANCE}/config').session).length > 0 || 'none'

				} else if(state == 'sandboxed'){
					this.store('session:${INSTANCE}/config', undefined)

				} else {
					this.storeConfig('session:${INSTANCE}/config')
				}
			},
			'sandboxed')],
})

var ConfigStore = 
module.ConfigStore = core.ImageGridFeatures.Feature({
	title: '',
	doc: '',

	tag: 'store-config',
	priority: 80,
	depends: [
		'timers',
		'store-localstorage',
	],
	suggested: [
		'store-fs-json-sync',
	],

	actions: ConfigStoreActions,

	handlers: [
		// XXX need to update rather than rewrite things...
		['prepareStoreToSave', 
			function(res, query, data){
				var ls_path = '${INSTANCE}/config'
				//var ls_path = 'config'
				query = this.parseStoreQuery(query)
				
				// config not requested...
				if(query.key != '*' 
						&& query.key.indexOf('config')
						&& query.key.indexOf(ls_path)){
					return
				}

				// localStorage...
				// NOTE: we do not need to clone anything here as this 
				// 		will be done by the localStorage handler...
				if(query.store.indexOf('storage') >= 0){
					//res.data.storage[ls_path] = this.config
					res.data.storage[ls_path] = data || this.config
				}

				if(query.store.indexOf('fileSync') >= 0){
					// XXX should this include path???
					//res.data.fileSync[this.config['config-fs-filename'] || '.ImageGrid.json'] = this.config
					res.data.fileSync[this.config['config-fs-filename'] || '.ImageGrid.json'] = data || this.config
				}
			}],
		//['prepareIndexForLoad',
		//	function(){
		//	}],
		// NOTE: this is sync for sync stores...
		['storeDataLoaded',
			function(_, store, data){
				var base = this.__config_base = this.__config_base || this.config
				var ls_path = '${INSTANCE}/config'

				// XXX sort out load priority/logic...
				// 		- one or the other or both?
				// 		- what order?

				if((data.storage || {})[ls_path]){
					var config = data.storage[ls_path] || {}
					config.__proto__ = base
					this.config = config
				}

				if((data.fsJSONSync || {}).config){
					var config = data.fsJSONSync.config || {}
					config.__proto__ = base
					this.config = config
				}

				// auto-start auto-save...
				this.config['config-auto-save-interval'] > 0 
					&& this.toggleConfigAutoStore('?') == 'off'
					&& this.toggleConfigAutoStore()
			}],
	],
})



/**********************************************************************
* vim:set ts=4 sw=4 :                               */ return module })
