//combo.js
//Written by Linn White
//Written on April 13, 2006
//Do not remove, modify, or otherwise hide the author information above this line
//This work falls under the creative-commons license.
//See http://creativecommons.org/licenses/by-sa/3.0/ for details.
//Usage:
//Add the following to any onload statement of  your html document
//var myComboBox = new Combo(100, document.getElementById('textbox'));
//100 is the height of your combo selection window, and 'textbox' is the id of the textbox that you want to convert.
//To add options use the following code:
//myComboBox.addOption('Item 1');

// myHeight - высота списка
// comboText - текстовое поле к которому присоединяется combo
// comboHidden - hidden поле в которое пишется id выбранного элемента, 
// multi - признак мультивыбора, 
// autoSubmitFunction - функция, которая вызывается при смене элемента (если не пустая строка)
// outerContainer - контейнер, обрамляющий контрол (div, span)

function Combo(myHeight, comboText, comboHidden, autoSubmitFunction, outerContainer, borderWidth, isHiddenOuter)
{
	var comboObject = this;
	var multi = false;
	comboObject.version = '0.5';
	var textValues = new Array();
	var idValues = new Array(); // соответствие ID объектов в списке select и их ID вставляемых в скрытое поле
	var newText;
	var defaultText = ''; 
	var comboIDS = 0;
	var activeOption = '';

	var isIE = false;
	var navAgent = new String (navigator.userAgent);
	if ((navigator.appName == 'Microsoft Internet Explorer') && (navAgent.indexOf ('MSIE') >= 0) && (navAgent.indexOf ('Opera') < 0)) {
		isIE = true;
	}

	//Create our combo box elements
	var comboDiv = document.createElement('div');
	var comboFrame = document.createElement('iframe');
	var comboButton = document.createElement('input');

	//Set our styles, positioning, etc.
	//The text box we are converting
	comboText.style.position = 'relative';
	comboText.setAttribute('autocomplete', 'off');
	//Combo Div.  Container for the options
	comboDiv.style.position = 'absolute';
	comboDiv.style.display = 'none';
	comboDiv.style.zIndex = '101';
	comboDiv.style.backgroundColor = '#ffffff';
	comboDiv.style.border = '1px solid #000000';
	comboDiv.style.overflow = 'auto';
	comboDiv.style.height = myHeight + 'px';
	//Combo Button.  Displays/hides the combo div
	comboButton.type = 'button';
	comboButton.style.textAlign = 'center';
	comboButton.style.position = 'absolute';

	comboButton.value = '';
	comboButton.style.zIndex = '100';
	comboButton.style.width = '18px';
	comboButton.className = 'combo';
	//Combo Frame.  Used to hide form elements in IE
	comboFrame.style.position = 'absolute';
	comboFrame.style.display = 'none';
	comboFrame.style.zIndex = '100';
	comboFrame.src = 'javascript:void(0)';
	comboFrame.style.width = comboText.offsetWidth + 'px';
	comboFrame.style.height =  myHeight - 1 + 'px';
	comboFrame.frameBorder = '0';
	
	// Перерисовка объектов ComboBox при изменении окружения
	comboObject.Adjust = function()
	{
		if (isIE) {
			controlTop = getElementTop (outerContainer);
		} else {
			controlTop = comboText.offsetTop;
		}
		comboButton.style.height = comboText.offsetHeight - (borderWidth * 2) + 'px';
		comboDiv.style.width = comboText.offsetWidth + 'px';	
		comboDiv.style.left = comboText.offsetLeft + 'px';
		comboDiv.style.top = controlTop + comboText.offsetHeight - borderWidth + 1 + 'px';
		comboFrame.style.left = comboText.offsetLeft + 'px';
		comboFrame.style.top = controlTop + comboText.offsetHeight - borderWidth + 1 + 'px';
		comboButton.style.left = comboText.offsetLeft + comboText.offsetWidth - comboButton.offsetWidth +'px';
		comboButton.style.top = controlTop + borderWidth + 'px';
	}
	
	//Hide the combobox if we click anywhere except our button.
	function hideCombo(e) 
	{
		activeOption = '';
		e = (e == null) ? window.event : e;
		target = (e.target) ? e.target : e.srcElement;
		if(target == comboButton)
		{
			return;
		}
		else
		{
			comboDiv.style.display = 'none';
			comboFrame.style.display = 'none';
		}
		comboDiv.scrollTop = 0; 
		var divOptions = comboDiv.getElementsByTagName('div');
		for(var i = 0; i < divOptions.length; i++)
		{
			divOptions[i].style.backgroundColor = '#ffffff';
			divOptions[i].style.color = '#000000';
		}

	}

	//Show matching items
	function showMatch(keycode) 
	{
		comboHidden.value = ''; // сотрём выбранный пункт если оный был
		var divOptions = comboDiv.getElementsByTagName('div');
		var newIndex;
		var mustMoveCursor = false;
		var isNotEnter = true;
		if (keycode == 40) { // вниз
			mustMoveCursor = true;
			filtOptions = checkMatch ();
			if (activeOption) { // combo расктыт, выбрана опция
				newIndex = '';
				for(var i = 0; i < filtOptions.length; i++)
				{
					if (filtOptions[i].id == activeOption) {
						newIndex = filtOptions[i + 1].id;
						if (i + 1 >= filtOptions.length) {
							newIndex = filtOptions[0].id;
						}
					}
				}
			} else { // combo не раскрыт
				comboDiv.style.display = 'block';
				comboFrame.style.display = 'block'
				showFiltOptions (filtOptions);
				newIndex = filtOptions[0].id;
			}

		} else if (keycode == 38) { // вверх
			mustMoveCursor = true;
			filtOptions = checkMatch ();
			if (activeOption) { // combo расктыт, выбрана опция
				newIndex = 0;
				for(var i = 0; i < filtOptions.length; i++)
				{
					if (filtOptions[i].id == activeOption) {
						newIndex = filtOptions[i - 1].id;
						if (i - 1 < 0) {
							newIndex = filtOptions[filtOptions.length - 1].id;
						}
					}
				}
			} 
		} else if (keycode == 36) { // home
			mustMoveCursor = true;
			filtOptions = checkMatch ();
			newIndex = filtOptions[0].id;
		} else if (keycode == 35) { // end
			mustMoveCursor = true;
			filtOptions = checkMatch ();
			newIndex = filtOptions[filtOptions.length - 1].id;
		} else if (keycode == 9) { // tab
			//
		} else if (keycode == 13) { // enter
			//
			isNotEnter = false;
			if (activeOption) {
				submitOption (document.getElementById(activeOption));
			}
		} else if (keycode == 27) { // esc
			hideCombo(0);
		} else { // любая другая кнопка		
			//activeOption = ''; // сбросим активную опцию
			filtOptions = checkMatch ();
			if (filtOptions.length > 0) { // найдены совпадения либо полный список
				comboDiv.style.display = 'block';
				comboFrame.style.display = 'block';
				showFiltOptions (filtOptions);
			} else {
				comboDiv.style.display = 'none';
				comboFrame.style.display = 'none';
			}
		}
		if (mustMoveCursor) {
			if (activeOption) {
				var oldOption = document.getElementById(activeOption);
				oldOption.style.backgroundColor = '#ffffff';
				oldOption.style.color = '#000000';
			}
			newOption = document.getElementById(newIndex);
			newOption.style.backgroundColor = '#6699cc';
			newOption.style.color = '#ffffff';
			activeOption = newOption.id;
			if (comboDiv.scrollTop + newOption.offsetTop + newOption.offsetHeight >= myHeight) {
				comboDiv.scrollTop = newOption.offsetTop - myHeight + newOption.offsetHeight;
			}
		}
		return (isNotEnter);
	}

	// Сбросим опции и проверим список на совпадение
	function checkMatch () {
		var divOptions = comboDiv.getElementsByTagName('div');
		var filteredOptions = new Array; 
		var j = 0;
		for(var i = 0; i < divOptions.length; i++)
		{
			if (((comboText.value != "") && (divOptions[i].innerHTML.replace(/\<.*?\>/ig, '').toLowerCase().indexOf(comboText.value.toLowerCase()) != '-1')) || (comboText.value == "") || (comboText.value == defaultText)) {
				filteredOptions[j] = divOptions[i];
				j++;
			}
		}
		return (filteredOptions);
	}

/*
s='';
for(var i = 0; i < filtOptions.length; i++)
{
	s=s+filtOptions[i].id;
}
alert(s);
*/

	// показать отфильтрованный список
	function showFiltOptions (optList) {
		var divOptions = comboDiv.getElementsByTagName('div');
		for(var i = 0; i < divOptions.length; i++)
		{
			divOptions[i].style.display = 'none';
		}
		for(var i = 0; i < optList.length; i++)
		{
			optList[i].style.display = 'block';
		}
	}

	//Show the combo div and frame
	function showCombo()
	{
		var divOptions = comboDiv.getElementsByTagName('div');
		for(var i = 0; i < divOptions.length; i++)
		{
			divOptions[i].style.display = 'block';
		}
		if (comboDiv.style.display == 'none') 
		{
			comboDiv.style.display = 'block';
			comboFrame.style.display = 'block'
		}
		else 
		{
			comboDiv.style.display = 'none';
			comboFrame.style.display = 'none'		
			activeOption = '';
		}
	}

	// нажали ентер или кликнули мышой по option
	function submitOption (comboOption) {
		comboHidden.value = idValues[comboOption.id]; // установим скрытое поле для выбранного индекса
		if(!multi)
		{
			comboText.value = comboOption.value.replace(/\&nbsp;/ig, '');
			comboDiv.style.display = 'none';
			comboFrame.style.display = 'none';
			if (autoSubmitFunction != '') { // нужен ли автосабмит формы
				setTimeout (autoSubmitFunction, 0); 
			}
			return;
		}
		comboOption.selected = (comboOption.selected) ? false : true ;
		comboOption.style.color = (!comboOption.selected) ? '#000000' : '#ffffff';
		comboOption.style.backgroundColor = (!comboOption.selected) ? '#ffffff' : '#333399';
		if(comboOption.selected)
		{
			newText = '';
			textValues[comboOption.id] = comboOption.value;
			for(var i in textValues)
			{
				if(textValues[i])
				{
					newText += textValues[i] + ',';
				}
			}
			comboText.value = newText.substring(0, newText.length - 1);
		}
		else
		{
			delete textValues[comboOption.id];
			newText = '';
			for(var i in textValues)
			{
				if(textValues[i])
				{
					newText += textValues[i] + ',';
				}
			}
			comboText.value = newText.substring(0, newText.length - 1);
		}
	}
	

	//Create divs for our options.
	comboObject.addOption = function(comboOptionText, comboOptionID)
	{
		var comboOption = document.createElement('div')
		comboOption.innerHTML = comboOptionText;
		comboOption.value = comboOptionText;
		comboOption.style.color = '#000000';
		comboOption.style.backgroundColor = '#ffffff';
		comboOption.style.cursor = 'pointer';
		comboOption.style.paddingLeft = '3px';
		comboOption.selected = false;
		comboOption.style.fontSize = '13px';
		comboOption.id = comboText.name + '_combo' + comboIDS;
		idValues[comboOption.id] = comboOptionID; // сохраним в массиве ID опции для дальнейшей работы
		comboIDS++;

		comboOption.onmouseover = function() // навели мышу
		{
			if(comboOption.selected)
			{
				return;
			}
			comboOption.style.backgroundColor = '#6699cc';
			comboOption.style.color = '#ffffff';
			activeOption = comboOption.id;
		}

		comboOption.onmouseout = function() // убрали мышу
		{
			if(comboOption.selected)
			{
				return;
			}
			comboOption.style.backgroundColor = '#ffffff';
			comboOption.style.color = '#000000';
			activeOption = '';
		}

		comboOption.onclick = function() // жмякнули мышой
		{
			submitOption (comboOption);
		}

		comboDiv.appendChild(comboOption);
	}
	
	comboObject.deleteOptions = function(index)
	{
		if(typeof(index) == 'number')
		{
			if(comboDiv.childNodes[index])
			{
				delete textValues[comboDiv.childNodes[index].id];
				delete idValues[comboDiv.childNodes[index].id];
				comboDiv.removeChild(comboDiv.childNodes[index]);
			}
		}
		else
		{
			while(comboDiv.firstChild)
			{
				comboDiv.removeChild(comboDiv.firstChild);
			}
			textValues = [];
			comboIDS = 0;
		}
	}

	comboObject.setSelection = function(selected_ind)
	{
		for(var i in idValues)
		{
			if (idValues[i] == selected_ind)
			{
				comboHidden.value = idValues[i];
				comboOption = document.getElementById(i);
				comboText.value = comboOption.value.replace(/\&nbsp;/ig, '');
				defaultText = comboText.value;
				comboDiv.style.display = 'none';
				comboFrame.style.display = 'none';
			}
		}
	}

	
	comboObject.setText = function(text)
	{
		comboText.value = text.replace(/\&nbsp;/ig, '');
		defaultText = comboText.value;
	}

	//Set our callbacks/functions.
	if(window.addEventListener)
	{
		window.addEventListener('resize', function() {comboObject.Adjust()}, false);
		comboText.addEventListener('keyup', function(e) {return (showMatch(e.which));}, false);
		comboButton.addEventListener('click', function() {showCombo()}, false);
		if(!multi)
		{
			window.addEventListener('click', function(e){hideCombo(e)}, false);
		}
		
	}
	else
	{
		window.onresize = function(){comboObject.Adjust()};
		comboText.onkeyup = function(e){return (showMatch(e.which));};
		comboButton.onclick = function(){showCombo()};
		if(!multi)
		{
			document.onclick = function(e){hideCombo(e)};
		}
	}
	comboText.onkeypress = function(e) { var k=e.keyCode||e.which; return k!=13; } // блокировка enter на текстовом поле
	
	//Draw our stuff
	document.body.appendChild(comboDiv);
	document.body.appendChild(comboFrame);
	outerContainer.appendChild(comboButton);
	if (!isHiddenOuter) {
		comboObject.Adjust();
	}
}

// определение позиции объекта на экране
function getElementTop (offsetTrail)
{
	var offsetTop = 0;
	while (offsetTrail) {
		offsetTop += offsetTrail.offsetTop;
		offsetTrail = offsetTrail.offsetParent;
	}
	return (offsetTop);
}

function getElementLeft (offsetTrail)
{
	var offsetLeft = 0;
	while (offsetTrail) {
		offsetLeft += offsetTrail.offsetLeft;
		offsetTrail = offsetTrail.offsetParent;
	}
	return (offsetLeft);
}
