var events = require('events');

module.exports = function() {
	var listeners = {};
	var that = new events.EventEmitter();

	that.watch = function(key, cb) {
		if (!listeners[key]) {
			listeners[key] = new events.EventEmitter();
			listeners[key].setMaxListeners(0);
		}

		if (cb) listeners[key].on('change', cb);
		return listeners[key];
	};

	that.watcher = function(key, cb) {
		var watcher = new events.EventEmitter();
		var onchange = function() {
			watcher.emit('change', 'change', key);
		};

		that.watch(key, onchange);
		if (cb) watcher.on('change', cb);
		watcher.close = function() {
			that.unwatch(key, onchange);
		};

		return watcher;
	};

	that.unwatch = function(key, cb) {
		if (!listeners[key]) return;
		if (cb) listeners[key].removeListener('change', cb);
		else listeners[key].removeAllListeners('change');
		if (!listeners[key].listeners('change').length) delete listeners[key];;
	};

	that.change = function(key) {
		if (listeners[key]) listeners[key].emit('change');
		that.emit('change', key);
	};

	that.cb = function(key, cb) {
		return function(err, val) {
			if (key) that.change(key);
			if (cb) cb(err, val);
		};
	};

	return that;
};