DynamicList = new Object();
DynamicList.cache = new Object();

/**
 * options:
 * - element элемент, к которому всё цепляется
 * - url это ссылка из которой будут браться данные
 * - emptyName = "Пусто" то, что будет показываться для пустого списка
 * - emptyValue = 0
 * - defaultName = "Выберите" то, что будет показываться первым пунктом, если нет - не показывается
 * - defaultValue = 0]
 * - intParam = true - считать ли параметр целым числом
 * - intValue = true - --//--
 * - param то, что используется в качестве параметра при получении списка,
 * 			может быть: функция, возвращающая текущее значение параметра, объект имеющий .value
 *			или просто значение (но это как-то тупо)
 * - value значение по-умолчанию, очень удобно использовать для задания предвыбранного значения
 * - callback(data) = [заполнение списка от] функция, используемая для получения данных
 * - notify() функция, вызываемая после заполнения всего
 * - noHandler = false не устанавливать слушателя (по-умолчанию ставится)
 **/
function dynamicList(options){
	if(!defined(options.element) || typeof options.element != 'object'){
		alert('Не задан элемент');
		return false;
	}

	var element = options.element;

	if(!defined(options.url)){
		alert('Не задан URL списка');
		return false;
	}

	if(!defined(options.emptyName))	options.emptyName = 'Пусто';
	if(!defined(options.emptyValue)) options.emptyValue = 0;

	if(!defined(options.noDef)) options.noDef = false;

	if(!defined(options.defaultName)){
//		if(element.options[0])
//			options.defaultName = element.options[0].innerHTML;
//		else
			options.defaultName = 'Выберите';
	}

	if(!defined(options.defaultValue)){
//		if(element.options[0])
//			options.defaultValue = element.options[0].value;
//		else
			options.defaultValue = 0;
	}




	if(!defined(options.intParam)) options.intParam = true;
	if(!defined(options.intValue)) options.intValue = true;

	element.updateList = function(param){
		var value = this.value?this.value:0;
		var select = this;

		if(options.intValue && !parseInt(value)
			|| !options.intValue && value.toString().length == 0)
		{
			value = options.value;
		}

		if(options.intValue)
			value = parseInt(value);



		if(!defined(param)){
			if(defined(options.param)){
				if(typeof options.param == 'function')
					param = options.param();
				else if(typeof options.param == 'object')
					param = options.param.value;
				else
					param = options.param;
			}
			else{
				alert("Nor param nor options.param is given");

				return false;
			}
		}


		if(options.intParam)
			param = parseInt(param);

        // TODO: закоментил чтобы при value=0 происходило обновление
		//if(!param){
		//	//options.defaultName = 'Все';
		//	SelectTools.clear(this);
		//	if(!options.noDef) {
		//		SelectTools.addOption(this, options.defaultValue, options.defaultName);
		//	}
		//	if(typeof this.dynamicListNotifier == 'function')
		//		this.dynamicListNotifier();
		//}
		//else{
			//options.defaultName = '--';
			var url = options.url + param;

			var callback = (typeof(options.callback) == 'function')?options.callback :
				function(data){
					SelectTools.clear(select);
					if(!options.noDef) {
						SelectTools.addOption(select, options.defaultValue, options.defaultName);
					}
					SelectTools.fill(select, SelectTools.makeData(data, 'id', 'name'), value);

					if(typeof(options.notify) == 'function')
						options.notify();

					if(typeof(select.dynamicListNotifier) == 'function')
							select.dynamicListNotifier();
				};

			SelectTools.clear(select);
			SelectTools.addOption(select, 0, 'Загрузка данных...');

			if(options.noCache || typeof(DynamicList.cache[url]) == 'undefined'){
				Json.call(url, function(data){
						DynamicList.cache[url] = data;
						callback(data);
					});
			}
			else{
				callback(DynamicList.cache[url]);
			}

		//}//else
	}



	if(!options.noHandler && typeof options.param == 'object'){
		var paramObj = options.param;
		if(!paramObj.dynamicListTargets)
			paramObj.dynamicListTargets = new Array();

		paramObj.dynamicListTargets.push(element);

		if(!paramObj.dynamicListListener){
			paramObj.dynamicListListener = true;
			paramObj.dynamicListNotifier = function(){
				for(var i in paramObj.dynamicListTargets){
					paramObj.dynamicListTargets[i].updateList();
				}
			}

			addListener(paramObj, 'change', paramObj.dynamicListNotifier);
		}
	}


}