/****************************************************************************************************/
/*	WHO.Auto Complete version 1.01.0010																*/
/*		Copyright (c) 2001-2010 by FAR/RAKUDA														*/
/*		All Rights Reserved																			*/
/*		Last Modified at 2010.07.13																	*/
/****************************************************************************************************/
var WHO = WHO || {};
WHO.AutoComplete = function(input,item,filter)
{
	//input  : HTML element Object : input 要素
	//item   : Array               : 補完リスト
	//filter : function(itemValue) : 補完フィルタ

	//this.input    : 入力フォーム
	//this.list     : オートコンプリートリスト
	//this.filter   : フィルター
	//this.select   : 選択中のアイテム（要素）
	//this.value    : 
	this.focused = false;//フォーカス中

	//リスト選択時のフィルター
	this.filter = filter || function(item,value)
	{
		return (item.indexOf(value,0) > -1);
	};
	this.value  = "whoautocompleteselectedvaluedammy";

	//ドロップダウンリストの作成
	this.list = this.createListContainer();
	document.body.appendChild(this.list);

	//ドロップダウンにアイテムを追加する
	this.addList(item);

	//入力フォームの登録
	if(input)
	{
		this.input = input;
		this.adjustPosition();
		this.registForm(input);
	}
	this.updateList();
	//アイテムの選択
	/*アイテム上にマウスが移動*/
	function _focusItemMouse(auto)
	{
		return function(e)
		{
			var item = e.target;
			if(item != auto.list)
			{
				while(item.parentNode != auto.list)
				{
					item = item.parentNode;
				}
				auto.focusItem(item);
			}
		}
	}
	this.list.addEventListener('mouseover',_focusItemMouse(this),false);
	/*アイテムをフォームに入力する*/
	function _setValueMouse(auto)
	{
		return function(e)
		{
			var item = e.target;
			auto.focused = true;
			if(item != auto.list)
			{
				while(item.parentNode != auto.list)
				{
					item = item.parentNode;
				}
				if(auto.input.value != item.getAttribute('title'))
				{
					auto.input.value = item.getAttribute('title');
					auto.blurItem();
					auto._changeEvent();
				}
			}
		}
	}
	this.list.addEventListener('mousedown',_setValueMouse(this),false);
	this.list.addEventListener('mouseup',(function(auto){return function()
	{
		auto.input.focus();
	}})(this),false);
//	this.list.addEventListener('keypress',(function(auto){return function(e){auto.keyCheck(e)}})(this),false);

	//リストを更新
	this.list.addEventListener('click',(function(auto){return function(){auto.updateList()}})(this),false);
//	setInterval((function(auto){return function(){auto.updateList()}})(this),1000);//日本語用

	return this;
}
/*ドロップダウンリストの作成*/
WHO.AutoComplete.prototype.createListContainer = function()
{
	var list = document.createElement('div');
		list.style.position   = "absolute";
		list.style.zIndex     = "1000";
		list.style.display    = "none";
		list.style.background = "#fff";
		list.style.color      = "#000";
		list.style.border     = "1px solid black";
		list.style.margin     = "0";
		list.style.padding    = "0";
		list.style.textAlign  = "left";
		list.style.fontSize   = "9pt";
		list.style.lineHeight = "1.0em";
		list.style.whiteSpace = "nowrap";
		list.style.maxHeight  = "20em";
		list.style.overflow   = "auto";
	return list;
}
/*リストコンテナにリストを追加*/
WHO.AutoComplete.prototype.addList = function(list)
{
	for(var i = 0;i < list.length;i++)
	{
		this.addNewItem(list[i]);
	}
}
/*リストを全て削除*/
WHO.AutoComplete.prototype.removeList = function()
{
	var list = this.list.firstChild;
	while(list)
	{
		var rem = list;
		list = list.nextSibling;
		this.list.removeChild(rem);
	}
}
/*ドロップダウンリストにアイテムを追加する*/
WHO.AutoComplete.prototype.addNewItem = function(value)
{
	var item = this.createItem(value);
	this.list.appendChild(item);
	return item;
}
/*アイテムの作成*/
WHO.AutoComplete.prototype.createItem = function(value)
{
	var item = document.createElement('span');
	item.style.display       = "block";
	item.style.clear         = "both";
	item.style.margin        = "0";
	item.style.padding       = "0";
//	item.style.width         = "100%";
	item.style.lineHeight    = "16px";
	item.style.overflow      = "hidden";
	item.style.OTextOverflow = "ellipsis";

	if(typeof(value) == 'object' && value[1])
	{
		item.setAttribute('title',value[0]);

		var text = document.createElement('span');
		text.style.display       = "block";
		text.style.styleFloat    = "left";
		text.style.margin        = "0";
		text.style.padding       = "0";
//		text.style.height        = "1em";
		text.style.lineHeight    = "16px";
		text.style.overflow      = "hidden";
		text.style.OTextOverflow = "ellipsis";
		text.appendChild(document.createTextNode(value[0]));
		item.appendChild(text);

		if(value[1])
		{
			var opti = document.createElement('sup');
			opti.style.display       = "block";
			opti.style.styleFloat    = "right";
			opti.style.margin        = "0";
			opti.style.padding       = "0";
//			opti.style.height        = "1em";
			opti.style.textAlign     = "right";
			opti.style.fontSize      = "0.5em";
			opti.style.color         = "red";
			opti.appendChild(document.createTextNode(value[1]));
			item.appendChild(opti);
		}
	}
	else
	{
		item.setAttribute('title',value);
		item.appendChild(document.createTextNode(value));
	}
	return item;
}
/*input フォームを登録*/
WHO.AutoComplete.prototype.registForm = function(input)
{
	input.setAttribute('autocomplete',"off");		//デフォルトのオートコンプリートを禁止
	//選択リストボックスを表示
	input.addEventListener('focus',(function(auto,input)
	{
		return function()
		{
			if(!input.getAttribute('disabled'))
			{
				if(!auto.focused)
				{
					auto.input = input;
					auto.list.style.display="block";
					auto.updateList();
					auto.adjustPosition();
					auto.blurItem();
				}
			}
		}
	})(this,input),false);
	//選択リストボックスを隠す
	input.addEventListener('blur',(function(auto)
	{
		return function()
		{
			if(auto.focused)
			{
				auto.input.focus();
				auto.focused = false;
			}
			else
			{
				auto.list.style.display="none";
			}
		}
	})(this),false);
	input.addEventListener('keypress',(function(auto){return function(e){auto.keyCheck(e)}})(this),false);
	//リストを更新
//	keypress では input の内容が更新される前にイベントが発生
//	input.addEventListener('keypress',(function(auto){return function(){auto.updateList()}})(this),false);
//	input.addEventListener('keyup',(function(auto){return function(){auto.updateList()}})(this),false);
	input.addEventListener('input',(function(auto){return function(){auto.updateList()}})(this),false);
}
/*chage イベントを発生させる*/
WHO.AutoComplete.prototype._changeEvent = function()
{
//	this.defaultValue = this.input.value;
//	this.edited  = false;//変更していない
	var event = document.createEvent('HTMLEvents');
	event.initEvent("change",true,false);
	this.input.dispatchEvent(event);
}
/*リストの位置を修正*/
WHO.AutoComplete.prototype.adjustPosition = function()
{
	var body = window.getComputedStyle(document.body,'');
	
	var top  = 0;
	var left = 0;
//	opera.postError(document.offsetTop);
	var elem = this.input;//.offsetParent;
//	if(body.getPropertyValue("position")=="absolute")
//	{
//		top  = top  - parseInt(body.getPropertyValue("margin-top"),10)  - parseInt(body.getPropertyValue("border-top-width"),10);
//		left = left - parseInt(body.getPropertyValue("margin-left"),10) - parseInt(body.getPropertyValue("border-left-width"),10);
//	}
	if(body.getPropertyValue("position")=="absolute" || body.getPropertyValue("position")=="relative")
	{
		top  = top  - parseInt(body.getPropertyValue("top"),10)  - parseInt(body.getPropertyValue("margin-top"),10)  - parseInt(body.getPropertyValue("border-top-width"),10);
		left = left - parseInt(body.getPropertyValue("left"),10) - parseInt(body.getPropertyValue("margin-left"),10) - parseInt(body.getPropertyValue("border-left-width"),10);
	}
	while(elem)
	{
		top  = top + elem.offsetTop;
		left = left + elem.offsetLeft;
		elem = elem.offsetParent; 
	}
	this.list.style.top  = top + "px";
	this.list.style.left = left + "px";
	this.list.style.padding    = "0";
	this.list.style.margin     = "0";
	this.list.style.marginTop  = this.input.offsetHeight+"px";
	var maxWidth               = this.input.offsetWidth - 2;
	this.list.style.width   = maxWidth + "px";
}
/*入力フォームでキーを押下*/
WHO.AutoComplete.prototype.keyCheck = function(e)
{
	/*右*/
	if(this.select && (e.keyCode == 13 || e.keyCode == 39))
	{
		var value = this.select.getAttribute('title');
		if(this.input.value != value)
		{
			this.input.value = value;
			this._changeEvent();
		}
		this.blurItem();
	}
	/*下*/
	if(e.keyCode==40)
	{
		this.input.focus();
		this.selectNext();
//		e.stopPropagation();
	}
	/*上*/
	else if(e.keyCode==38)
	{
		this.input.focus();
		if(this.select)
		{
			this.selectPrevious();
		}
		else if(this.list.style.display=="none")
		{
			this.selectPrevious();
		}
		else
		{
			this.list.style.display="none";
		}
	}
}

/*ドロップダウンリストを更新する*/
WHO.AutoComplete.prototype.updateList = function()
{
	var span  = this.list.firstChild;
	var value = this.input ? this.input.value : "";
	var sw;
	//文字列増加
	if(this.value && value.indexOf(this.value)>-1)sw = 1;
	//文字列減少
	else if(value && this.value.indexOf(value)>-1)sw = 2;
	//その他
	else if(this.value != value)sw = 3;
	while(span)
	{
		var item = span.getAttribute('title');
		switch(sw)
		{
			//文字列増加
			case 1:
			if(span.style.display=="block")
			{
				if(!this.filter(item,value))
				{
					span.style.display="none";
					if(span == this.select)
					{
						this.selectPrevious(this.select);
					}
				}
			}
			break;
			//文字列減少
			case 2:
			if(span.style.display=="none")
			{
				if(this.filter(item,value))
				{
					span.style.display="block";
				}
			}
			break;
			//その他
			case 3:
			if(this.filter(item,value))
			{
				span.style.display="block";
			}
			else
			{
				span.style.display="none";
				if(span == this.select)
				{
					this.selectPrevious(this.select);
				}
			}
			break;
		}
		span = span.nextSibling;
	}
	this.value = value;
}
/*次のアイテムを選択*/
WHO.AutoComplete.prototype.selectNext = function()
{
	if(!this.select)
	{
		this.list.style.display="block";
		this.focusItem(this.list.firstChild);
	}
	else
	{
		this.focusItem(this.select.nextSibling);
	}
	if(this.select)
	{
		if(this.select.style.display == 'none')
		{
			this.selectNext();
		}
	}
	if(this.select)
	{
		if(this.list.scrollTop > this.select.offsetTop || this.list.scrollTop < this.select.offsetTop - this.list.offsetHeight + this.select.offsetHeight * 4)
		{
			this.list.scrollTop = this.select.offsetTop - this.list.offsetHeight + this.select.offsetHeight * 4;
		}
	}
}
/*前のアイテムを選択*/
WHO.AutoComplete.prototype.selectPrevious = function()
{
	if(!this.select)
	{
		this.list.style.display="block";
		this.focusItem(this.list.lastChild);
	}
	else
	{
		this.focusItem(this.select.previousSibling);
	}
	if(this.select)
	{
		if(this.select.style.display == 'none')
		{
			this.selectPrevious();
		}
	}
	if(this.select)
	{
		if(this.list.scrollTop > this.select.offsetTop - this.select.offsetHeight * 4 || this.list.scrollTop < this.select.offsetTop - this.list.offsetHeight - this.select.offsetHeight * 4)
		{
			this.list.scrollTop = this.select.offsetTop - this.select.offsetHeight * 4;
		}
	}
}
/*アイテムをフォーカスする*/
WHO.AutoComplete.prototype.focusItem = function(item)
{
	this.blurItem();
	if(item)
	{
		this.select = item;
		item.style.backgroundColor="#00c";
		item.style.color="#fff";
	}
}
/*アイテムのフォーカスをはずす*/
WHO.AutoComplete.prototype.blurItem = function()
{
	if(this.select)
	{
		this.select.style.backgroundColor="";
		this.select.style.color="";
	}
	this.select=undefined;
}

