/*
 郵便番号住所の検索と設定
*/

window.onload = function init() {
	//郵便番号住所変換の要素の設定
	var pa = new postalAddress('postalcode', 'btn_addr', 'pref', 'addr1', 'suggest');
}


//
// 郵便番号住所変換クラス
//

//コンストラクタ
function postalAddress(code, button, pref, addr1, suggest) {
	//HTML要素
	this.code = document.getElementById(code);
	this.button = document.getElementById(button);
	this.pref = document.getElementById(pref);
	this.addr1 = document.getElementById(addr1);
	this.suggest = document.getElementById(suggest);
	//イベント設定
	var self = this;
	this.button.onclick = function (){
		self.getAddr();
	}

	//スタイル設定
	this.suggest.style.display = "none";
}

//プロパティとメソッド
postalAddress.prototype = {

	//住所取得URL
	url : "data/",

	//キーコード
	key : {
		TAB:	 9,
		RETURN:	13,
		ESC:	27,
		UP:		38,
		DOWN:	40
	},

	//
	//郵便番号から住所を取得
	//
	getAddr : function() {

		var dir = this.code.value.match(/([0-9])([0-9]{2})-*([0-9]{2})([0-9]{2})/);
		if (dir==null) {
			alert("郵便番号を半角数字７桁で指定してください。");
			this.code.focus();
			return;
		}

		dir = dir.slice(1);
		var url  = this.url + dir.join("/") + ".js";

		this.suggest.innerHTML = "検索中です、しばらくお待ちください。...";
		this.suggest.style.display = "block";

		var xmlhttp = this.createXmlHttpRequest();

		xmlhttp.open("GET", url, true);
	
		var self = this;
		xmlhttp.onreadystatechange = function() { 
			//受信完了
			if (xmlhttp.readyState==4) {
				self.showAddr(xmlhttp);
			}
		}

		xmlhttp.send('');
	},

	//
	//住所の設定
	//
	showAddr : function(xmlhttp) {

		//初期化
		var self = this;
		this.suggest.innerHTML = "";
		this.suggest.style.display = "none";

		//住所の検索結果一覧
		var list = new Array();
		if (xmlhttp.status=="200")
			list = eval(xmlhttp.responseText);
	
		switch (list.length) {
			case 0:
				this.suggest.innerHTML = "郵便番号に該当する住所は見つかりません。";
				this.suggest.style.display = "block";
				//メッセージ解除のイベント設定
				this.code.onblur = function() {
					self.suggest.style.display = "none";
					this.onblur = null;
				}
				this.code.focus();
				break;

			case 1:
				//住所設定
				this.pref.value = list[0].pref;
				this.addr1.value = list[0].addr1 + list[0].addr2 + list[0].addr3;
				//カーソル移動
				this.moveCaret(this.addr1);
				break;

			default:
				//都道府県の設定
				this.pref.value = list[0].pref;

				//住所の選択肢の設定
				for (var i=0; i<list.length; i++) {
					var elm = document.createElement("div");
					elm.innerHTML = list[i].addr1 + list[i].addr2 + list[i].addr3;
					elm.name = i;
					//イベント設定
					elm.onclick = function() {
						self.selectAddr(this);
					}
					elm.onmouseover = function() {
						//ハイライト解除
						this.parentNode.childNodes[self.suggestIndex].className = "";
						//ハイライト設定
						this.className = "select";
						self.suggestIndex = this.name;
					}
					elm.onmouseout = function() {
						//this.className = "";
					}
					this.suggest.appendChild(elm);
				}

				//初期選択
				this.suggestIndex = 0;
				this.suggest.childNodes[this.suggestIndex].className = "select";

				//キー入力のイベント取得の設定
				this.addr1.onkeydown = function(e) {
					return self.checkKey(e); // e for Firefox
				}

				this.addr1.focus();
				this.suggest.style.display = "block";

		}

		//砂時計カーソルを既定値に戻す
		this.button.style.cursor = "auto";

		return true;
	},

	//
	//住所の選択
	//
	selectAddr : function(elm) {
		//住所の設定
		this.addr1.value = elm.innerHTML;
		//カーソル移動
		this.moveCaret(this.addr1);
		//選択候補を非表示
		this.suggest.style.display = "none";
		//イベント解除
		this.addr1.onkeydown = null;
	},

	//
	//入力キーのチェック
	//
	checkKey : function(e) {
		if (e)
			event = e; //e:Firefox event:IE 
		switch (event.keyCode) {
			case this.key.ESC:
			case this.key.TAB:
				this.suggest.style.display = "none";
				//イベント解除
				this.addr1.onkeydown = null;
				break;
			case this.key.UP:
				this.suggest.childNodes[this.suggestIndex].className = "";
				this.suggestIndex = Math.max(--this.suggestIndex, 0);
				this.suggest.childNodes[this.suggestIndex].className = "select";
				break;
			case this.key.DOWN:
				this.suggest.childNodes[this.suggestIndex].className = "";
				this.suggestIndex = Math.min(++this.suggestIndex, this.suggest.childNodes.length-1);
				this.suggest.childNodes[this.suggestIndex].className = "select";
				break;
			case this.key.RETURN:
				this.selectAddr(this.suggest.childNodes[this.suggestIndex]);
				//イベント解除
				this.addr1.onkeydown = null;
				return false;
				break;
		}
		return true;
	},

	//キャレットを文字列の最後に移動
	moveCaret : function(elm) {
		elm.focus();
		if (elm.createTextRange) {
			var range = elm.createTextRange();
			range.move('character', elm.value.length);
			range.select();
		} else if (elm.setSelectionRange) {
			elm.setSelectionRange(elm.value.length, elm.value.length);
		}
	},

	//
	// 非同期通信
	//
	createXmlHttpRequest : function() {
		var xmlhttp = false;
		if( window.XMLHttpRequest) {
			xmlhttp = new XMLHttpRequest();
		} else if(window.ActiveXObject) {
			try {
				xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
			} catch(e) {
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
		}
		return xmlhttp;
	}

}

