/*
dynamic_list.js
json.js
select.js
*/

function defined(x){
	return typeof(x) != 'undefined' && x != null;
};

function addListener(element, event, func){
	if(element.attachEvent){
		element.attachEvent('on' + event, function(){ func(window.event) });
	}else if(element.addEventListener){
		element.addEventListener(event, func, false);
	}
};






var SelectTools = new Object();

SelectTools.clear = function(select){
	select = this._find(select);
	while(select.options.length){
		select.remove(0);
	}
};

SelectTools._find = function(select){
	if(typeof(select) == 'string'){
		return document.getElementById(select);
	}else{
		return select;
	}
};

SelectTools.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;
};

SelectTools.clearAdd = function(select, value, text){
	select = this._find(select);
	
	this.clear(select);
	this.addOption(select, value, text, true);
};

SelectTools.fill = function(select, elements, selectedElement){
	select = this._find(select);
	for(var i in elements){
		SelectTools.addOption(select, elements[i][0], elements[i][1], selectedElement == elements[i][0]);
	}
};

SelectTools.makeData = function(data, value, text){
	var out = new Array();
	if(typeof(value) == 'function' && typeof(text) == 'function'){
		for(var i in data){
			out.push([value(data[i]), text(data[i])]);
		}
	}
	else if(typeof(value) == 'function'){
		for(var i in data){
			out.push([value(data[i]), data[i][text]]);
		}
	}
	else if(typeof(text) == 'function'){
		for(var i in data){
			out.push([data[i][value], text(data[i])]);
		}
	}
	else{
		for(var i in data){
			out.push([data[i][value], data[i][text]]);
		}
	}
	
	return out;
};





var Json = new Object();
Json.callbacks = new Array();
Json.trace = false;
Json._debug = false;
Json.cache = false;

Json.call = function(url, callback){
	var i = this.callbacks.length;
	this.callbacks[i] = callback;
	
	if(url.indexOf('?') != -1){
		url += '&';
	}else{
		url += '?';
	}	
	url += '__json_call='+i;

	if(this.trace){
		prompt('', url);
	}
	var script = document.createElement('SCRIPT');
	script.src = url;
	document.getElementsByTagName('head')[0].appendChild(script);
};

Json.done = function(num, result){
	if(this._debug){
		alert(this.dump(result, ''));
	}
	this.callbacks[num](result);
};

Json.dump = function(v, t){
	if(typeof(t) == 'undefined') {
		t = '';
	}
	if(typeof(v) == 'object'){
		var out = t + '[\n';
		
		for(var i in v){
			out += t + '  ' + i + ': ' + this.dump(v[i], t + '  ') + '\n';
		}
		
		out += t + ']';
		
		return out;
	}
	else if(typeof(v) == 'array'){
		var out = t + '[';
		
		for(var i in v){
			out += t + '  ' + i + ': ' + this.dump(v[i], t + '  ');
		}
		
		out += t + ']';
		
		return out;
	}
	else{
		return v;
	}
};

Json.debug = function(debug){
	this._debug = (typeof(debug) != 'undefined')?debug:true;
};






DynamicList = new Object();
DynamicList.cache = new Object();
var lang = 0;
/**
 * 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.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);
		}
		
	
		if(!param){
			//options.defaultName = options.defaultName;
			SelectTools.clear(this);
			SelectTools.addOption(this, options.defaultValue, options.defaultName);
			if(typeof(options.notifyReset) == 'function'){
				options.notifyReset();
			}
			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);
					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);
			if (lang==1)
			{
				SelectTools.addOption(select, 0, 'Data load...');
			} else {
				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]);
			}

		}
	};
	
	

	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);
		}
	}

	
};