
/*
 * グローバル変数
 */
var worriedWindowsNumber = 100;
var formElement;	// FORM要素ノード
var inputElements;	// INPUT要素ノード集合

if (document.getElementById)
	addEvent(window, "load", initialize);

/*
 * ページ読込み後に実行される関数
 */
function initialize() {
	formElement   = document.getElementsByTagName("form")[0];
	inputElements = document.getElementsByTagName("input");

	/* ラジオボタンをチェックボックスに変える */
	changeRadioButtons()

	/* 一括選択用のチェックボックスを追加する */
	addBatchCheckBoxes();

	/* フォームの送信時にイベントを設定 */
	addEvent(formElement, "submit", validateForm);
	/*addEvent(formElement, "submit", saveHistory);*/

	/* フォームの消去時にイベントを設定 */
	addEvent(formElement, "reset", setFocus);

	/* 検索語欄にフォーカスをあわせる */
	setFocus();

	/*addHistoryBox(formElement);*/
}

/*
 * 一括選択用のチェックボックスを追加する
 */
function addBatchCheckBoxes() {
	var h2Elements = document.getElementsByTagName("h2");
	var labelElement, inputElement, labelChildes;

	for (var i = 0; i < h2Elements.length; i++ ) {
		inputElement = createInputElement("checkbox", "", "");
		labelElement = document.createElement("label");
		labelChildes = h2Elements[i].childNodes;
		labelElement.appendChild(inputElement);
		while (labelChildes.length)
			labelElement.appendChild(labelChildes[0]);
		h2Elements[i].appendChild(labelElement);
		addEvent(inputElement, "change" , checkBoxesByBatch);

		/* MSIEはchangeイベントタイプに非対応の模様 */
		addEvent(inputElement, "click" , checkBoxesByBatch);
	}
}

/*
 * チェックボックスを一括で選択する
 */
function checkBoxesByBatch(e) {
	var batchCheck = e.target.nodeName.toLowerCase() == "input" ?
	                 e.target : e.target.firstChild;
	var h2Element  = batchCheck.parentNode.parentNode; /* 親の親 */
	var ulElement  = node_after(h2Element);            /* その弟 */
	var checkBoxes = ulElement.getElementsByTagName("input");

	for (var i = 0; i < checkBoxes.length; i++)
		checkBoxes[i].checked = batchCheck.checked;
}

/*
 * すべてのラジオボタンをチェックボックスに変える
 */
function changeRadioButtons() {
	var checkBox;

	/*
	 * MSIEがINPUT要素のtype属性の書き換えに対応していないので、
	 * 要素を丸ごと置換する。
	 */
	for (var i = 0; i < inputElements.length; i++) {
		if (inputElements[i].type != "radio") continue;
		/* name属性値を変更しておく */
		checkBox = createInputElement("checkbox",
				"", inputElements[i].value);
		inputElements[i].parentNode.replaceChild(
				checkBox, inputElements[i]);
	}

	/* value属性値をコピーするための隠しフィールド */
	formElement.appendChild(createInputElement("hidden", "engine"));
}

/*
 * フォームの内容を検証し、送信する
 */
function validateForm(e) {
	var engines = new Array();
	var i;
	
	/* 検証 */
	if (formElement.elements.query.value == "") {
		alert("検索語を入力してください。");
		formElement.elements.query.focus();
		e.preventDefault();
		return;
	}
	
	/* 送信 */
	for (i = 0; i < inputElements.length; i++) {
		if (!inputElements[i].checked) continue;
		if (!inputElements[i].value  ) continue;
		/* Operaが勝手に設定するvalueは無視する */
		if (inputElements[i].value == "on") continue;
		/* value属性値をコピー */
		engines[engines.length] = inputElements[i].value;
	}
	if (engines.length < worriedWindowsNumber ||
			confirm(engines.length + "個のウィンドウを開きますか。")) {
		for (i = 0; i < engines.length; i++) {
			/* 1回ごとに設定し直さなければならない模様 */
			formElement.setAttribute("target", "_blank");
			formElement.setAttribute("method", "GET");
			/* 隠しフィールドにvalue属性値をコピー */
			formElement.lastChild.value = engines[i];
			formElement.submit();
		}
	}
	e.preventDefault();
}

/*
 * 検索語欄にフォーカスを移動する
 */
function setFocus() {
	formElement.elements.query.focus();
}

/*
 * INPUT要素を生成する
 */
function createInputElement(type, name, value) {
	var element = document.createElement("input");

	element.setAttribute("type" , type );
	element.setAttribute("name" , name );
	element.setAttribute("value", value);
	return element;
}

/*
 * イベントを追加もしくは設定する
 */
function addEvent(target, type, listener) {
	if (window.event)
		listener = EventListenerIE(listener);
	if (target.addEventListener)
		target.addEventListener(type, listener, false);
	else
		target["on" + type] = listener;
}

/*
 * MSIEのためのEventListener
 */
function EventListenerIE(listener) {
	return function() {
		var Event = {
			target         : event.srcElement,
			preventDefault : function() {
				event.returnValue = false
			}
		};
		listener(Event);
	};
}

/*
 * 空白文字を手軽に取り扱えるようにする幾つかの関数
 * 出展: http://www.mozilla-japan.org/docs/dom/technote/whitespace/
 */

/*
 * ノードのテキスト内容が完全に空白であるか判断
 *
 * @param nod  CharacterData インターフェイスを実装したノード
 *             (例: Text, Comment, CDATASection ノード)
 * @return     nod のテキスト内容が全て空白文字であれば true
 *             それ以外は false
 */
function is_all_ws(nod) {
	// ECMA-262 第3版 の String 及び RegExp の機能を使用
	return !(/[^\t\n\r ]/.test(nod.data));
}

/*
 * 反復処理関数がノードを無視するべきかどうか判断
 *
 * @param nod  DOM1 の Node インターフェイスを実装したノード
 * @return     ノードが次のいずれかであれば true:
 *                1) 全て空白文字である Text ノード
 *                2) Comment ノード
 *             それ以外は false
 */
function is_ignorable(nod) {
	return	(nod.nodeType == 8) || // コメントノード
		((nod.nodeType == 3) && is_all_ws(nod)); // 全空白テキストノード
}

/*
 * 完全に空白或いはコメントのノードを無視するようにした nextSibling
 *
 * @param sib  参照ノード
 * @return     次のいずれか:
 *               1) is_ignorable 検査で無視できないと判断された sib に
 *                  最も近い後方の兄弟ノード、或いは
 *               2) 該当するノードがなければ null
 */
function node_after(sib) {
	while ((sib = sib.nextSibling))
		if (!is_ignorable(sib))
			return sib;
	return null;
}


/*
 * 検索履歴を選択するためのプルダウンメニューを追加する
 */
//function addHistoryBox() {
//	var inputElement  = formElement.elements.query;
//	var selectElement = document.createElement("select");
//	var optionElement = document.createElement("option");
//	var optionTextNode = document.createTextNode("▼検索履歴");
//
//	inputElement.parentNode.insertBefore(selectElement,
//		inputElement.nextSibling);
//	selectElement.appendChild(optionElement);
//	optionElement.appendChild(optionTextNode);
//
//	var words = loadHistory() || return;
//
//	for (var i = 0; i < words.length; i++) {
//		optionElement = document.createElement("option");
//		optionTextNode = document.createTextNode(words[i]);
//		selectElement.appendChild(optionElement);
//		optionElement.appendChild(optionTextNode);
//	}
//	addEvent(selectElement, "change", addHistoryWord);
//}

/*
 * 検索履歴を取得する
 */
//function loadHistory() {
//	var cookie = new Cookie();
//	var value  = cookie.get("history");
//
//	if (value == "") return [];
//	return value.split("\n");
//}

/*
 * 検索履歴を保存する
 */
//function saveHistory(words) {
//	var query = formElement.elements.query.value;
//	if (query == "") return;
//
//	var cookie = new Cookie();
//	var words  = loadHistory();
//
//	for (var i = 0; i < words.length; i++)
//		if (query == words[i])
//			return;
//
//	words.unshift(formElement.elements.query.value);
//	cookie.set("history", words.join("\n"), 30);
//}

/*
 * 検索履歴を検索語フィールドにコピーする
 */
//function addHistoryWord(e) {
//	var selectElement = e.target;
//	var queryField = selectElement.form.elements.query;
//
//	with (selectElement)
//		if (selectedIndex != 0)
//			queryField.value = options[selectedIndex].text;
//}

/*
 * クッキーを操作するための汎用クラス
 */
//function Cookie() {
//	this.get = function(name) {
//		var regexp = new RegExp("\\b" + name + "=([^;]*)");
//		return regexp.exec(document.cookie) ?
//			unescape_(RegExp.$1) : "";
//	}
//	this.set = function(name, value, days, path) {
//		var       temp  =   name + "=" + escape_(value);
//		if (days) temp += "; expires=" + expires(days);
//		if (path) temp += "; path="    + path;
//		document.cookie = temp;
//	}
//	function expires(days) {
//		var date = new Date();
//		date.setTime(date.getTime() + days*24*60*60*1000);
//		return date.toGMTString();
//	}
//	/* MSIE5.5未満?は代用品 */
//	var escape_   = encodeURIComponent || escape;
//	var unescape_ = decodeURIComponent || unescape;
//}
