//<![CDATA[

/*
		KOMPONENTA TComboBox
		
		- autor				: Tomáš Poles
		- created			: 2004-10-01		
		- last update		: 2006-05-18
		- version			: 1.0.4
		- platform			: client browser (IE, Mozilla)
		
		TO-DO
		 3. upravit/rozšířit způsoby vyvolání uživatelských událostí (metoda fireEvent)
		
		1.0.4
		+ podpora enabled/disabled položky

		1.0.3
		+ podpora překreslování pouze změněných částí (obsah, styl apod.)

		1.0.2
		+ podpora aktualizace "content" a "text" při vnějším zásahu přes DHTML
		+ podpora atributu "selected" v tagu <item> !!! přednost má selectedValue !!!
		+ podpora prázdného/nezadaného atributu "name" v tagu "comboBox"

		1.0.1
		+ podpora vkládání přes dhtml
		+ podpora kláves up, down, enter, esc
		+ atribut submitOnEnter v TComboBox
			... nastavuje se pokud při enter má/nemá odesílat formulář
		+ atribut text v TComboBoxItem
			... slouží k zobrazení při výběru (pokud není dosadí se obsah elementu item)
*/

//globální seznam objektů
document.comboBoxes = new Array();

//---------------------------------------------------------------------------------------------------
//  HLAVNÍ OBJEKT: TComboBox
//---------------------------------------------------------------------------------------------------
function TComboBox(AElement)
{
	//properties
	//... public
	this.index = -1;
	this.name = null;
	this.element = AElement;
	this.expanded = true;
	this.selected = null;
	this.hovered = null;
	this.items = new Array();
	//... ... nastavení
	this.submitOnEnter = true;
	//... ... styly
	this.classMain = null;
	this.classValue = null;
	this.classEdit = null;
	this.classEditFocused = null;
	this.classButton = null;
	this.classList = null;
	//... ... události
	this.onChanging = null;
	this.onChange = null;
	//... private
	this._no_action = false;
	this._selected_value = "";
	this._main_name = "";
	this._selected_name = "";
	this._button_name = "";
	this._list_name = "";
	this._item_name = "";

	//inicializace
	this.init = function()
	{
		//... properties
		this.index = document.comboBoxes.length;
		this.name = this.element.getAttribute("name");
		this._selected_value = this.element.getAttribute("selectedValue");
		this.element.removeAttribute("name");
		this.element.setAttribute("_instance_exists", "1");
		//... ... nastavení
		this.submitOnEnter = !IsValueInArray(this.element.getAttribute("submitOnEnter") + "", ["false", "0", "no"]);
		//... ... styly
		this.classMain = IsNull(this.element.getAttribute("classMain"), "");
		this.classValue = IsNull(this.element.getAttribute("classValue"), "");
		this.classEdit = IsNull(this.element.getAttribute("classEdit"), "");
		this.classEditFocused = IsNull(this.element.getAttribute("classEditFocused"), "");
		this.classButton = IsNull(this.element.getAttribute("classButton"), "");
		this.classList = IsNull(this.element.getAttribute("classList"), "");
		//... události
		this.onChanging = this.element.getAttribute("onChanging");
		this.onChange = this.element.getAttribute("onChange");
		//... položky
		var polozky = this.element.getElementsByTagName("item");
		for (var j = 0; j < polozky.length; j ++) {
			this.items[j] = new TComboBoxItem(this, j, polozky[j]);
		}
		//... vložení do seznamu (dle jména)
		if (this.name != null) {
			document.comboBoxes[this.name] = this;
		}
		//... nastavení jmen
		//this._main_name = "comboBox_" + (IsNull(this.name, "") != "" ? this.name : this.index);
		// * musí být dle indexu z důvodu rozpoznávání komponent dle těchto názvů
		// * v globálních událostech ( v názvu comboBoxu se může vyskytovat cokoliv)
		this._main_name = "comboBox_" + this.index;
		this._selected_name = this._main_name + "_selected";
		this._button_name = this._main_name + "_button";
		this._list_name = this._main_name + "_list";
		this._item_name = this._main_name + "_item_";
		//... vykreslení
		this.paint();	
		this.collapse();
		//... nastavení selected
		if (this.items.length > 0) {
			sIdx = this.indexOf(this._selected_value);
			if (sIdx < 0) {
				for (var i = this.items.length - 1; i >= 0; i --) {
					if (!this.items[i].enabled) continue;
					if ((this.items[i].element.getAttribute("selected") + "") == "") {
						sIdx = i;
						break;
					}
				}
			}
			if (sIdx < 0 || !this.items[sIdx].enabled) {
				var item = this.getFirstEnabledItem();
				if (item != null) item.select();
			} else {
				this.items[sIdx].select();
			}
		}
	}

	//vykreslení
	this.paint = function()
	{
		//... proměnné	
		var tmp_class_main = (this.classMain != "" ? 'class="' + this.classMain + '"' : '');
		var tmp_class_value = (this.classValue != "" ? 'class="' + this.classValue + '"' : '');
		var tmp_class_edit = (this.classEdit != "" ? 'class="' + this.classEdit + '"' : '');
		var tmp_class_edit_focused = (this.classEditFocused != "" ? 'class="' + this.classEditFocused + '"' : '');
		var tmp_class_button = (this.classButton != "" ? 'class="' + this.classButton + '"' : '');
		var tmp_class_list = (this.classList != "" ? 'class="' + this.classList + '"' : '');
		//... události
		//... ... button
		var evt_button = "";
		evt_button += 'onclick="return document.comboBoxes[' + this.index + ']._handle_button_click(this)" ';
		//evt_button += 'onclick="alert(\'kuku\')" ';
		evt_button += 'onfocus="return document.comboBoxes[' + this.index + ']._handle_button_focus(this)" ';
		//... ... selected
		var evt_selected = "";
		evt_selected += 'onclick="return document.comboBoxes[' + this.index + ']._handle_selected_click(this)" ';
		//... ... list
		var evt_list = "";
		evt_list += 'onmouseout="return document.comboBoxes[' + this.index + ']._handle_list_mouseout(this)" ';
		//... sestavení HTML
		var sHTML = '';
		sHTML += '<div id="' + this._main_name + '" name="' + this._main_name + '" ' + tmp_class_main + '"> \r\n';
		sHTML += '	<table ' + tmp_class_value + '> \r\n';
		sHTML += '		<tr> \r\n';
		sHTML += '			<td width="99%" id="' + this._selected_name + '" name="' + this._selected_name + '" ' + evt_selected + ' ' + tmp_class_edit + '>&nbsp;</td> \r\n';
		sHTML += '			<td width="1%"><input type="button" id="' + this._button_name + '" name="' + this._button_name + '" value="" ' + evt_button + ' ' + tmp_class_button + '/></td> \r\n'
		sHTML += '		</tr> \r\n';
		sHTML += '	</table> \r\n';
		sHTML += '	<div id="' + this._list_name + '" name="' + this._list_name + '" ' + evt_list + ' ' + tmp_class_list + '> \r\n';
		for (var i = 0; i < this.items.length; i ++) {
			var item = this.items[i];
			var classes = '';
			if (item.isSelected() && this.classSelected != "") classes = 'class="' + this.classSelected + '"';
			else if (item.isHovered() && this.classHover != "") classes = 'class="' + this.classHover + '"';
			else if (this.classDefault != "") classes = 'class="' + this.classDefault + '"';
			var events = "";
			events += 'onclick="return document.comboBoxes[' + this.index + '].items[' + i + ']._handle_click(this)" ';
			events += 'onmouseover="return document.comboBoxes[' + this.index + '].items[' + i + ']._handle_mouseover(this)" ';
			sHTML += '		<div id="' + this._item_name + i + '" name="' + this._item_name + i + '" ' + events + ' ' + classes + '></div> \r\n';
		}
		sHTML += '	</div> \r\n';
		if (IsNull(this.name, "") != "") {
			sHTML += '	<input type="hidden" id="' + this.name + '" name="' + this.name + '" value=""/> \r\n';
		}
		sHTML += '</div> \r\n';
		//... vložení
		this.element.innerHTML = sHTML;
		//... vykreslení položek
		for (var i = 0; i < this.items.length; i ++) {
			this.items[i].paint(null, false);
		}
	}

	//zobrazení seznamu
	this.expand = function()
	{
		if (this.expanded) return false;
		var list = GetTag(this._list_name);
		list.style.display = "block";
		this.expanded = true;
		//... překreslení "selected" položky
		if (this.selected != null) {
			this.selected.paint(null, true, true);
		}
	}

	//skrytí seznamu
	this.collapse = function()
	{
		if (!this.expanded) return false;
		var list = GetTag(this._list_name);
		list.style.display = "none";
		if (this.hovered != null) {
			var item = this.hovered;
			this.hovered = null;
			item.paint();
		}
		this.expanded = false;
	}
	
	//skrytí seznamu - cizích comb
	this.collapseOthers = function()
	{
		for (var i = 0; i < document.comboBoxes.length; i ++) {
			if (i != this.index) document.comboBoxes[i].collapse();
		}
	}
	
	//nastavení focusu
	this.focus = function()
	{
		this._no_action = true;
		var tag = GetTag(this._button_name);
		tag.focus();
		this._no_action = false;
	}
	
	//vyhledání indexu položky dle hodnoty
	this.indexOf = function(AValue)
	{
		var ret = -1;
		for (var i = 0; i < this.items.length; i ++) {
			if (this.items[i].value == AValue) {
				ret = i;
				break;
			}
		}
		return ret;
	}
	
	//najde prvni povolenou polozku
	this.getFirstEnabledItem = function()
	{
		for (var i = 0; i < this.items.length; i ++) {
			if (this.items[i].enabled) return this.items[i];
		}
		return null;
	}	
	
	//najde nasledujici povolenou polozku
	this.getNextEnabledItem = function(AItem)
	{
		var item = (AItem != null ? AItem : (this.expanded && this.hovered != null ? this.hovered : this.selected));
		if (item == null) return this.getFirstEnabledItem();
		for (var i = item.index + 1; i < this.items.length; i ++) {
			if (this.items[i].enabled) return this.items[i];
		}
		return null;
	}	
	
	//najde predchozi povolenou polozku
	this.getPreviousEnabledItem = function(AItem)
	{
		var item = (AItem != null ? AItem : (this.expanded && this.hovered != null ? this.hovered : this.selected));
		if (item == null) return this.getFirstEnabledItem();
		for (var i = item.index - 1; i >= 0; i --) {
			if (this.items[i].enabled) return this.items[i];
		}
		return null;
	}	
	
	//vyvolání událostí
	this.fireEvent =  function(AType, AObject)
	{
		var ret = true;
		eval("var exists = (this." + AType + " && this." + AType + " != null && this." + AType + " != '');");
		if (exists) {
			try {
				eval("var udalost = this." + AType + ";");
				eval("var vysledek = " + udalost + "(this, AObject);");
				ret = (vysledek == true || vysledek == null || (vysledek + "") == "");
			} catch(e) {
				ret = true;
			}
		}
		return ret;
	}
	
	//zachycení událostí prvků
	//... BUTTON - OnClick
	this._handle_button_click = function(AElement)
	{
		if (this._no_action) return false;
		//... zavření ostatních
		this.collapseOthers();
		//... otevření/zavření aktuálního
		if (this.expanded) this.collapse();
		else this.expand();
		this.focus();
		return false;
	}

	//... BUTTON - OnFocus
	this._handle_button_focus = function(AElement)
	{
		if (!this._no_action) this.collapseOthers();
	}

	//... SELECTED - OnClick
	this._handle_selected_click = function(AElement)
	{
		return this._handle_button_click(AElement);
	}

	//... LIST - OnMouseOut
	this._handle_list_mouseout = function(AElement)
	{
		if (this.hovered != null) {
			var item = this.hovered;
			this.hovered = null;
			item.paint();
		}
	}

	//... COMBO - OnKeyDown
	this._handle_keydown = function(AElement, AEvent)
	{
		//... ENTER
		if (AEvent.keyCode == 13) {
			if (this.expanded) {
				var item = (this.hovered != null ? this.hovered : this.selected);
				if (item != null) {
					var wc = (document.all ? false : true);
					item.select(wc);
				}
				return false;
			} else if (this.submitOnEnter) {
				var form = GetTag(this._button_name).form;
				if (form != null) {
					form.submit();
					return false;
				}
			}
		//... ESC
		} else if (AEvent.keyCode == 27) {
			if (this.expanded) this.collapse();
			return false;
		//... UP
		} else if (AEvent.keyCode == 38) {
			if (this.expanded) {
				var item = (this.hovered != null ? this.hovered : this.selected);
				var item_prev = (item != null ? item.getPreviousEnabledItem() : null);
				if (item != null && item_prev != null) item_prev.hover();
			}
			return false;
		//... DOWN
		} else if (AEvent.keyCode == 40) {
			if (!this.expanded) this.expand();
			else {
				var item = (this.hovered != null ? this.hovered : this.selected);
				var item_next = (item != null ? item.getNextEnabledItem() : null);
				if (item != null && item_next != null) item_next.hover();
			}
			return false;
		}
		return true;
	}

	//inicializace
	this.init();
}

//---------------------------------------------------------------------------------------------------
//	POLOŽKA SEZNAMU: TComboBoxItem
//---------------------------------------------------------------------------------------------------
function TComboBoxItem(ACombo, AIndex, AElement)
{
	//properties
	//... public
	this.comboBox = ACombo;
	this.element = AElement;
	this.index = AIndex;
	this.value = null;
	this.content = null;
	this.text = null;
	this.enabled = true;
	//... ... styly
	this.classDefault = null;
	this.classSelected = null;
	this.classHover = null;
	this.classDisabled = null;

	//inicializace	
	this.init = function()
	{
		this.value = this.element.getAttribute("value");
		this.content = this.element.innerHTML;
		this.text = this.element.getAttribute("text");
		this.enabled = !IsValueInArray((this.element.getAttribute("enabled") + ""), ["false", "0", "no"]);
		//... ... styly
		this.classDefault = IsNull(this.element.getAttribute("classDefault"), "");
		this.classSelected = IsNull(this.element.getAttribute("classSelected"), "");
		this.classHover = IsNull(this.element.getAttribute("classHover"), "");
		this.classDisabled = IsNull(this.element.getAttribute("classDisabled"), "");
	}

	//vykreslení
	this.paint = function(_tag, _akt, _ws)
	{
		var tag = (_tag == null) ? GetTag(this.comboBox._item_name + this.index) : _tag;
		var akt = IsNull(_akt, true);
		var ws = IsNull(_ws, false);
		var selected = this.isSelected();
		var hovered = this.isHovered();
		var dhtml = false;
		//... aktualizace obsahu
		//... - z důvodu vnějšího zásahu přes DHTML
		if (akt) {
			var tag2 = GetTag(selected ? this.comboBox._selected_name : this.comboBox._item_name + this.index);
			if (IsNull(this.text, "") != "" && _tag != null) {
				dhtml = (this.text != tag2.innerHTML);
				this.text = tag2.innerHTML;
			} else {
				var buf = (IsNull(this.text, "") != "" ? tag.innerHTML : tag2.innerHTML);
				dhtml = (this.content != buf);
				this.content = buf;
			}
		}
		//... obsah
		//... ... atribut text je naplněn a zápis je prováděn do selected
		if (IsNull(this.text, "") != "" && _tag != null) {
			if (tag.innerHTML != this.text || dhtml) tag.innerHTML = this.text;
		//... ... jinak se přiřadí obsah elementu item
		} else {
			if (tag.innerHTML != this.content || dhtml) tag.innerHTML = this.content;
		}
		//... styl
		if (_tag == null) {
			if (!this.enabled && this.classDisabled != "") tag.className = this.classDisabled;
			else if (selected && this.classSelected != "") tag.className = this.classSelected;
			else if (hovered && this.classHover != "") tag.className = this.classHover;
			else tag.className = this.classDefault;
		}
		//... pokud je vybrán
		if (selected && _tag == null && !ws) {
			var tag = GetTag(this.comboBox._selected_name);
			this.paint(tag, akt);
		};
	}
	
	//najde nasledujici povolenou polozku
	this.getNextEnabledItem = function()
	{
		return this.comboBox.getNextEnabledItem(this);
	}	
	
	//najde predchozi povolenou polozku
	this.getPreviousEnabledItem = function()
	{
		return this.comboBox.getPreviousEnabledItem(this);
	}	
	
	//výběr
	this.select = function(AWithoutCollapse)
	{
		if (!this.enabled) return false;
		if (this.isSelected()) {
			if (this.comboBox.expanded) this.comboBox.collapse();
			else this.comboBox.expand();
			return false;
		}
		//... událost - onChanging
		if (!this.comboBox.fireEvent("onChanging", this)) return false;
		//... nastavení hodnoty
		var old = this.comboBox.selected;
		this.comboBox.selected = this;
		if (IsNull(this.name, "") != "") {
			var input = GetTag(this.comboBox.name);
			if (input != null) input.value = this.value;
		}
		//... překreslení
		if (old != null) old.paint();
		this.paint(null, false);
		//... zavření listu
		if (!AWithoutCollapse) {
			this.comboBox.collapse();
		}
		//... událost - onChange
		this.comboBox.fireEvent("onChange");
	}

	//přejetí myší
	this.hover = function()
	{
		if (!this.enabled) return false;
		if (this.isHovered()) return false;
		//... nastavení
		var old = this.comboBox.hovered;
		this.comboBox.hovered = this;
		//... překreslení
		if (old != null) old.paint();
		this.paint();
	}
	
	//test - selected
	this.isSelected = function()
	{
		return (this.comboBox.selected != null && this.comboBox.selected.index == this.index);
	}
	
	//test - hovered
	this.isHovered = function()
	{
		return (this.comboBox.hovered != null && this.comboBox.hovered.index == this.index);
	}

	//zachycení událostí prvků
	//... ITEM - OnClick
	this._handle_click = function(AElement)
	{
		this.select();
		this.comboBox.focus();
		return false;
	}
	
	//... ITEM - OnMouseOver
	this._handle_mouseover = function(AElement)
	{
		this.hover();
	}
	
	//inicializace
	this.init();
}

//---------------------------------------------------------------------------------------------------
//  ZACHYCENÍ GLOBÁLNÍCH UDÁLOSTÍ
//---------------------------------------------------------------------------------------------------

//... vrací objekt TComboBox dle obsaženého elementu
function FindComboBox(AElement)
{
	do {
		var tag = (!tag ? AElement : tag.parentNode);
		var tmp = ((tag.name && IsNull(tag.name, "") != "" ? tag.name : tag.id) + "").split("_");
		if (tmp.length >= 2 && tmp[0].toLowerCase() == "combobox") {
			var combo = document.comboBoxes[tmp[1]];
			if (combo == null) combo = document.comboBoxes[parseInt(tmp[1])];
			return combo;
		}
	}	while (tag != null && tag.parentNode != null) // && tag != tag.parentNode)
	return null;
}

//... COMBO - OnKeyDown
document.onkeydown = function(e)
{
	var evt = (e == null ? event : e);
	var src = (evt.srcElement ? evt.srcElement : evt.target);
	var combo = FindComboBox(src);
	if (combo != null) {
		return combo._handle_keydown(src, evt);
	}
	return true;
};

//... zavření všech comb
//... ... click, kdekoliv mimo komponentu
document.onclick = function(e)
{
	var evt = (e != null ? e : event);
	var src = (evt.srcElement ? evt.srcElement : evt.target);
	var combo = FindComboBox(src);
	if (combo == null) {
		for (var i = 0; i < document.comboBoxes.length; i ++) document.comboBoxes[i].collapse();
	}
}

//---------------------------------------------------------------------------------------------------
//  INICIALIZAČNÍ FUNKCE
//---------------------------------------------------------------------------------------------------
function InitComboBoxes()
{
	//načtení všech komponent TComboBox
	//var temp = document.getElementsByTagName("comboBox");
	var temp = GetElements("comboBox");
	for (var i = 0; i < temp.length; i ++) {
		var exists = ((temp[i].getAttribute("_instance_exists") + "") == "1");
		if (!exists) {
			document.comboBoxes[document.comboBoxes.length] = new TComboBox(temp[i]);
		}
	}
}

//]]>
