
var _debug_mode;
function _initDebug(status){
    // デバッグ・メッセージ領域をクリア
    document.getElementById("_debug").innerHTML = "";
    _debug_mode = (status) ? true : false;
}
function _isDebugMode(){
    return _debug_mode; 
}
function _debug(st){
    // メッセージ領域に st を追加表示
    
    // ### debug message を出さないようにするにはこの行を生かす ###
    if (!_debug_mode) return;
    
    if (st == "_CLEAR_"){
        // メッセージ領域を初期化
        document.getElementById("_debug").innerHTML = "";
    } else {
        var elm = document.getElementById("_debug");
        var buff = elm.innerHTML;
        elm.innerHTML = buff + st + "<br/>";
    }
}

function toggleView(elm, status){
	// elm を status が true なら表示 false なら非表示
	if (status){
		//elm.style.display = "table-row"; // 表示する：FireFox 対応
		elm.style.display = "block"; // 表示する
	} else
		elm.style.display = "none"; // 表示しない
}

function setColor(element, color, bgcolor){
	element.style.backgroundColor=bgcolor;
	element.style.color=color;
}

function resetColor(element, color, bgcolor){
	element.style.backgroundColor=bgcolor;
	element.style.color=color;
}

function setChangeColor(elm, color, bgcolor){
	// node を mouseover/mouseout に応じ変色させる
	// mouseout 時には CELL オリジナルの色に戻す
	var col = (color) ? color : "#000";
	var bgcol = (bgcolor) ? bgcolor : "#fff";
	var cl = "'" + col + "','" + bgcol + "'";
	elm.setAttribute("onmouseout", "resetColor(this," + cl + ")");
	elm.setAttribute("onmouseover", "setColor(this, '#ff0', '#00f')");
}

function idOfCode(code){
    // code "id.class" から "id" を返す
    if (code && code.length){
        var array = code.split("/");
        return (array[0].length) ? array[0] : null;
    } else {
        return null;
    }
}
function classOfCode(code){
    // code "id.class" から "class" を返す
    if (code && code.length){
        var array = code.split("/");
        if ((array.length > 1) && (array[1].length > 0))
            return array[1];
        else
            return null;
    } else {
        return null;
    }
}

var _modules = new Array();
function setModuleForId(obj, key){
	_modules[key] = obj;
}
function moduleForId(key){
	return _modules[key];
}

var _switchButtonObjects;
function switchButtonClicked(elm){
	// switchButton がクリックされた時の動作
	var selectedRadioNum = 0;
	// elm 以外の兄弟 element の背景色を元来の色に戻す
	var array = elm.parentNode.childNodes;
	for (var i=0,ct=array.length; i < ct; i++){
		var node = array[i];
		if (node == elm)
			selectedRadioNum = i;
		else {
			var obj = _switchButtonObjects[i];
			node.style.backgroundColor = obj.bgcolor;
		}
	}
	
	// 選択された element の背景色を白にする
	elm.style.backgroundColor = "#fff";
	
	// 選択されたオブジェクトの script を実行
	var obj = _switchButtonObjects[selectedRadioNum];
	eval('(' + obj.script + ')');
}
function newSWITCHBUTTON(elm, items){
	// ボタン形式の radio button を生成
	// items={("label"="foo","bgcolor":"#red","script":"alert('hello')"),,}
	_switchButtonObjects = items;
	elm.innerHTML = "";
	var tbl = newTABLE(elm, "");
	tbl.style.width = "100 %";
	tbl.style.border = "0px solid #000";
	tbl.style.borderCollapse = "collapse";
	var tr = newTR(tbl, "", "");
	for (var i=0,count=items.length; i < count; i++){
		var obj = items[i]; // "label:bgcolor" 形式
		var td = newTD(tr, "", obj.label);
		td.style.backgroundColor = obj.bgcolor;
		td.style.border = "1px solid #000";
		td.style.padding = "1px 3px";
		td.style.fontSize = "9pt";
		var action = "switchButtonClicked(this)";
		td.setAttribute("onclick", action);
	}
}

function showMessage(id, msg){
	// メッセージ・タグを開く
	// ## あらかじめ PHP ファイルなどに以下を埋め込んでおくこと ##
	// <SPAN id="_message" STYLE="visibility: hidden; position: absolute;"></SPAN>
	var elm = document.getElementById(id);
	elm.innerHTML = msg;
	elm.style.backgroundColor = "#f55";
	elm.style.color = "#fff";
	//elm.style.borderColor = "#900"; // "solid" の場合
	elm.style.borderWidth = 2;
	elm.style.border = "outset"; // "solid";
	elm.style.padding = "3px 10px";
	elm.style.left = 25; // 表示するx座標
	elm.style.top = 100; // 表示するy座標
	elm.style.visibility = "visible";
	var action = "hideMessage('"+id+"')";
	elm.setAttribute("onmouseover", action);
}
function hideMessage(id){
	// メッセージ・タグを閉じる
	var elm = document.getElementById(id);
	elm.style.visibility = "hidden";
}

var _offsetX;
var _offsetY;
var _clientX;
var _clientY;
var _cursorLocked;
function cursorLock(){ // mouse down
	_cursorLocked = true;
}
function cursorUnlock(){ // mouse up
	_cursorLocked = false;
}
function getMouseXY(evt){
	// マウスでパネルのタイトルを掴み移動させる
	// Firefox ではうまく動作しない
	if (_cursorLocked){ // mouse down
		var elm = document.getElementById("_confirm");
		elm.style.left = evt.clientX - _offsetX; // 表示するx座標
		elm.style.top = evt.clientY - _offsetY; // 表示するy座標
	} else { // mouse up
		// layerX layerY は Firefox のみの独自規格で、他のブラウザーは
		// offsetX offsetY だが、最近は Safari でも layerX layerY が動く
		// Firefox では evt.x evt.y は動かない
		_offsetX = evt.layerX;
		_offsetY = evt.layerY;
		_clientX = evt.clientX;
		_clientY = evt.clientY;
	}
}
function mouseX(){
	return _clientX;
}
function mouseY(){
	return _clientY;
}

function closeConfirm(){
	// 確認パネルを閉じる
	var elm = document.getElementById("_confirm");
	elm.innerHTML = "";
	// ## マウス・イベントが横取りされないようワークスペース外に押し出しておく
	// ## サイズ変更や disabled などやってみたが、不具合が出る
	elm.style.left = -10000; // 表示するx座標
	//	elm.style.height = 0;
	//	elm.style.visibility = "hidden";
	window.onmousemove = false; // マウス制御を解除しておく
}
function fixConfirm(action){
	// 確認パネルの 確定ボタンの動作
	// eval('(' + action + ')');
	eval(action);
	closeConfirm();
}
function openConfirm(x, y, title, buff, actionMessage, action){
	// 確認パネルを開く
	// ## あらかじめ base に _confirm エレメントの埋め込みが必要
	window.onmousemove = getMouseXY;
	var elm = document.getElementById("_confirm");
	elm.style.left = x; // 表示するx座標
	elm.style.top = y; // 表示するy座標
	elm.style.visibility = "visible";
	elm.style.fontFamily = "arial, Helvetica";
	elm.innerHTML = "";
	
	var tbl = newTABLE(elm, "");
	tbl.style.borderTop = "1px solid #777";
	tbl.style.borderLeft = "1px solid #777";
	tbl.style.borderRight = "2px solid #999";
	tbl.style.borderBottom = "2px solid #999";
	tbl.style.backgroundColor = "#ffc";
	//tbl.style.width = "100%";
	
	var tr = newTR(tbl, "", ""); // header
	tr.style.backgroundColor = "#da3";
	tr.style.color = "#000";
	tr.setAttribute("onmousedown", "cursorLock()");
	tr.setAttribute("onmouseup", "cursorUnlock()");
	var td = newTD(tr, "", "");
	td.style.fontSize = "10pt";
	td.style.height = "23px";
	td.style.padding = "0px 5px";
	var im = newIMAGE(td, "icon", "./close.png", "?");
	im.setAttribute("onclick", "closeConfirm()");
	im.style.verticalAlign = "top";
	var tx = newTEXT(td, "　" + title);
	
	var tr = newTR(tbl, "", ""); // contents
	var td = newTD(tr, "", "");
	td.innerHTML = buff;
	if (action){
		var tr = newTR(tbl, "", ""); // controls
		tr.style.backgroundColor = "#ccc";
		var td = newTD(tr, "", "");
		td.style.padding = "0px 5px";
		td.style.textAlign = "right";
		// action 実行とともに confirm panel を閉じる
		var bt = newBUTTON(td, "", actionMessage);
		var act = "fixConfirm('" + action + "')";
		bt.setAttribute("onclick", act);
	}
}

var _fadeoutInfoElement;
function closeInfo(){
    // fadeoutInfo を削除
	_fadeoutInfoElement.innerHTML = "";
}
function freezeFadoutInfo(){
    // フェードアウトを止める
    setFadeOutNode("", 0);
}
function showFadeoutInfo(elementId, message, fadeoutTime){
	// メッセージを表示し、一定時間でフェードアウト
    // fadeoutTime は 1000 位が適当
	var elm = document.getElementById(elementId);
    if (!elm) return; // メッセージ表示領域がなかった
    
	elm.innerHTML = "";
    _fadeoutInfoElement = elm;
    var sp = newSPAN(elm, "");
    sp.style.color = "#f39";
    
    // CLOSE ICON を表示したい場合
    var img = newIMAGE(sp, "", "./close.png", "map");
    img.style.height = "11px";
    img.setAttribute("onclick", "closeInfo()");
    var sp = newSPAN(sp, "");
    sp.innerHTML = " " + message; // message に HTML も埋め込める
    
    // message がクリックされたら fadeout を停止する
    sp.setAttribute("onclick", "freezeFadoutInfo()");
    
    // FADE OUT の設定
    if (fadeoutTime) setFadeOutNode(elm, fadeoutTime);
}

var _floatPanel;
function setFloatPanel(panel){
	_floatPanel = panel;
}
function floatPanel(){
	return _floatPanel;
}
function _checkPanel(){
	// カーソル位置が floatPanel 外にあれば floatPanel を閉じる
	if (isOutOfPanel()){
		closeFloatPanel();
	}
	
	function isOutOfPanel(){
		// カーソル位置が floatPanel 上になければ true を返す
		// floatPanel の位置
		var pos = getPosition(floatPanel());
		var x = pos.x;
		var y = pos.y;
		var w = floatPanel().offsetWidth;
		var h = floatPanel().offsetHeight;
		
		//　カーソルがクリックされた位置
		var mx = _clientX;
		var my = _clientY;
		
		// カーソルのクリックされた位置が floatPanel 外なら true を返す
		if (mx < x) return true;
		if (x + w < mx) return true;
		if (my < y) return true;
		if (y + h < my) return true;
		
		return false;
	}
}
function _getCursorMove(evt){
	// マウスでパネルのタイトルを掴み移動させる
	// Firefox ではうまく動作しない
	if (_cursorLocked){ // mouse down
		floatPanel().style.left = evt.clientX - _offsetX; // 表示するx座標
		floatPanel().style.top = evt.clientY - _offsetY; // 表示するy座標
	} else { // mouse up
		// layerX layerY は Firefox のみの独自規格で、他のブラウザーは
		// offsetX offsetY だが、最近は Safari でも layerX layerY が動く
		// Firefox では evt.x evt.y は動かない
		_offsetX = evt.layerX;
		_offsetY = evt.layerY;
	}
	_clientX = evt.clientX;
	_clientY = evt.clientY;
}
function closeFloatPanel(){
	// 確認パネルを閉じる
	closeInfoTip();
    if (floatPanel()){
        floatPanel().innerHTML = "";
        // ## マウス・イベントが横取りされないようワークスペース外に押し出しておく
        //floatPanel().style.top = -10000; // 表示するy座標
        floatPanel().style.left = -10000; // 表示するx座標
    }
	window.onmousemove = false; // マウス制御を解除しておく
}
function openFloatPanel(element, x, y, title, status, closeAction){
	// 確認パネルを開く
	window.onmousemove = true; // マウス制御を起動
	var elm = element.parentNode; // _panel と同じもの
	elm.style.marginTop = "2%";
	elm.style.marginRight = "2%";
    elm.style.borderRadius = "10px";
    elm.style.backgroundColor = "#ffc";
	setFloatPanel(elm);
	
	// floatPanel の基盤層にパネルを閉じる動作を設定
	var parent = elm.parentNode;
    var fixed = (status && status.length) ? true : false;
	//if (! fixed) parent.setAttribute("onclick", "_checkPanel()");
	
	// タイトルを掴んでドラッグできる
	if (! fixed)
		window.onmousemove = _getCursorMove;
	
	elm.style.left = x; // 表示するx座標
	elm.style.top = y; // 表示するy座標
	elm.style.visibility = "visible";
	elm.style.fontFamily = "arial, Helvetica";
	elm.innerHTML = "";
	var tbl = newTABLE(elm, "float-table");
	
	// TITLE
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "float-header", "");
	var sp = newSPAN(td, "");
	sp.style.padding = "0px 5px";
	var im = newIMAGE(sp, "", "./close.png", "?");
    var action = (closeAction) ? closeAction : "closeFloatPanel()";
	im.setAttribute("onclick", action);
	im.style.height = "12px";
	var sp = newSPAN(td, "");
    sp.innerHTML = title;
    
    var sp = newSPAN(td, "floatPanelOptionArea");
    
	// CONTENTS
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "", "");
	td.appendChild(element);
}

var _infoTipPanel;
function setInfoTipNode(panel){
	_infoTipPanel = panel;
}
function infoTip(){
	return _infoTipPanel;
}
function prickPin(){
	// ピン・アイコンを立て infoTip がフェードアウトしないようにする
	var gem = document.getElementById("noPrickIcon");
	if (gem.style.display == "none") return;
	
	gem.style.display = "none";
	
	var td = document.getElementById("pinArea");
	var im = newIMAGE(td, "", "./redPin.png", "pin");
	im.style.height = "14px";
	
	setFadeOutTime(0);
}
function closeInfoTip(){
	// infoTip を閉じる
	if (! infoTip()) return;
	
	infoTip().display = "none";
	infoTip().innerHTML = "";

	// マウス・イベントが横取りされないようワークスペース外に押し出しておく
    //	infoTip().style.left = -10000; // 表示するx座標
}

function kickInfoTip(targetId, comment){
    // HELP 用インフォティップを開く
    // 不可視設定の DIV: _infoTip を用意する必要あり
    var elm = document.getElementById("_infoTip");
    if (!elm){
        alert("_infoTip がありません"); return;
    }
    elm.innerHTML = "";
	setInfoTipNode(elm);
    
    var targetElement = document.getElementById(targetId); // infoTip を起動する element
    var pos = getPosition(targetElement);
	elm.style.left = pos.x + 0; // 表示するx座標
	elm.style.top = pos.y + 40; // 表示するy座標
	elm.style.visibility = "visible";
    
    // 画面右端からはみ出るようなら位置を調整
    var wWidth = window.innerWidth; // 画面巾
    // elm.style.left は "100px" 型式なので数値に変換
    var tLeft = elm.style.left.substr(0, elm.style.left.length - 2) * 1;
    // infoTip 表示後では折り返され p.offsetWidth 短縮の可能性あるので事前に決め打ち
    var tWidth = 100;
    if (tLeft + tWidth > wWidth){
        elm.style.left = wWidth - tWidth;
    }
    
    // infoTip を表示
    var p = newSPAN(elm, "/infoTIp"); // ## これにより残像発生を防ぐ
    p.innerHTML = comment;
    //p.setAttribute("onclick", "closeInfoTip()");
}
function _kickInfoTip(targetId, comment){
    // HELP 用インフォティップを開く
    // 不可視設定の DIV: _infoTip を用意する必要あり
    /*
    var elm = document.getElementById("_infoTip");
    if (!elm){
        alert("_infoTip がありません"); return;
    }
    elm.innerHTML = "";
	setInfoTipNode(elm);
     */
    
    var targetElement = document.getElementById(targetId); // infoTip を起動する element
    
    var tip = newDIV(targetElement, "/infoTip");
	setInfoTipNode(tip);

    var pos = getPosition(targetElement);
	tip.style.left = pos.x + 0; // 表示するx座標
	tip.style.top = pos.y + 40; // 表示するy座標
//	tip.style.visibility = "visible";
    
    // 画面右端からはみ出るようなら位置を調整
    var wWidth = window.innerWidth; // 画面巾
    // tip.style.left は "100px" 型式なので数値に変換
    var tLeft = tip.style.left.substr(0, tip.style.left.length - 2) * 1;
    // infoTip 表示後では折り返され p.offsetWidth 短縮の可能性あるので事前に決め打ち
    var tWidth = 100;
    if (tLeft + tWidth > wWidth){
        tip.style.left = wWidth - tWidth;
    }
    
    // infoTip を表示
    tip.innerHTML = comment;
}
function setInfoTip(targetId, comment){
    // targetId にマウスが載ったら comment の infoTip を表示
    var elm = document.getElementById(targetId);
    
    elm.setAttribute("onmouseover", "kickInfoTip('"+targetId+"','"+comment+"')");
    elm.setAttribute("onmouseout", "closeInfoTip()");
}

function showInfoTip(x, y, element, fadeout, title, action){
	// infoTip を開く
	var elm = element.parentNode; // _panel と同じもの
	setInfoTipNode(elm);
	
	elm.style.left = x; // 表示するx座標
	elm.style.top = y; // 表示するy座標
	elm.style.visibility = "visible";
	elm.style.marginTop = "2%";
	elm.style.marginRight = "2%";
	elm.innerHTML = "";
	
	// table
	var tbl = newTABLE(elm, "");
	tbl.style.backgroundColor = "#ffc";
	tbl.style.color = "#000";
	tbl.style.border = "1px solid #888";
	tbl.style.fontSize = "10pt";
	tbl.style.fontFamily = "arial, Helvetica";
    
	// title
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "", "");
	tr.style.backgroundColor = "#ec9"; // light brown
	td.style.borderBottom = "thin solid #a63"; // brown
	var tbl2 = newTABLE(td, "");
	tbl2.style.width = "100%";
	var tr2 = newTR(tbl2, "", "");
	var td = newTD(tr2, "", "");
	var im = newIMAGE(td, "icon", "./close.png", "?");
	im.setAttribute("onclick", "closeInfoTip()");
    
	var td = newTD(tr2, "", "");
	td.style.fontSize = "11pt";
	td.style.textAlign = "center";
	if (title && title.length)
		var tx = newTEXT(td, title);
    
	var td = newTD(tr2, "pinArea", "");
	td.style.fontSize = "11pt";
	td.style.width = "40px";
	td.style.textAlign = "right";
	td.setAttribute("onclick", "prickPin()");
	var im = newIMAGE(td, "noPrickIcon", "./redgem.png", "fix");
	im.style.height = "10px";
	
	// contents
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "", "");
	td.appendChild(element);
    
	if (action){
		// contents をクリックした時にアクションを実施
		td.setAttribute("onclick", action);
	}
	
	if (fadeout && (fadeout > 0)){
		// パネルをフェードアウト
		setFadeOutTime(fadeout);
		setFadeOutElement(elm);
		setOpacityValue(1);
		fadeOut();
	}
}

function setFadeOutNode(elm, fadeOutTime){
    // elm を fadeOutTime でフェードアウトするよう設定
    // ### 外部から closeInfoTip() でこの elm を消すことができる ###
    setFadeOutTime(fadeOutTime);
    setFadeOutElement(elm);
    setInfoTipNode(elm);
    setOpacityValue(1);
    fadeOut();
}

/////////////////////////////////
//////// fade ///////////////////

function closeWarn(panelId){
    // 警告パネルを閉じる
    var el = document.getElementById(panelId);
    el.innerHTML = "";
}
function warn(baseElm, panelId, message, action){
    // 警告パネルを表示: baseElm の位置に panelId を表示
    var h =  baseElm.offsetHeight;
    var w = baseElm.offsetWidth;
    var pos = getPosition(baseElm); // dom.js
    
    //alert("warn:"+h+"/"+w+"->"+pos.x+"/"+pos.y); //##
    
    var el = document.getElementById(panelId);
    el.innerHTML = "";
    el.style.left = pos.x; // 表示するx座標
    el.style.top = pos.y; // 表示するy座標
    el.style.visibility = "visible";
    
    var tbl = newTABLE(el, "");
    tbl.style.width = "100%";
    tbl.style.width = w;
    tbl.style.height = h;
    tbl.style.border = "thin solid #aaa";
    tbl.style.backgroundColor = "#ff0";
    tbl.style.fontSize = "10pt";
    
    var tr = newTR(tbl,"","");
    var td = newTD(tr,"","");
    td.innerHTML = message; // HTML を設定できる
    td.style.padding = "0px 10px";
    
    if (action && action.length)
        td.setAttribute("onclick", action);
}

function setOpacity(elm, op){
	// elm の透明度を設定: 1..0
    // IE6.0, IE7.0
    elm.style.filter = 'alpha(opacity=' + (op * 100) + ')';
    // Firefox, Netscape
    elm.style.MozOpacity = op;
    // Chrome, Safari, Opera
    elm.style.opacity = op;
}

var _fadeOutElement;
function setFadeOutElement(elm){
	_fadeOutElement = elm;
}
function fadeOutElement(){
	return _fadeOutElement;
}

var _fadeOutTime;
function setFadeOutTime(time){
	_fadeOutTime = time;
}
function fadeOutTime(){
	// この時間まではフェードアウト開始しない
	return _fadeOutTime;
}

var _opct = 1; // 最初の透明度
function setOpacityValue(val){
	_opct = val;
}

function fadeOut(){
	var elm = fadeOutElement();
	
	setOpacity(elm, _opct);
	_opct -= 0.02; // 何%ずつ変化させるか
	if (_opct <= 0){
		closeInfoTip();
		return;
	}
	
	var time = fadeOutTime(); // この時間まではフェードアウト開始しない
	if (time == 0) return; // フェードアウトタイムがゼロならフェードアウトしない
	var interval = (_opct < 0.9) ? 30 : time; // 変化させる間隔（ミリ秒単位）
	setTimeout("fadeOut()", interval);
}

///// startFade(16,0x80,0x80,0x80,0xff,0xff,0xe0);
///// startFade(16,0,0,512,512,512,512);

var cvtable='0123456789ABCDEF';

// 10進数を16進数に変換する関数
function ToHexa(n){
	if(n<=0)        return '00';
	else if(n>=255) return 'ff';
	return cvtable.charAt(Math.floor(n/16))+
	cvtable.charAt(n%16);
}
// 背景色を変更する関数
function SetBgColor(r,g,b){
	document.bgColor='#'+ToHexa(r)+ToHexa(g)+ToHexa(b);
}

tid=null; interval=50;
cStep=0;    nStep=0;
sr=0; sg=0; sb=0; er=0; eg=0; eb=0;
// フェード関数
function startFade(step,r0,g0,b0,r1,g1,b1){
	// step:     階調,
	// r0,g0,b0: 最初の色(RGB値)
	// r1,g1,b1: 最後の色(RGB値)
	if(tid==null){
		cStep=0; nStep=step;
		sr=r0; sg=g0; sb=b0; er=r1; eg=g1; eb=b1;
		doFade();
	}
}
// フェード実行関数
function doFade(){
	if(cStep++<nStep){
		SetBgColor(
				   Math.floor(sr+(er-sr)*(cStep/nStep)),
				   Math.floor(sg+(eg-sg)*(cStep/nStep)),
				   Math.floor(sb+(eb-sb)*(cStep/nStep))
				   );
		tid=setTimeout('doFade()',interval);
	} else tid=null;
}

//////// fade ///////////////////
/////////////////////////////////

function getPosition(el){
	// エレメント el の左上の座標を返す
	// 使用法: var pos = getPosition(el); var x = pos.x; var y = pos.y;
	// 実現に悩んだ結果、以下を参考にさせて頂きました: Thanks !!
	// http://n-yagi.0r2.net/script/2009/06/post_13.html
	var ex  =   0;
	var ey  =   0;
	do {
		ex  +=  el.offsetLeft;
		ey  +=  el.offsetTop;
	} while(  el  =   el.offsetParent );
	
	return  {x:ex,y:ey};
}

function newTABLE(elm, code){
	// elm の下に TABLE を生成して返す
	var tbl = document.createElement('TABLE');
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) tbl.setAttribute("id", id);
	if (cls) tbl.setAttribute("class", cls);

	elm.appendChild(tbl);
	return tbl;
}

function newTEXT(elm, value){
	// elm の下に TEXT を生成して返す
	var tx = document.createTextNode(value);
	elm.appendChild(tx);
	return tx;
}

function newTR(elm, code, label){
	// elm の下に <TR></TR> を生成して返す
	var tr = document.createElement('TR');
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) tr.setAttribute("id", id);
	if (cls) tr.setAttribute("class", cls);
    
	elm.appendChild(tr);
	if (label == null) label = "";
	if (label.length){
		var td = document.createElement('TD');
		tr.appendChild(td);
		var tx = document.createTextNode(label);
		td.appendChild(tx);
	}
	return tr;
}

function newTH(elm, id, label){
	// elm の下に <TD></TD> を生成して返す
	var td = document.createElement('TH');
	if (id.length) td.setAttribute("ID", id);
	if (label == null) label = "";
	if (label.length){
		var tx = document.createTextNode(label);
		td.appendChild(tx);
	}
	elm.appendChild(td);
	return td;
}

function newTD(elm, code, label){
	// elm の下に <TD></TD> を生成して返す
	var td = document.createElement('TD');
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) td.setAttribute("id", id);
	if (cls) td.setAttribute("class", cls);

	if (label == null) label = "";
	if (label.length){
		var tx = document.createTextNode(label);
		td.appendChild(tx);
	}
	elm.appendChild(td);
	return td;
}

function newBR(elm){
	// elm の下に BR を生成して返す
	var br = document.createElement('BR');
	elm.appendChild(br);
	return br;
}

function newP(elm, text){
	// elm の下に P を生成して返す
	var p = document.createElement('P');
	elm.appendChild(p);
	if (text) newTEXT(p, text);
	return p;
}

function newOL(elm, code){
	// elm の下に OL を生成して返す
	var p = document.createElement('OL');
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) p.setAttribute("id", id);
	if (cls) p.setAttribute("class", cls);
    
	elm.appendChild(p);
	return p;
}

function newUL(elm, code){
	// elm の下に UL を生成して返す
	var p = document.createElement('UL');
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) p.setAttribute("id", id);
	if (cls) p.setAttribute("class", cls);

	elm.appendChild(p);
	return p;
}

function newLI(elm, text, code){
	// elm の下に LI を生成して返す
	var p = document.createElement('LI');
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) p.setAttribute("id", id);
	if (cls) p.setAttribute("class", cls);
    
	elm.appendChild(p);
	if (text) newTEXT(p, text);
	return p;
}

function newDL(elm, code){
	// elm の下に DL を生成して返す
	var p = document.createElement('DL');
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) p.setAttribute("id", id);
	if (cls) p.setAttribute("class", cls);
    
	elm.appendChild(p);
	return p;
}
function newDT(elm, code){
	// elm の下に DT を生成して返す
	var p = document.createElement('DT');
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) p.setAttribute("id", id);
	if (cls) p.setAttribute("class", cls);
    
	elm.appendChild(p);
	return p;
}
function newDD(elm, code){
	// elm の下に DD を生成して返す
	var p = document.createElement('DD');
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) p.setAttribute("id", id);
	if (cls) p.setAttribute("class", cls);
    
	elm.appendChild(p);
	return p;
}

function newDIV(elm, code){
	// elm の下に DIV を生成して返す
	var dv = document.createElement('DIV');
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) dv.setAttribute("id", id);
	if (cls) dv.setAttribute("class", cls);

	elm.appendChild(dv);
	return dv;
}

function newJS(elm, id){
	// elm の下に JS を生成して返す
    alert("newJS is old-fashion"); //##
	var dv = document.createElement('JS');
	if (id.length) dv.setAttribute("id", id);
	elm.appendChild(dv);
	return dv;
}

function newSPAN(elm, code){
	// elm の下に span を生成して返す
	var sp = document.createElement('span');
	//if (id.length) sp.setAttribute("id", id);
    var id = idOfCode(code);
    var cls = classOfCode(code);
	if (id) sp.setAttribute("id", id);
	if (cls) sp.setAttribute("class", cls);
    
	elm.appendChild(sp);
	return sp;
}

function newDATE(elm, id, value){
	// 日付入力フィールドを生成 -- HTML5 の機能でまだ規定が未確定
	var ip = document.createElement('INPUT');
	ip.setAttribute("TYPE", "date");
	if (id.length) ip.setAttribute("id", id);
	ip.setAttribute("VALUE", value);
	elm.appendChild(ip);
	
	return ip;
}

function newFIELD(elm, id, label, size, value){
	// 入力フィールドを生成
	if (label.length){
		newTEXT(elm, label);
	}
	var ip = document.createElement('INPUT');
	ip.setAttribute("TYPE", "text");
	if (id.length) ip.setAttribute("id", id);
	ip.setAttribute("SIZE", size);
	ip.setAttribute("VALUE", value);
	elm.appendChild(ip);
	
	return ip;
}

function newPASSWORD_FIELD(elm, id, label, size, value){
	// パスワード専用入力フィールドを生成
	if (label.length){
		newTEXT(elm, label);
	}
	var ip = document.createElement('INPUT');
	ip.setAttribute("TYPE", "password");
	if (id.length) ip.setAttribute("id", id);
	ip.setAttribute("SIZE", size);
	ip.setAttribute("VALUE", value);
	elm.appendChild(ip);
	
	return ip;
}

function newHIDDEN(elm, id, value){
	var ip = document.createElement('INPUT');
	elm.appendChild(ip);
	ip.setAttribute("TYPE", "hidden");
	ip.setAttribute("VALUE", value);
	if (id.length) ip.setAttribute("id", id);
	
	return ip;
}

function newBUTTON(elm, id, label){
	// ボタンを生成
	var ip = document.createElement('INPUT');
	ip.setAttribute("TYPE", "button");
	ip.setAttribute("VALUE", label);
	if (id.length) ip.setAttribute("id", id);
	elm.appendChild(ip);
	
	return ip;
}

function newIMAGE_BUTTON(elm, id, imageSource, alt){
	// ボタンを生成
	var ip = document.createElement('INPUT');
	ip.setAttribute("TYPE", "image");
	ip.setAttribute("SRC", imageSource);
	ip.setAttribute("ALT", alt);
	if (id.length){
        ip.setAttribute("id", id);
        ip.setAttribute("NAME", id);
    }
	elm.appendChild(ip);
	
	return ip;
}

function newFileSelectBUTTON(elm, id, action){
	// アプロード・ボタンを生成
	// アップロードされたファイルが filenam 名で送られる
	var ip = document.createElement('INPUT');
	ip.setAttribute("TYPE", "file");
	ip.setAttribute("NAME", "file");
    ip.setAttribute("onchange", action);
	if (id.length) ip.setAttribute("id", id);
	elm.appendChild(ip);
	return ip;
}

function newUploadBUTTON(elm, id, filename){
	// アプロード・ボタンを生成
	// アップロードされたファイルが filenam 名で送られる
	var ip = document.createElement('INPUT');
	ip.setAttribute("TYPE", "file");
	ip.setAttribute("NAME", filename);
	if (id.length) ip.setAttribute("id", id);
	elm.appendChild(ip);
	return ip;
}

function newSubmitBUTTON(elm, id, label){
	// submit(送信)ボタンを生成
	var ip = document.createElement('INPUT');
	ip.setAttribute("TYPE", "submit");
	ip.setAttribute("VALUE", label);
	if (id.length) ip.setAttribute("id", id);
	elm.appendChild(ip);
	return ip;
}

function newFORM(elm, action){
	// FORM を生成: submitButton で action が実行される
	var fm = document.createElement('FORM');
	fm.setAttribute("METHOD", "POST");
	fm.setAttribute("enctype", "multipart/form-data");
	fm.setAttribute("ACTION", action);
	elm.appendChild(fm);
	return fm;
}

function newCHECKBOX(elm, id, label, status){
	var ip = document.createElement('INPUT');
	elm.appendChild(ip);
	ip.setAttribute("TYPE", "checkbox");
	if (id.length > 0) ip.setAttribute("id", id);
	
	// FireFox では ip.setAttribute("checked"); は受け付けない
	if (status) { ip.setAttribute("checked", true); }
	
	if (label.length){
		var tx = document.createTextNode(label);
		elm.appendChild(tx);
	}
	
	return ip;
}

function newTEXTAREA(elm, id, cols, rows, value){
	// TEXTAREAを生成
	var ip = document.createElement('TEXTAREA');
	if (id.length) ip.setAttribute("id", id);
	ip.setAttribute("id", id);
	ip.setAttribute("COLS", cols);
	ip.setAttribute("ROWS", rows);
	elm.appendChild(ip);
	var tx = document.createTextNode(value);
	ip.appendChild(tx);
	
	return ip;
}

function newA(elm, label, href, target){
	var a = document.createElement('A');
	elm.appendChild(a);
	a.href=href;
	if (target.length) a.target=target;
	newTEXT(a, label);
	
	return a;
}

function newIMAGE(elm, id, src, alt){
    var img = document.createElement('IMG');
	elm.appendChild(img);
	img.setAttribute("id", id);
	img.setAttribute("SRC", src); // src は URI
	img.setAttribute("ALT", alt);
	
	return img;
}

function newHR(elm){
    var hr = document.createElement('HR');
	elm.appendChild(hr);
	
	return hr;
}

function newLAYER(elm, name){
    var ly = document.createElement('layer');
	ly.setAttribute("name", name);
	elm.appendChild(ly);
	
	return ly;
}

function newIFRAME(elm, name){
    var el = document.createElement('iframe');
	el.setAttribute("name", name);
	elm.appendChild(el);
	
	return el;
}

///////////////////////////////////////////////////
///// HTML5 ///////////////////////////////////////

function newCANVAS(elm, id, width, height, action){
    // CANVAS を生成：color などは外部から与える
    var can = document.createElement('canvas');
	can.setAttribute("id", id);
    can.width = width;
    can.height = height;
    can.addEventListener("mousemove", action, true);
	elm.appendChild(can);
	
	return can;
}

function newSlider(elm, id, step, value, max, min, action){
    // スライダーを生成
	var ip = document.createElement('INPUT');
	ip.setAttribute("TYPE", "range");
	ip.setAttribute("STEP", step);
	ip.setAttribute("VALUE", value);
	ip.setAttribute("MAX", max);
	ip.setAttribute("MIN", min);
	ip.setAttribute("onchange", action);
	if (id.length) ip.setAttribute("id", id);
	elm.appendChild(ip);
	return ip;
}

///// HTML5 ///////////////////////////////////////
///////////////////////////////////////////////////


function makePopupMenu(elm, id, array, selectedItem){
	var sl = document.createElement('SELECT');
	sl.setAttribute("id", id);
	elm.appendChild(sl);
    
    //array.push(""); // どういう訳か最後に dummy を付けておかないと最終を自動選択できない
	var count = array.length;
	for (var i=0; i < count; i++){
		var title = array[i];
		var op = document.createElement('OPTION');
		tx = document.createTextNode(title);
		op.appendChild(tx);
		op.setAttribute("value",title);
		if (title == selectedItem){
			// op.setAttribute("selected"); -- FireFox では動かない
			op.setAttribute("selected", true);
		}
        // op 属性すべてを設定してから以下を実行すること
		sl.appendChild(op);
	}
	return sl;
}

function newPopupItem(elm, popupName, id, label){
	var ip = document.createElement('INPUT');
	elm.appendChild(ip);
	ip.setAttribute("TYPE", "radio");
	ip.setAttribute("id", id);
	ip.setAttribute("NAME", popupName); // radio button グループの共通名称
	var tx = newTEXT(elm, label);
	return ip;
}


/////////////////////////////////////////////////////
// NEW 年月日ポップアップ・メニュー ///////////////////////

var _datePopupReceiver = new Object();
var _oldDateLabel;
var _noChangeMaxDays;
function _setDatePopField(id, val){
    // 隠しフィールドにデータを記憶するとともに、レシーバにその値を返す
    document.getElementById(id).value = val;
    
    if (val && (! _noChangeMaxDays)){
        // 年月の変更に伴い日付ポップアップの日数を変更
        var array = val.split("-");
        // val は " " あるいは "yyyy-mm-dd" 形式
        if (array.length == 3){
            var datePopup = document.getElementById(id+".day");
            // 日ポップアップが隠れている場合は何もしない
            if (datePopup.style.visibility !== "hidden"){
                var yyyy = array[0];
                var mm = array[1];
                var dd = array[2];
                var dobj = new Date(yyyy, mm, 0);
                var lastday = dobj.getDate();
                var days = makeArray(1, lastday);
                days.splice(0,0,"");
                var sp = document.getElementById(id+".datePopDateArea");
                sp.innerHTML = "";
                var dpop = makePopupMenu(sp, id+".day", days, dd*1);
                dpop.setAttribute("onchange", "_datePopupChanged('" + id + "')");
            }
        }
    }
    _noChangeMaxDays = false;
    
    if (_datePopupReceiver[id])
        eval('(' + _datePopupReceiver[id](val) + ')');
}
function _labelPopupChanged(id){
    // 年号ポップアップが変更された
    var nengou = document.getElementById(id+".koyomiLabel").value;
    var yymmdd = document.getElementById(id).value; // 隠しフィールド
    var array = yymmdd.split("-");
    var yyyy = array[0];
    
    _setDatePopYear(id, nengou, yyyy);
    _oldDateLabel = nengou;
}
function _datePopupChanged(id){
    // datePopUp のどれかが変更された時に呼ばれる
    var nengou = document.getElementById(id+".koyomiLabel").value;
    var yy = document.getElementById(id+".warekiYear").value * 1;
    var mm = document.getElementById(id+".month").value * 1;
    var dd = document.getElementById(id+".day").value * 1;
    
    //alert("_datePopupChanged:" + nengou+" "+yy+"/"+mm+"/"+dd); //##
    
    var yyyy = seirekiYear(nengou, yy);
    if (mm < 10) mm = "0" + mm;
    if (dd < 10) dd = "0" + dd;
    var yymmdd = yyyy + "-" + mm + "-" + dd;
    
    // 隠しフィールドに西暦を記憶
    // 空フィールドにするかどうかは yyyy でなく ポップアップメニューの yy で判定
    var val = (yy * mm * dd == 0) ? " " : yymmdd;
    
    _setDatePopField(id, val);
}
function _setDatePopYear(id, label, yyyy){
    // 年ポップアップを設定 : yyyy は西暦年とする
    var ary = today().split("-"); // "2012-07-30" 形式
    var begin = ary[0] * 1 - 100; // 年配列は100年前から始める
    var range = 130;
    var year = yyyy * 1;
    if (label == "平成"){
        begin = 1; range = 40; year = warekiYear(label, yyyy);
    } else if (label == "昭和"){
        begin = 1; range = 63; year = warekiYear(label, yyyy);
    } else if (label == "大正"){
        begin = 1; range = 14; year = warekiYear(label, yyyy);
    } else if (label == "明治"){
        begin = 1; range = 43; year = warekiYear(label, yyyy);
    }
    
	var years = makeArray(begin, range);
    years.splice(0,0,"");
	var sp = document.getElementById(id+"_koyomiYear");
    sp.innerHTML = "";
	var ypop = makePopupMenu(sp, id+".warekiYear", years, year); // 和暦
	ypop.setAttribute("onchange", "_datePopupChanged('"+id+"')");
}

function getDatePopUpValue(id){
    // 設定された年月日を 西暦 "yyyy-mm-dd" 形式で返す
    // ### 原則として "_receiver(yymmdd)" で返送するのでこのメソッドを使う必要はない
    return document.getElementById(id).value;
}
function newDatePopUp(elm, id, label, yyyy, mm, dd, noDay, receiver){
	// label が "西暦" なら西暦固定と解釈され、西暦・和暦のポップアップを表示しない
    // label が "西暦" 以外なら yyyy に該当する和暦ラベルになり和暦年に自動変換
	// yyyy は西暦で指定すること
    // noDay:true なら日のポップアップを表示しない、通常は false
    // ### popup で更新された年月日の外部からの取得方法 ###
	//　１）id で特定される field に "yyyy-mm-dd" を記憶しているので
    //   document.getElementById(id).value で取得できる
    // ２）receiver("2011-08-28") の形で年月日が更新されるごとに結果が送り返される
    // 年月日ポップアップ更新ごとに回答しなくてよいのなら receiver は省略可
    
    _datePopupReceiver[id] = receiver;
    _oldDateLabel = label;
    
    //alert("newDatePopUp receiver->"+_datePopupReceiver); //##
    
    // 年号ラベル
    if (label != "西暦"){
        var sp = newSPAN(elm, "_koyomiLabel");
        //if (label.length == 0) lebel = "西暦";
        var labels = nengouArray(); // lib.js "西暦","平成","昭和","大正","明治";
        if (yyyy > 0) label = nengou(yyyy); // yyyy に相当する和暦ラベル
        var npop = makePopupMenu(sp, id+".koyomiLabel", labels, label);
        npop.setAttribute("onchange", "_labelPopupChanged('"+id+ "')");
    }
    
	var sp = newSPAN(elm, id+"_koyomiYear");
    _setDatePopYear(id, label, yyyy);
	
    // MONTH popup
	var months = makeArray(1, 12);
    months.splice(0,0,"");
	var mpop = makePopupMenu(elm, id+".month", months, mm*1);
	mpop.setAttribute("onchange", "_datePopupChanged('" + id + "')");
    //alert("newDatePopUp:id("+id+")"+label+":"+yyyy+"/"+mm+"/"+dd); //##
	
    // DAY popup
	var dobj = new Date(yyyy, mm, 0);
	var lastday = dobj.getDate();
	var days = makeArray(1, lastday);
    days.splice(0,0,"");
    var sp = newSPAN(elm, id+".datePopDateArea"); // 日数は月により書き換えの可能性あり
	var dpop = makePopupMenu(sp, id+".day", days, dd*1);
	dpop.setAttribute("onchange", "_datePopupChanged('" + id + "')");
    
    // 西暦年月日の隠しフィールド
    var fd = newHIDDEN(elm, id, "");
    
    // ここで日ポップアップの日数を変更するとエラーが起こるので日数変更なしの true をつける
    _noChangeMaxDays = true;
    _datePopupChanged(id);
    
    // 日ポップアップが指定されていない場合、それを表示しない
	if (noDay){
		// ## これは calendar.js から呼ばれた時に利用される
		dpop.style.visibility = "hidden";
		dpop.style.width = "0px";
		var mx = document.getElementById("datePopup.calendar");
		if (mx)
			showCalendarMatrix(yyyy, mm, dd);
	}
}

// NEW 年月日ポップアップ・メニュー ///////////////////////
/////////////////////////////////////////////////////

/////////////////////////////////////////////////////
// OLD 年月日ポップアップ・メニュー ///////////////////////

var _datepopup;
function setDatePopup(id, obj){
	if (!_datepopup) _datepopup = new Array();
	_datepopup[id] = obj;
}
function datePopup(id){
    // 日付ポップアップを返す、そのままでは使わず以下のように利用
	// ## 以下のメソッドを使って外部から value を取り出す
	// ## 例えば -- var seireki = datePopup(id).yyyy();
	return _datepopup[id];
}

function selectedYYMMDD(id){
	// 年月日ポップアップから西暦年月日を返す
	// ## datePopUp オブジェクトに含めても余り効率化されないので分離
	var year = document.getElementById(id+".year").value;
	var month = document.getElementById(id+".month").value;
	var day = document.getElementById(id+".day").value;
	
	if (month.length < 2) month = "0"+month;
	if (day.length < 2) day = "0"+day;
	return year + "-" + month + "-" + day;
}

function koyomiSelected(id){
	// 暦の選択に応じて年数ポップアップを変化させる
	// 月ポップアップが変更されたと同じ動作
	monthChanged(id);
}
function yearChanged(id){
	// 「和暦」が変更されたなら、西暦：隠しフィールドも更新
	var label = document.getElementById(id+".koyomiLabel").value;
	var warekiPop = document.getElementById(id+".warekiYear");
	var dayPop = document.getElementById(id+".day");
	if (warekiPop.value.length == 0){
		// 年ポップで空白が選択された場合
		var yy = yyyy = mm = dd = 0;
	} else {
		var yy = document.getElementById(id+".warekiYear").value * 1;
		var yyyy = seirekiYear(label, yy);
		var mm = document.getElementById(id+".month").value;
		var dd = dayPop.value;
	}
	var noDay = (dayPop.style.visibility == "hidden") ? true : false;
	makeDatePopUp(id, label, yyyy, mm, dd, noDay);
}
function monthChanged(id){
	// 月ポップアップが変更された
	var label = document.getElementById(id+".koyomiLabel").value;
	var yyyy = document.getElementById(id+".year").value;
	var mm = document.getElementById(id+".month").value;
	var dayPop = document.getElementById(id+".day");
	var dd = dayPop.value;
	var noDay = (dayPop.style.visibility == "hidden") ? true : false;
	//alert("monthChanged "+label+":"+yyyy+"/"+mm+"/"+dd); //##
	makeDatePopUp(id, label, yyyy, mm, dd, noDay);
}
function makeDatePopUp(id, label, yy, mm, dd, noDay){
	//alert("makeDatePopUp:"+label+"->"+yy+"/"+mm+"/"+dd+"->"+noDay); //##
	// id で特定される element 上に label(和暦などのラベル),date をセット
	// yy は西暦で指定すること。labelの「西暦」、和暦に従って年を変換
	// label が "" なら西暦固定と解釈され、西暦・和暦のポップアップを表示しない
    // ### selectedYYMMDD(id)　でポップアップの年月日を取得する ###
    alert("makeDatePopUp -- legacy"); //##
    
	var obj = new Object();
	setDatePopup(id, obj);
    
    var ary = today().split("-"); // "2012-07-30" 形式
	var range = ary[0] * 1 + 20; // 現在から 20年後まで選択できるようにする
    var fromYear = ary[0] * 1 - 100; // 現在から 100年前かあ選択できるようにする
    //	var range = 2020;
    var warekiYear = yy;
    if (isSame(label, "平成")){ warekiYear -= 1988; range = 40; }
    else if (isSame(label, "昭和")){ warekiYear -= 1925; range = 63; }
    else if (isSame(label, "大正")){ warekiYear -= 1911; range = 14; }
    else if (isSame(label, "明治")){ warekiYear -= 1867; range = 43; }
    
    // 以下は range 決定後実施
    if (yy == 0)
        warekiYear = 0; // 西暦年ポップが空白の場合
    else if (warekiYear <= 0)
        warekiYear = 1;
    else if (warekiYear > range)
        warekiYear = range;
    
    // 和暦年を調整後、西暦年もそれに合わせる
    if (warekiYear > 0)
        yy = seirekiYear(label, warekiYear);
    
	// ポップアップからの 暦表示・和暦年・年・月・日 は以下のように取得する
	// koyomiLabel は datePopup(id).nengou()
	var elm = document.getElementById(id);
	elm.innerHTML = "";
	
	if (label.length == 0) lebel = "西暦";
	var labels = nengouArray(); // lib.js "西暦","平成","昭和","大正","明治";
	var js = newSPAN(elm, "_koyomiLabel");
	var npop = makePopupMenu(js, id+".koyomiLabel", labels, label);
	var action = "koyomiSelected('" + id + "')";
	npop.setAttribute("onchange", action);
	
	var yyyyF = newHIDDEN(elm, id+".year", yy); // 西暦：隠しフィールド
	var begin = (label == "西暦") ? fromYear : 1;
	var years = makeArray(begin, range); years.splice(0,0,"");
	var ypop = makePopupMenu(elm, id+".warekiYear", years, warekiYear*1); // 和暦
	ypop.setAttribute("onchange", "yearChanged('" + id + "')");
	
	var months = makeArray(1, 12); months.splice(0,0,"");
	var mpop = makePopupMenu(elm, id+".month", months, mm*1);
	mpop.setAttribute("onchange", "monthChanged('" + id + "')");
	
	var dobj = new Date(yy, mm, 0);
	var lastday = dobj.getDate();
	var days = makeArray(1, lastday); days.splice(0,0,"");
    
	var dpop = makePopupMenu(elm, id+".day", days, dd*1);
	if (noDay){
		// 日ポップアップが指定されていない場合、それを表示しない
		// ## これは calendar.js から呼ばれた時に利用される
		dpop.style.visibility = "hidden";
		dpop.style.width = "0px";
		var mx = document.getElementById("datePopup.calendar");
		if (mx){
			showCalendarMatrix(yy, mm, dd);
		}
	}
	
	// ## 以下のメソッドを使って外部から value を取り出す
	// ## 例えば -- var seireki = datePopup(id).yyyy();
    
	obj.yyyy = function(){
		// 西暦を返す
		return yyyyF.value;
	}
	
	obj.nengou = function(){
		// 年号を返す
		return npop.value;
	}
	
	obj.yy = function(){
		// 和暦を返す
		return ypop.value;
	}
	
	obj.mm = function(){
		// 月を返す
		return mpop.value;
	}
	
	obj.dd = function(){
		// 日を返す
		return dpop.value;
	}
}

// OLD 年月日ポップアップ・メニュー ///////////////////////
/////////////////////////////////////////////////////


function newRADIO(elm, id, groupName, names, selection){
	// ラジオボタンを生成
	// groupName: radio button グループの共通名称
	// # array['item1'] = "アイテム１";
	// # array['item2'] = "アイテム２"; のような array を作成しておく
	// # newRADIO(elm, "_radioArea", "radioButtons", array, "item1");
	// # elm 上の _dadioArea というエレメント上に "radioButtons" というグループ名で
	// # radio button を作成し "item1" が選択状態になる。
	// # 選択された値は checkedRADIO("_radioArea") でゲットできる（"アイテム１" など）
	elm.innerHTML = "";
	var js = newSPAN(elm, id); // radio button を収納する node
	for (num in names){
		var status = (isSame(num, selection)) ? true : false;
		makeRadio(js, groupName, names[num], status);
        newTEXT(js, " "); // space
	}
	
	function makeRadio(elm, groupName, label, status){
		// radio ボタンを生成
		var ip = document.createElement('INPUT');
		ip.setAttribute("TYPE", "radio");
		ip.setAttribute("VALUE", label);
		ip.setAttribute("NAME", groupName); // radio button グループの共通名称
		// FireFox では ip.setAttribute("checked"); は受け付けない
		// if (status) { ip.setAttribute("CHECKED"); }
		ip.checked = (status > 0) ? true : false;
        
		elm.appendChild(ip);
		var tx = document.createTextNode(label);
		elm.appendChild(tx);
	}
}
function checkedRADIO(id){
	// id で指定されたラジオボタンからチェックされた値を返す
	var radio = document.getElementById(id);
	var array = radio.childNodes;
	for (var i=0,num=0,count=array.length; i < count; i++){
		var elm = array[i];
		if (elm.toString() == "[object HTMLInputElement]"){
			if (array[i].checked)
				return num;
			num++;
		}
	}
	return "";
}

//////////////////////////////////////////////
////// 時刻入力フィールド ///////////////////////

function dt_setHour(val, obj){
	val = val * 1;
	obj.hour = val;
	obj.hourF.value = val;
}
function dt_setMinutes(val, obj){
	val = val * 1;
	obj.minutes = val;
	obj.minutesF.value = val;
}
function dt_setSecond(val, obj){
	val = val * 1;
	obj.second = val;
	obj.secondF.value = val;
}

function time_string(obj){
	// 西暦 "20:38:00" 形式で日付を返す
	var hh = obj.hour * 1;
	var mm = obj.minutes * 1;
	var ss = obj.second * 1;
	if (mm < 10) { mm = "0" + mm; }
	if (ss < 10) { ss = "0" + ss; }
	
	var time = ""+hh+":"+mm+":"+ss;
	obj.value = time; // 外部へ結果渡しに使う
	return time;
}

function time_hourChanged(id){
	// 和暦の年数が変更されたなら西暦の年数も変更する
	var obj = moduleForId(id);
	obj.hour = obj.hourF.value * 1;
	document.getElementById(obj.id).value = time_string(obj);
}
function time_minutesChanged(id){
	// 和暦の月数が変更されたなら西暦の年数も変更する
	var obj = moduleForId(id);
	obj.minutes = obj.minutesF.value * 1;
	document.getElementById(obj.id).value = time_string(obj);
}
function time_secondChanged(id){
	// 和暦の日数が変更されたなら西暦の年数も変更する
	var obj = moduleForId(id);
	obj.second = obj.secondF.value * 1;
	document.getElementById(obj.id).value = time_string(obj);
}

function time_fieldSelected(num, id){
	// 時分秒のどのフィールドが選択されたかを記憶
	var obj = moduleForId(id);
	//	alert(obj.id+"^"+obj.year+"-"+obj.month+"-"+obj.day); //##
	var hourF = obj.hourF;
	var minutesF = obj.minutesF;
	var secondF = obj.secondF;
	hourF.style.color='#000';
	hourF.style.backgroundColor='#fff';
	minutesF.style.color='#000';
	minutesF.style.backgroundColor='#fff';
	secondF.style.color='#000';
	secondF.style.backgroundColor='#fff';
	num = num * 1;
	switch (num){
		case 0:
			hourF.style.color='#ff0';
			hourF.style.backgroundColor='#00f';
			hourF.focus();
			break;
		case 1:
			minutesF.style.color='#ff0';
			minutesF.style.backgroundColor='#00f';
			minutesF.focus();
			break;
		case 2:
			secondF.style.color='#ff0';
			secondF.style.backgroundColor='#00f';
			secondF.focus();
			break;
	}
	obj.selectedField = num;
}

function time_increment(id){
	// 数値をインクリメント
	var obj = moduleForId(id);
	var hh = obj.hourF.value * 1;
	var mm = obj.minutesF.value * 1;
	var ss = obj.secondF.value * 1;
	switch (obj.selectedField){
		case 0:
			if (hh < 24)
				dt_setHour(hh + 1, obj);
			break;
		case 1:
			if (mm >= 59){
				dt_setHour(hh + 1, obj);
				dt_setMinutes(0, obj);
			} else {
				dt_setMinutes(mm + 1, obj);
			}
			break;
		case 2:
			if (ss >= 59){
				dt_setMinutes(mm + 1, obj);
				dt_setSecond(0, obj);
			} else {
				dt_setSecond(ss + 1, obj);
			}
	}
	document.getElementById(obj.id).value = time_string(obj);
}

function time_decrement(id){
	// 数値をインクリメント
	var obj = moduleForId(id);
	var hh = obj.hourF.value * 1;
	var mm = obj.minutesF.value * 1;
	var ss = obj.secondF.value * 1;
	switch (obj.selectedField){
		case 0:
			if (hh > 1)
				dt_setHour(hh - 1, obj);
			else {
				dt_setHour(0, obj);
				dt_setMinutes(59, obj);
			}
			break;
		case 1:
			if (mm > 60){
				dt_setHour(hh - 1, obj);
				dt_setMinutes(59, obj);
			} else if (mm > 1){
				dt_setMinutes(mm - 1, obj);
			} else {
				dt_setMinutes(0, obj);
				dt_setSecond(59, obj);
			}
			break;
		case 2:
			if (ss > 0){
				dt_setSecond(ss - 1, obj);
			}
	}
	document.getElementById(obj.id).value = time_string(obj);
}

function TimeStepper(elm, id, hh, mm, ss, hasStepper){
	// 時刻入力モジュールを生成する *** コンストラクター ***
	// 複数使う場合は new TimeStepper() で生成すること
	// 外部からは this.value で結果をゲットできる
	// hasStepper が false なら +/- ボタンは省略
	this.id = id;
	this.hour = hh * 1;
	this.minutes = mm * 1;
	this.second = ss * 1;
	this.type = "timeStepper";
	
	// 時分秒
	this.hourF = newFIELD(elm, "_time_hour", "", 2, this.hour);
	newTEXT(elm, "時");
	this.hourF.setAttribute("onclick", "time_fieldSelected('0','"+id+"')");
	this.hourF.setAttribute("onchange", "time_hourChanged('"+id+"')");
	this.minutesF = newFIELD(elm, "_time_minutes", "", 2, this.minutes);
	newTEXT(elm, "分");
	this.minutesF.setAttribute("onclick", "time_fieldSelected('1','"+id+"')");
	this.minutesF.setAttribute("onchange", "time_minutesChanged('"+id+"')");
	if (ss){
		this.secondF = newFIELD(elm, "_time_second", "", 2, this.second);
		newTEXT(elm, "秒");
		this.secondF.setAttribute("onclick", "time_fieldSelected('2','"+id+"')");
		this.secondF.setAttribute("onchange", "time_secondChanged('"+id+"')");
	} else {
		this.second = 0;
		this.secondF = newHIDDEN(elm, "_time_second", this.second);
	}
	
	// 上下矢印
	if (hasStepper){
		var bt = newBUTTON(elm, "", "+");
		bt.setAttribute("onclick", "time_increment('"+id+"')");
		var bt = newBUTTON(elm, "", "-");
		bt.setAttribute("onclick", "time_decrement('"+id+"')");
	}
	
	// データ受け渡しのための隠しフィールド
	// ### 外部から document.getElementById(this.id).value で値をゲットできる
	var hd = newHIDDEN(elm, this.id, "");
	// var hd = newFIELD(elm, this.id, "", 30, ""); // テスト表示用
	document.getElementById(this.id).value = time_string(this);
	
	setModuleForId(this, id);
	return this;
}

////// 時刻入力フィールド ///////////////////////
//////////////////////////////////////////////

