var LW       = LW || {};
LW._handlerTemplates = {
	hasUniqId: function (type, url, overrides) {
		return {
			_url: url,
			_retrieve: function (uniqId) {
				LW.event.fireWhenReady(type + '.retrieve', uniqId);
			},
			_retrieve_immediate: function (uniqId) {
				LW.event.fire(type + '.retrieve', uniqId);
			},
			_parse: function (uniqId, response) {
				if (response.server_went_away) {
					LW.serverList.remove(uniqId);
					return;
				}
				if (response) {
					LW[type]._findCache[uniqId] = response;
					LW.event.fireWhenReady(type + '.load', uniqId);
				}
			},
			_cacheTimeout: 60,
			_findCache: {},
			find: function (uniqId) {
				if (LW[type]._findCache[uniqId]) {
					return LW[type]._findCache[uniqId];
				}
				return null;
			},
			clear: function (uniqId) {
				LW.JSON.cache.expire(LW[type]._url + uniqId);
			},
			load: function (uniqId) {
				LW.JSON.load(LW[type]._url + uniqId, function (response) { LW[type]._parse(uniqId, response); }, function () { LW[type]._retrieve(uniqId); }, LW[type]._cacheTimeout);
			},
			preLoad: function (uniqId, data) {
				LW.JSON.preLoad(LW[type]._url + uniqId, data, function (response) { LW[type]._parse(uniqId, response); }, function () { LW[type]._retrieve_immediate(uniqId); }, LW[type]._cacheTimeout);
			}
		};
	},
	single: function (type, url, overrides) {
		return {
			_url: url,
			_retrieve: function () {
				LW.event.fireWhenReady(type + '.retrieve');
			},
			_retrieve_immediate: function (uniqId) {
				LW.event.fire(type + '.retrieve', uniqId);
			},
			data: null,
			_parse: function (response) {
				LW[type].data = response;
				LW.event.fireWhenReady(type + '.load');
			},
			_cacheTimeout: 60,
			clear: function () {
				LW.JSON.cache.expire(LW[type]._url);
				LW[type].data = null;
			},
			load: function () {
				LW.JSON.load(LW[type]._url, LW[type]._parse, LW[type]._retrieve, LW[type]._cacheTimeout);
			},
			preLoad: function (data) {
				LW.JSON.preLoad(LW[type]._url, data, LW[type]._parse, LW[type]._retrieve_immediate, LW[type]._cacheTimeout);
			}
		};
	},
	lookup: function (type, field, url, overrides) {
		return {
			_cacheTimeout: 60,
			_url: url,
			_fullUrl: function (arg) {
				return LW[type]._url + '?' + LW[type]._field + '=' + arg
			},
			_field: field,
			_retrieve: function (arg) {
				LW.event.fireWhenReady(type + '.retrieve', arg);
			},
			_retrieve_immediate: function (arg) {
				LW.event.fire(type + '.retrieve', arg);
			},
			_cache: {},
			_parse: function (response) {
				var arg = response[LW[type]._field];
				LW[type]._cache[arg] = response;
				LW.event.fireWhenReady(type + '.load', arg);
			},
			find: function (arg) {
				return LW[type]._cache[arg];
			},
			clear: function (arg) {
				LW.JSON.cache.expire(LW[type]._fullUrl(arg));
				LW[type].data = null;
			},
			load: function (arg) {
				LW.JSON.load(LW[type]._fullUrl(arg), LW[type]._parse, function () { LW[type]._retrieve(arg); }, LW[type]._cacheTimeout);
			},
			preLoad: function (data) {
				var arg = data[LW[type]._field];
				LW.JSON.preLoad(LW[type]._fullUrl(arg), data, LW[type]._parse, function () { LW[type]._retrieve_immediate(arg); }, LW[type]._cacheTimeout);
			}
		};
	},
	noUniqId: function (type, url, overrides) {
		return {
			_url: url,
			_lookupField: 'name',
			_retrieve: function () {
				LW.event.fireWhenReady(type + '.retrieve');
			},
			_retrieve_immediate: function () {
				LW.event.fire(type + '.retrieve');
			},
			_parse: function (response) {
				LW[type]._findCache = {};
				for (var key in response) {
					if (response[key] && typeof response[key] != 'string') {
						LW[type].list = response[key];
						LW.event.fireWhenReady(type + '.load');
					}
				}
			},
			list: [],
			_cacheTimeout: 60,
			_findCache: {},
			find: function (value) {
				if (LW[type]._findCache[value]) {
					return LW[type]._findCache[value];
				}
				var field = LW[type]._lookupField;
				var l = LW[type].list.length;
				for (var i=0; i<l; i++) {
					var entry = LW[type].list[i];
					if (entry && entry[field] == value) {
						LW[type]._findCache[value] = entry;
						return entry;
					}
				}
				return null;
			},
			each: function(callback) {
				for (var i in LW[type].list) {
					callback(LW[type].list[i]);
				}
			},
			clear: function () {
				LW.JSON.cache.expire(LW[type]._url);
			},
			load: function () {
				LW.JSON.load(LW[type]._url, LW[type]._parse, LW[type]._retrieve, LW[type]._cacheTimeout);
			},
			length: function () {
				return LW[type].list.length;
			},
			preLoad: function (data) {
				LW.JSON.preLoad(LW[type]._url, data, LW[type]._parse, LW[type]._retrieve_immediate, LW[type]._cacheTimeout);
			}
		};
	}
};

LW.objects = {
	createHandler: function (template, type, url, overrides) {
		var lookatme = LW;
		/* many different pieces of data are loaded in exactly the same manner, so I created some templates for creating the js 'objects' */
		if (! LW[type]) {
			LW[type] = LW._handlerTemplates[template](type, url, overrides);
			if (overrides) {
				for (var method in overrides) {
					LW[type][method] = overrides[method];
				}
			}
		}
	}
};

