const assets=require('assets');

let watchers=Object.create(null);
let lastWatchCode=1;

const toBoolean=v => {
	if(v=='false' || v==false) return false;
	return true;
};
const notify=(key, value) => {
	const interested=watchers[key];
	if(interested) Object
		.keys(interested)
		.map(key => interested[key])
		.forEach(fn => fn(key, value));
};

const get=key => {
	let confVal=localStorage.getItem('config.'+key);
	if(confVal===null) return assets.get('config')[key];
	return confVal;
};
const getB=key => toBoolean(get(key));
const getN=key => +get(key);
const getS=key => ''+get(key);

const set=(key, value) => {
	localStorage.setItem('config.'+key, value);
	notify(key, value);
};

const remove=key => {
	localStorage.removeItem('config.'+key, value);
	notify(key, assets.get('config')[key]);
};
const clear=() =>
	Object
		.keys(assets.get('config'))
		.forEach(remove);

const watch=(key, fn) => {
	if(!watchers[key]) watchers[key]=[];
	const code='w'+lastWatchCode++;
	watchers[key][code]=fn;
	return code;
};
const watchB=(key, fn) => watch(key, (k, v) => fn(k, toBoolean(v)));
const watchN=(key, fn) => watch(key, (k, v) => fn(k, +v));
const watchS=(key, fn) => watch(key, (k, v) => fn(k, ''+v));

const unwatch=(key, code) => {
	if(!watchers[key]) return;
	delete watchers[key][code];
};

const list=() =>
	Object
		.keys(assets.get('config'));
const dict=() => {
	let dict=Object.create(null);
	Object
		.keys(assets.get('config'))
		.forEach(
			key => dict[key]={
				raw: get(key),
				b: getB(key),
				n: getN(key),
				s: getS(key)
			}
		);
	return dict;
};

return module.exports={
	get, getB, getN, getS,
	set,
	remove, clear,
	watch, watchB, watchN, watchS,
	unwatch,
	list, dict
};
