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

/**
 * options:
 * - element элемент, к которому всё цепляется
 * - url это ссылка из которой будут браться данные
 * - emptyName = "Пусто" то, что будет показываться для пустого списка
 * - emptyValue = 0
 * - defaultName = "Выберите" то, что будет показываться первым пунктом, если нет - не показывается
 * - defaultValue = 0
 * - intValue = true - считать ли аргумент целым числом
 * - params Объект с именами параметров - paramName => valueName
 * - value значение по-умолчанию, очень удобно использовать для задания предвыбранного значения
 * - callback(data) = [заполнение списка от] функция, используемая для получения данных
 * - notify() функция, вызываемая после заполнения всего
 * - noHandler = false не устанавливать слушателя (по-умолчанию ставится)
 **/
DynamicList.create = function(options){
	if(!defined(options.element) || typeof options.element != 'object'){
		alert('Не задан элемент');
		return false;
	}	
	
	var element = options.element;
	element.dynamicListOptions = options;
	
	if(!defined(options.url)){
		alert('Не задан URL списка');
		return false;
	}
	
	if(!defined(options.emptyName))	options.emptyName = 'Пусто';
	if(!defined(options.emptyValue)) options.emptyValue = 0;
	
	if(!defined(options.defaultName)){
		options.defaultName = 'Выберите';
	}
	
	if(!defined(options.defaultValue)){
		options.defaultValue = 0;
	}
	
	if(!defined(options.intValue)) options.intValue = true;
	
	element.updateList = function(){
		var value = this.value ? this.value : (options.intValue ? 0 : '');
		var select = this;
		
		if(options.intValue && !parseInt(value) 
			|| !options.intValue && value.toString().length == 0)
		{
			value = options.value;
		}
		
		if(options.intValue)
			value = parseInt(value);
			
		var url = options.url;
		if(url.indexOf('?') == -1)
			url += '?';
		else
			url += '&';
		
		var data = element.form.lsfGetData();
		var first = 1;
		if(element.form.ajaxSendFields) {
			// Надо отправлять все поля, т.к. есть зависимости при проверках.
			for(var i = 0; i < element.form.ajaxSendFields.length; i++){
				var fieldName = element.form.ajaxSendFields[i];
				if(first) first = 0; else url += '&';
			
				url += '__param_' + fieldName + '=' + escape(data[fieldName]);
			}
		}
		else {
			// Старое поведение.
			for(var i in options.params){
				if(first) first = 0; else url += '&';
			
				url += '__param_' + i + '=' + escape(data[i]);
			}
		}	
		
		YAHOO.log('DynamicSelect url: ' + url, 'info');
		
		var callback = (typeof(options.callback) == 'function')?options.callback : 
			function(data){
				while(select.options.length)
					select.remove(0);
				
				if(options.defaultName.length)
					DynamicList.addOption(select, options.defaultValue, options.defaultName);
					
				for(var i in data){
					DynamicList.addOption(select, i, data[i], i == value);
				}
				
				if(typeof(options.notify) == 'function')
					options.notify();
					
				if(typeof(select.dynamicListNotifier) == 'function')
						select.dynamicListNotifier();
			};
			
		while(select.options.length)
			select.remove(0);


        if(options.skipEmptyParams) {
            var noEmptyParams = true;
            for(var param in options.params) {
                if(data[param] == '0' && (options.skipEmptyParams & 1))
                    noEmptyParams = false;
                else if(data[param] == '' && (options.skipEmptyParams & 2))
                    noEmptyParams = false;
            }

            if(!noEmptyParams) {
                callback([]);
                return;
            }
        }

		DynamicList.addOption(select, 0, 'Загрузка данных...');
		
		if(options.noCache || typeof(DynamicList.cache[url]) == 'undefined'){
			var yuiCall = {
				success: function(o){
					var data;
					eval('data = ' + o.responseText);
					DynamicList.cache[url] = data;
					callback(data); 
				},
				
				failure: function(o){
					DynamicList.addOption(select, 0, 'Ошибка при получении списка');
					// alert("DynamicList: Ошибка при получении списка");
				}
			}
			
			var transaction = YAHOO.util.Connect.asyncRequest('GET', url, yuiCall, null);
		}
		else{
			callback(DynamicList.cache[url]);
		}
	}
	
	if(!options.noHandler && typeof options.params == 'object'){
		for(var i in options.params){
			var paramObj = document.getElementById(options.params[i]);
			
			if(!paramObj){
				alert('DynamicList: Невозможно найти объект-параметр ' + options.params[i]);
				continue;
			}
			
			if(!paramObj.dynamicListTargets)
				paramObj.dynamicListTargets = new Array();
				
			paramObj.dynamicListTargets.push(element);
			
			if(!paramObj.dynamicListListener){
				paramObj.dynamicListListener = true;
				paramObj.dynamicListNotifier = function(){
					for(var i = 0; i < this.dynamicListTargets.length; i++){
						this.dynamicListTargets[i].updateList();
					}
				}
				
				YAHOO.util.Event.addListener(paramObj, 'change', paramObj.dynamicListNotifier);
			}
		}
	}
}

DynamicList.addOption = function(selectElement, optionValue, optionText, selected){
	var oOption = document.createElement("OPTION");

	oOption.text = optionText;
	oOption.value = optionValue;
	selectElement.options.add(oOption);

	oOption.selected = selected;

	return oOption;
}
