// ================================================================
//  addrajax.js ---- ADdress DRilled down by Ajax
//  Copyright 2006 Kawasaki Yusuke <u-suke [at] kawa.net>
//  http://www.kawa.net/works/ajax/addrajax/addrajax.html
// ================================================================

ADDRAjax = function (fpref,fcity,farea) {
	if ( fpref ) this.form_pref = fpref;
	if ( fcity ) this.form_city = fcity;
	if ( farea ) this.form_area = farea;
};

// デフォルト値
ADDRAjax.prototype.JSONDATA = 'addrajax/data';
ADDRAjax.prototype.URL_SUFFIX = '';
ADDRAjax.prototype.form_pref = 'pref';
ADDRAjax.prototype.form_city = 'city';
ADDRAjax.prototype.form_area = 'area';
ADDRAjax.prototype.onChange = function(pref,city,area){};

// エリアの一覧
ADDRAjax.prototype.AREA_MAP = [
    null,       '北海道',   '東北',   '関東',   '東海・北陸',   
    '関西',     '中国・四国',   '九州'
];

// エリア（北海道地区）の一覧
ADDRAjax.prototype.AREA1_MAP = [
    null,       '北海道'
];
ADDRAjax.prototype.AREA1_MAP_NUM = [
    null,       '1'
];

// エリア（東北地区）の一覧
ADDRAjax.prototype.AREA2_MAP = [
    null,       '青森県',   '岩手県',   '宮城県',   '秋田県',
    '山形県',   '福島県'
];
ADDRAjax.prototype.AREA2_MAP_NUM = [
    null,       '2',        '3',        '4',        '5',
    '6',        '7'
];

// エリア（関東地区）の一覧
ADDRAjax.prototype.AREA3_MAP = [
    null,       '茨城県',   '栃木県',   '群馬県',   '埼玉県',
    '千葉県',   '東京都',   '神奈川県'
];
ADDRAjax.prototype.AREA3_MAP_NUM = [
    null,       '8',        '9',        '10',       '11',
    '12',       '13',       '14'
];

// エリア（東海・北陸地区）の一覧
ADDRAjax.prototype.AREA4_MAP = [
    null,       '新潟県',   '富山県',   '石川県',   '福井県',
    '山梨県',   '長野県',   '岐阜県',   '静岡県',   '愛知県',
    '三重県'
];
ADDRAjax.prototype.AREA4_MAP_NUM = [
    null,       '15',       '16',       '17',       '18',
    '19',       '20',       '21',       '22',       '23',
    '24'
];

// エリア（関西地区）の一覧
ADDRAjax.prototype.AREA5_MAP = [
    null,       '滋賀県',   '京都府',   '大阪府',   '兵庫県',
    '奈良県',   '和歌山県'
];
ADDRAjax.prototype.AREA5_MAP_NUM = [
    null,       '25',       '26',       '27',       '28',
    '29',       '30'
];

// エリア（中国・四国地区）の一覧
ADDRAjax.prototype.AREA6_MAP = [
    null,       '鳥取県',   '島根県',   '岡山県',   '広島県',
    '山口県',   '徳島県',   '香川県',   '愛媛県',   '高知県'
];
ADDRAjax.prototype.AREA6_MAP_NUM = [
    null,       '31',       '32',       '33',       '34',
    '35',       '36',       '37',       '38',       '39'
];

// エリア（九州地区）の一覧
ADDRAjax.prototype.AREA7_MAP = [
    null,       '福岡県',   '佐賀県',   '長崎県',   '熊本県',
    '大分県',   '宮崎県',   '鹿児島県', '沖縄県'
];
ADDRAjax.prototype.AREA7_MAP_NUM = [
    null,       '40',       '41',       '42',       '43',
    '44',       '45',       '46',       '47'
];

// 都道府県名の一覧
ADDRAjax.prototype.PREF_MAP = [
    null,       '北海道',   '青森県',   '岩手県',   '宮城県',   
    '秋田県',   '山形県',   '福島県',   '茨城県',   '栃木県',   
    '群馬県',   '埼玉県',   '千葉県',   '東京都',   '神奈川県', 
    '新潟県',   '富山県',   '石川県',   '福井県',   '山梨県',   
    '長野県',   '岐阜県',   '静岡県',   '愛知県',   '三重県',   
    '滋賀県',   '京都府',   '大阪府',   '兵庫県',   '奈良県',   
    '和歌山県', '鳥取県',   '島根県',   '岡山県',   '広島県',   
    '山口県',   '徳島県',   '香川県',   '愛媛県',   '高知県',   
    '福岡県',   '佐賀県',   '長崎県',   '熊本県',   '大分県',   
    '宮崎県',   '鹿児島県', '沖縄県'
];
ADDRAjax.prototype.PREF_MAP_NUM = [
    null,       '1',        '2',        '3',        '4',   
    '5',        '6',        '7',        '8',        '9',   
    '10',       '11',       '12',       '13',       '14',  
    '15',       '16',       '17',       '18',       '19',   
    '20',       '21',       '22',       '23',       '24',   
    '25',       '26',       '27',       '28',       '29',   
    '30',       '31',       '32',       '33',       '34',   
    '35',       '36',       '37',       '38',       '39',   
    '40',       '41',       '42',       '43',       '44',   
    '45',       '46',       '47'
];

// キャッシュ格納用
ADDRAjax.prototype.JSON_CACHE = [];

// 都道府県名→都道府県IDの逆変換表
(function(){
	var rev = {};
	var map = ADDRAjax.prototype.PREF_MAP;
	for( var i=0; i<map.length; i++ ) {
		if ( ! map[i] ) continue;
		rev[map[i]] = i;
	}
	ADDRAjax.prototype.PREF_REV = rev;
})();

// 初期化
ADDRAjax.prototype.init = function () {
	// フォームの各変数を検索
	var apref = document.getElementsByName( this.form_pref );
	var acity = document.getElementsByName( this.form_city );
	var aarea = document.getElementsByName( this.form_area );
	if ( ! apref ) return;
	if ( ! acity ) return;
	if ( ! aarea ) return;

	// フォームの各変数を確認
	this.elem_pref = apref[0];
	this.elem_city = acity[0];
	this.elem_area = aarea[0];
	if ( ! this.elem_pref ) return;
	if ( ! this.elem_city ) return;
	if ( ! this.elem_area ) return;

	// 初回に1度だけ使用するコールバック関数
	this.onceAfterPref = null;
	this.onceAfterCity = null;
	this.onceAfterArea = null;

	// 都道府県名のプルダウンを初期化
	if ( !this.getAreaValue() ) this.initSelectList( this.elem_area, this.AREA_MAP, this.AREA_MAP );
	if ( !this.getPrefValue() ) this.initSelectList( this.elem_pref, this.PREF_MAP, this.PREF_MAP_NUM );
	if ( this.getPrefValue() == '都道府県を選択' ) this.initSelectList( this.elem_pref, this.PREF_MAP, this.PREF_MAP_NUM );
	if ( !this.getCityValue() ) this.initSelectList( this.elem_city, [], [] );
	if ( this.getCityValue() == '市区町村を選択' ) this.initSelectList( this.elem_city, [], [] );

	// イベントハンドラの登録
	var __this = this;
	Event.observe( this.elem_pref, 'change', function(){__this.onChangePref();} );
	Event.observe( this.elem_city, 'change', function(){__this.onChangeCity();} );
	Event.observe( this.elem_area, 'change', function(){__this.onChangeArea();} );
};

// プルダウンの初期化
ADDRAjax.prototype.initSelectList = function ( elem, list, list2, defval ) {
	var opts = elem.options;
	for( var i=opts.length; i>0; i-- ) {
		if ( ! opts[i] ) continue;
		opts[i].parentNode.removeChild( opts[i] );
	}
	if ( list.length ) {
		elem.disabled = false;
	} else {
		elem.disabled = true;
	}
	for( var i=0; i<list.length; i++ ) {
		var str = list[i];
		if ( ! str ) continue;
		if ( typeof(str) == 'object' ) str = str[1];
		var eopt = document.createElement( 'option' );
		elem.appendChild( eopt );
		eopt.text  = str;
		if ((list2.length > 0) && (list2.length >= i)) eopt.value = list2[i];
		if ( eopt.value.indexOf(",") != -1 ) {
			eopt.value = eopt.value.substring(0,eopt.value.indexOf(","));
			eopt.value = eopt.value.slice(-3);
		}
		if ( str == defval ) eopt.selected = true;
	}
}

// プルダウンの値を取得する
ADDRAjax.prototype.getSelectValue = function (elem) {
	var opts = elem.options;
	if ( ! opts ) return;
	for( var i=0; i<opts.length; i++ ) {
		if ( opts[i].selected ) return opts[i].text;
	}
};
ADDRAjax.prototype.getPrefValue = function () {
	return this.getSelectValue( this.elem_pref );
};
ADDRAjax.prototype.getCityValue = function () {
	return this.getSelectValue( this.elem_city );
};
ADDRAjax.prototype.getAreaValue = function () {
	return this.getSelectValue( this.elem_area );
};

// プルダウンの値を選択する
ADDRAjax.prototype.setSelectValue = function (elem,value) {
	if ( ! elem ) return;
	var opts = elem.options;
	if ( ! opts ) return;
	for( var i=0; i<opts.length; i++ ) {
		opts[i].selected = false;
	}
	for( var i=0; i<opts.length; i++ ) {
		if ( opts[i].value == value ) {
			opts[i].selected = true;
		}
	}
};

// Safariの文字化け防止
ADDRAjax.prototype.getResponseText = function ( req ) {
    var text = req.responseText;
    if ( navigator.appVersion.indexOf('KHTML') > -1 ) {
        var esc = escape( text );
        if ( esc.indexOf('%u') < 0 && esc.indexOf('%') > -1 ) {
            text = decodeURIComponent( esc );
        }
    }
    return text;
};

// 都道府県の選択時に呼ばれるイベント
ADDRAjax.prototype.onChangePref = function () {
	var varea = this.getAreaValue();
	var vpref = this.getPrefValue();

	var __this = this;
	var prefcb = function (data) {
		if ( __this.onceAfterPref ) {
			__this.onceAfterPref( vpref, '', varea );
			__this.onceAfterPref = null;
		} else if ( __this.onChange ) {
			__this.onChange( vpref, '', varea );
		}
	};

	if ( ! vpref ) {
		this.initSelectList( this.elem_city, [], [] );
//		this.initSelectList( this.elem_area, [] );
		window.setTimeout( prefcb, 1 );
		return;
	}
	var prefid = this.PREF_REV[vpref];
	if ( ! prefid ) return;

	var updateCityList = function (data) {
		__this.initSelectList( __this.elem_city, data[2], data[2]);
//		__this.initSelectList( __this.elem_area, [] );
		window.setTimeout( prefcb, 1 );
	};

	var data = this.JSON_CACHE[prefid];
    if ( data ) return updateCityList( data );

    // JSONファイル名を決定する
	var pref2 = ''+prefid;
	if ( pref2.length < 2 ) pref2 = '0' + pref2;
    var url = '/'+this.JSONDATA+'/pref-'+pref2+'.json'+this.URL_SUFFIX;

    // JSONファイル受信後のコールバック関数
    var receiveJSON = function (req) {
        if ( ! req ) return;
        if ( ! req.responseText ) return;
        var json = __this.getResponseText( req );
        data = eval('('+json+')');
        __this.JSON_CACHE[prefid] = data;
        updateCityList( data );
    };

    // JSONファイルを受信する
    var opt = {
        method: 'GET', 
        asynchronous: true,
        onComplete: receiveJSON
    };
    var conn = new Ajax.Request( url, opt );
};

// 市区町村の選択時に呼ばれるイベント
ADDRAjax.prototype.onChangeCity = function () {
	var varea = this.getAreaValue();
	if ( ! varea ) return;
	var vpref = this.getPrefValue();
	if ( ! vpref ) return;
	var prefid = this.PREF_REV[vpref];
	if ( ! prefid ) return;
//	var data = this.JSON_CACHE[prefid];
//	if ( ! data ) return;
	var vcity = this.getCityValue();
	if ( ! vcity ) return;
//	for( var i=0; i<data[2].length; i++ ) {
//		if ( data[2][i][1] == vcity ) {
//			this.initSelectList( this.elem_area, data[2][i][2] );
//		}
//	}
	var __this = this;
	var citycb = function () {
		if ( __this.onceAfterCity ) {
			__this.onceAfterCity( vpref, vcity, varea );
			__this.onceAfterCity = null;
		} else if ( __this.onChange ) {
			__this.onChange( vpref, vcity, varea );
		}
	};
	window.setTimeout( citycb, 1 );
};

// エリアの選択時に呼ばれるイベント
ADDRAjax.prototype.onChangeArea = function () {
	var varea = this.getAreaValue();
	var vpref = this.getPrefValue();
	var vcity = this.getCityValue();
	if (varea == '北海道') {
		this.initSelectList( this.elem_pref, this.AREA1_MAP, this.AREA1_MAP_NUM );
	}
	if (varea == '東北') {
		this.initSelectList( this.elem_pref, this.AREA2_MAP, this.AREA2_MAP_NUM );
	}
	if (varea == '関東') {
		this.initSelectList( this.elem_pref, this.AREA3_MAP, this.AREA3_MAP_NUM );
	}
	if (varea == '東海・北陸') {
		this.initSelectList( this.elem_pref, this.AREA4_MAP, this.AREA4_MAP_NUM );
	}
	if (varea == '関西') {
		this.initSelectList( this.elem_pref, this.AREA5_MAP, this.AREA5_MAP_NUM );
	}
	if (varea == '中国・四国') {
		this.initSelectList( this.elem_pref, this.AREA6_MAP, this.AREA6_MAP_NUM );
	}
	if (varea == '九州') {
		this.initSelectList( this.elem_pref, this.AREA7_MAP, this.AREA7_MAP_NUM );
	}
	this.initSelectList( this.elem_city, [], [] );
	var __this = this;
	var areacb = function () {
		if ( __this.onceAfterArea ) {
			__this.onceAfterArea( '', '', varea );
			__this.onceAfterArea = null;
		} else if ( __this.onChange ) {
			__this.onChange( '', '', varea );
		}
	};
	window.setTimeout( areacb, 1 );
};

// 指定地域に移動する
ADDRAjax.prototype.setAddress = function (pref,city,area) {
	if ( area ) {
		var __this = this;
		if ( pref ) {
			this.onceAfterArea = function () {
				__this.setSelectValue( __this.elem_pref, pref );
				__this.onChangePref();
			};
			if ( city ) {
				this.onceAfterPref = function () {
					__this.setSelectValue( __this.elem_city, city );
					__this.onChangeCity();
				};
			}
		}
		var func = function () {
			__this.setSelectValue( __this.elem_area, area );
			__this.onChangeArea();
		};
		window.setTimeout( func, 1 );
	}
};
