
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 elmFor(id){
    // anId を id とするエレメントを返す
    var elm = document.getElementById(id);
    if (elm){
        return elm;
    } else {
        //alert(id + " を ID とするエレメントは存在しません");
        return null;
    }
}

function toggleNode(id){
    // 内容をトグル式に開閉
    var elm = elmFor(id);
    if (elm.style.display == "none")
        elm.style.display = "block"; // 表示
    else 
        elm.style.display = "none"; // 非表示
}

function showMessage(id, msg){
	// メッセージ・タグを開く
	// ## あらかじめ PHP ファイルなどに以下を埋め込んでおくこと ##
	// <SPAN id="_message" STYLE="visibility: hidden; position: absolute;"></SPAN>
	var elm = document.getElementById(id);
    if (!elm){
        // alert(id + " is not found"); 
        return;
    }
	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);
	if (elm) elm.style.visibility = "hidden";
}

function foldNode(id){
	// id で識別されたノードを開いたり閉じたりする
	var elm = document.getElementById(id);
	if (elm){
		if (elm.style.display == "none")
            elm.style.display = "table-row"; // "block" 表示する
		else
			elm.style.display = "none"; // 表示しない
	}
}

function idOfCode(code){
    // code "id/class" から "id" を返す
    if (code && code.length){
        var array = code.split("/");
        return (array[0].length > 0) ? 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 _infoTipPanel;
function setInfoTipNode(panel){
	_infoTipPanel = panel;
}
function infoTip(){
	return _infoTipPanel;
}
function closeInfoTip(){
	// infoTip を閉じる
	if (! infoTip()) return;
	
	infoTip().display = "none";
	infoTip().innerHTML = "";
}
function _closeInfoTip(elm){
	elm.display = "none";
	elm.innerHTML = "";
}
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 + targetElement.offsetHeight + 5; // 表示するy座標
	elm.style.visibility = "visible";
    
    // 万一 inofoTIp が画面に残ってしまった場合に対応
    // ### どういう訳か closeInfoTip() ではうまく動作しない ###
    elm.setAttribute("onmouseover", "_closeInfoTip(this)");
    
    // 画面右端からはみ出るようなら位置を調整
    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;
}
function setInfoTip(targetId, comment){
    // targetId にマウスが載ったら comment の infoTip を表示
    
    // iOS ではボタンのタップと重なり使い勝手が悪くなるので infoTIp を起動しない
    if ((osType() == "ipad") || (osType() == "iphone")) return;
    
    var elm = document.getElementById(targetId);
    elm.setAttribute("onmouseover", "kickInfoTip('"+targetId+"','"+comment+"')");
    elm.setAttribute("onmouseout", "closeInfoTip()");
}

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 openHelp(url){
	// HELP を表示
	window.open(url,"Help","width=450,height=700,scrollbars=yes,resizable=yes");
}

function makePopupMenu(elm, id, array, selectedItem){
    alert("makePopupMenu() is regacy");
    return newPopupMenu(elm, id, array, selectedItem);
}
function newPopupMenu(elm, id, array, selectedItem){
	var sl = document.createElement('SELECT');
	sl.setAttribute("id", id);
	elm.appendChild(sl);
    
    for (i in array){
		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;
}

var _datePopupReceiver = new Object();
var _oldDateLabel;
var _noChangeMaxDays;
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 は省略可
    //_debug("== newDatePopUp->"+id+"->"+label+"->"+yyyy+"->"+mm+"->"+dd); //##
    
    if (receiver) _datePopupReceiver[id] = receiver;
    _oldDateLabel = label;
    
    // 年号ラベル
    if (label != "西暦"){
        var sp = newSPAN(elm, "_koyomiLabel");
        var labels = nengouArray(); // lib.js "西暦","平成","昭和","大正","明治";
        if (yyyy > 0) label = nengou(yyyy); // yyyy に相当する和暦ラベル
        var npop = newPopupMenu(sp, id+".koyomiLabel", labels, label);
        npop.setAttribute("onchange", "_labelPopupChanged('"+id+ "')");
    }
    
	var sp = newSPAN(elm, id+"_koyomiYear");
    _setDatePopYear(id, label, yyyy);
    //_debug("-- _setDatePopYear->done"); //##
	
    // MONTH popup
	var months = makeArray(1, 12);
    months.splice(0,0,"");
	var mpop = newPopupMenu(elm, id+".month", months, mm*1);
    //_debug("-- mpop->"+mpop); //##
	mpop.setAttribute("onchange", "_datePopupChanged('" + id + "')");
	
    // 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 day = (noDay) ? 1 : dd * 1; // 日表示がない場合、日は１で固定
	var dpop = newPopupMenu(sp, id+".day", days, day);
	dpop.setAttribute("onchange", "_datePopupChanged('" + id + "')");
    //_debug("-- dpop->"+dpop); //##
    
    // 西暦年月日の隠しフィールド
    var fd = newHIDDEN(elm, id, "");
    
    //_debug("-- newDatePopUp:id("+id+")"+label+":"+yyyy+"/"+mm+"/"+dd); //##
	
    // ここで日ポップアップの日数を変更するとエラーが起こるので日数変更なしの true をつける
    _noChangeMaxDays = true;
    _datePopupChanged(id);
    
    //_debug("-- noDay->"+noDay); //##

    // 日ポップアップが指定されていない場合、それを表示しない
	if (noDay){
		// ## これは calendar.js から呼ばれた時に利用される
		dpop.style.visibility = "hidden";
		dpop.style.width = "0px";
	}
}
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 nenElm = document.getElementById(id+".koyomiLabel");
    var nengou = (nenElm) ? nenElm.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 は西暦年とする
    //_debug("== _setDatePopYear->"+id+"->"+label+"->"+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");
    if (sp){
        sp.innerHTML = "";
        
        var ypop = newPopupMenu(sp, id+".warekiYear", years, year); // 和暦
        ypop.setAttribute("onchange", "_datePopupChanged('"+id+"')");
    }
}
function _setDatePopField(id, val){
    // 隠しフィールドにデータを記憶するとともに、レシーバにその値を返す
    document.getElementById(id).value = val;
    //alert("_setDatePopField->"+id+"->"+document.getElementById(id).value); //##
    
    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 = newPopupMenu(sp, id+".day", days, dd*1);
                dpop.setAttribute("onchange", "_datePopupChanged('" + id + "')");
            }
        }
    }
    _noChangeMaxDays = false;
    
    if (_datePopupReceiver[id])
        eval('(' + _datePopupReceiver[id](val) + ')');
}


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 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 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 newFRAMESET(elm, name, cols, rows){
    var el = document.createElement('frameset');
    el.setAttribute("name", name);
    if (cols) el.setAttribute("cols", cols);
    if (rows) el.setAttribute("rows", rows);
    elm.appendChild(el);
    
    return el;
}
function newFRAME(elm, name, src, frameborder){
    var el = document.createElement('frame');
    el.setAttribute("name", name);
    el.setAttribute("src", src);
    el.setAttribute("marginheight", 0);
    el.setAttribute("marginwidth", 0);
    if (frameborder) 
        el.setAttribute("frameborder", 1);
    else
        el.setAttribute("frameborder", 0);
    elm.appendChild(el);
    
    return el;
}

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

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 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 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 newTEXT(elm, value){
	// elm の下に TEXT を生成して返す
	var tx = document.createTextNode(value);
	elm.appendChild(tx);
	return tx;
}

function newFIELD(elm, id, label, size, value){
	// 入力フィールドを生成
	if (label.length > 0){
		var tx = 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 newOnOffButton(id, label, onStatus, receiver){
    // On/OFF ボタンを生成
    // id はボタンを貼り付ける親ノードの ID
    var elm = document.getElementById(id);
    elm.innerHTML = "";
    
    if (onStatus * 1 > 0){
        var bt = newSPAN(elm, "/onButton");
        bt.innerHTML = label; // ON
        var val = "'" + id + "','" + label + "','0','" + receiver + "'";
        bt.setAttribute("onclick", "newOnOffButton(" + val + ")");
        eval(receiver + "(0)");
    } else {
        var bt = newSPAN(elm, "/offButton");
        bt.innerHTML = label; // OFF
        var val = "'" + id + "','" + label + "','1','" + receiver + "'";
        bt.setAttribute("onclick", "newOnOffButton(" + val + ")");
        eval(receiver + "(1)");
    }
}*/

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

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 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 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;
}

var _clientX;
var _clientY;
var _cursorLocked;
function cursorLock(elm){ // mouse down
	_cursorLocked = true;
}
function cursorUnlock(){ // mouse up
	_cursorLocked = false;
}
function getMouseXY(evt){
	// マウスでパネルのタイトルを掴み移動させる
	// Firefox ではうまく動作しない
	if (_cursorLocked){ // mouse down
        var panelWidth = floatPanel().clientWidth;
        floatPanel().style.left = evt.clientX - (panelWidth / 2); // 表示するx座標
		floatPanel().style.top = evt.clientY - 10; // 表示するy座標
	}
}
function mouseX(){
	return _clientX;
}
function mouseY(){
	return _clientY;
}

var _floatPanel;
function setFloatPanel(panel){
	_floatPanel = panel;
}
function floatPanel(){
	return _floatPanel;
}
function closeFloatPanel(id){
	// 確認パネルを閉じる
    var panel = (id) ? elmFor(id) : floatPanel();
	closeInfoTip();
    if (panel){
        panel.innerHTML = "";
        // ## マウス・イベントが横取りされないようワークスペース外に押し出しておく
        //panel.style.left = -10000; // 表示するx座標
        panel.style.visibility = "hidden";
    }
	window.onmousemove = false; // マウス制御を解除しておく
}
function openFloatPanel(element, x, y, title, status, closeAction){
	// 確認パネルを開く
	window.onmousemove = true; // マウス制御を起動
	var elm = element.parentNode; // _panel と同じもの
    elm.setAttribute("class", "floatPanel");
	elm.style.color = "#000"; // アプリで白文字に設定することがあるので
	setFloatPanel(elm);
	
	// floatPanel の基盤層にパネルを閉じる動作を設定
	var parent = elm.parentNode;
    var fixed = (status && status.length) ? true : false;
	
	// タイトルを掴んでドラッグできる
	if (! fixed) window.onmousemove = getMouseXY;
	
	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, "", "");
	tr.setAttribute("onmousedown", "cursorLock(this)"); // マウスで掴み可動にする
	tr.setAttribute("onmouseup", "cursorUnlock()"); // マウスで掴み可動にする
    
	var td = newTD(tr, "/yellow-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;
    sp.style.fontSize = "10pt";
    
    var sp = newSPAN(td, "floatPanelOptionArea");
    
	// CONTENTS
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "", "");
	td.appendChild(element);
}

function openSeeThroughPanel(id, x, y, w, title, helpAction, titleAction){
	// 半透明パネルを開く
	var elm = document.getElementById(id);
    if (!elm){
        alert(id + " がないのでパネルを表示できません");
        return null;
    }
    window.onmousemove = getMouseXY
	setFloatPanel(elm);
    
	elm.style.padding = "5px";
    elm.style.borderRadius = "10px";
	elm.style.left = x; // 表示するx座標
	elm.style.top = y; // 表示するy座標
	elm.style.width = w;
	elm.style.backgroundColor = "#eee";
	elm.style.opacity = "0.7";
    elm.style.boxShadow = "2px 2px 10px 2px #555";
	elm.style.visibility = "visible";
	elm.innerHTML = "";
    
    // === HEADER =============
    var div = newDIV(elm, "/clearfix");
	div.setAttribute("onmousedown", "cursorLock(this)"); // マウスで掴み可動にする
	div.setAttribute("onmouseup", "cursorUnlock()"); // マウスで掴み可動にする
    var rightWidth = 20; // RIGHT SIDE WIDTH
    // --- LEFT SIDE
    // CLOSE BUTTON
    var dv = newDIV(div, "/left-side");
    dv.style.width = (w - 20 - 5) + "px";
    dv.style.padding = "0"; // CSS を上書き
    var bt = newDIV(dv, "/closeButton");
    bt.style.fontSize = "10pt";
	bt.style.fontWeight = "bold";
    bt.innerHTML = "x";
	bt.setAttribute("onclick", "closeFloatPanel('" + id + "')");
    // TITLE
    if (title){
        var sp = newSPAN(dv, "seeThroughPanelTitle"); // 外部から取得するための ID
        sp.innerHTML = title;
        sp.style.fontSize = "9pt";
        elm.style.opacity = "1.0";
        
        if (titleAction){
            // タイトルをクリックすると titleAction を実行
            sp.setAttribute("onclick", titleAction);
            sp.setAttribute("class", "record");
            sp.style.padding = "0 10px";
            sp.style.borderRadius = "10px";
        }
    }
    // --- RIGHT SIDE
    var dv = newDIV(div, "/right-side");
    dv.style.width = rightWidth + "px";
    dv.style.padding = "0"; // CSS を上書き
    dv.style.position = "relative";
    dv.style.top = "3px";
    dv.style.padding = "0"; // CSS を上書き
    // HELP
    if (helpAction){
        var img = newIMAGE(dv, "", "help.png", "help");
        img.style.height = "15px";
        img.setAttribute("onclick", helpAction);
        img.setAttribute("class", "expandIcon");
    }
    
    // === CONTENTS ===============
	var contents = newDIV(elm, "");
    contents.style.marginTop = "5px";
    
    return contents;
}


/////////////////////////////////////
//////// fade out ///////////////////

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();
        closeInfo();
		return;
	}
	
	var time = fadeOutTime(); // この時間まではフェードアウト開始しない
	if (time == 0) return; // フェードアウトタイムがゼロならフェードアウトしない
	var interval = (_opct < 0.9) ? 30 : time; // 変化させる間隔（ミリ秒単位）
	setTimeout("fadeOut()", interval);
}

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

//////// fade out ///////////////////
/////////////////////////////////////

///////////////////////////////////////////////////
///// 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 moveCursorAtEndOf(elm){
    // elm 中のカーソルを文末に置く
    elm.focus();
    
    // 入力欄を一旦、全選択にしておく
    var rng = document.createRange();
    rng.selectNodeContents(elm);
    window.getSelection().addRange(rng);
    
    // HTML5：選択された欄の文末にカーソルを置く
    var sel = window.getSelection();
    sel.collapseToEnd();
}

///// カーソル・コントロール //////////////////////////
///////////////////////////////////////////////////

///////////////////////////////////////////////////////
///// 文字列長制限メニュー ////////////////////////////////

var _limitedMenus;
var _limitedPopupMenu;

function closeLimitedInfo(){
    // infoTip を削除
    var elm = elmFor("limitedInfoArea");
    if (elm) elm.parentNode.removeChild(elm);
}
function showLimitedInfo(elm, popupId){
    // 選択されたポップアップ・メニューのフルスペルを表示
    var index = elmFor(popupId).selectedIndex;
    var fullname = _limitedMenus[index];
    if (fullname.length == 0) return;

    var pos = getPosition(elm);

    // 不可視設定の DIV: _infoTip を用意する必要あり
    var elm = document.getElementById("_infoTip");
    if (!elm){
        alert("_infoTip がありません"); return;
    }
    elm.innerHTML = "";
	elm.style.left = pos.x + 0; // 表示するx座標
	elm.style.top = pos.y + 28; // 表示するy座標
	elm.style.visibility = "visible";

    // infoTip を表示
    var p = newSPAN(elm, "limitedInfoArea/infoTIp"); // ## これにより残像発生を防ぐ
    p.innerHTML = fullname;
}

function selectedLimitedMenu(){
    // 文字列制限メニューの選択されたメニューを返す
    if (_limitedPopupMenu){
        var index = _limitedPopupMenu.selectedIndex;
        
        return _limitedMenus[index];
    } else {
        return "";
    }
}

function makeLimitedMenu(elm, menus, item, length, receiver){
    // 文字列長制限メニュー用のメニュー配列を設定
    _limitedMenus = menus;
    
    // 文字列長制限メニューを生成
    var array = [];
    for (num in _limitedMenus){
        var menu = _limitedMenus[num];
        if (menu.length > length) menu = menu.substr(0, length);
        array.push(menu);
    }
    
    // 文字列制限ポップアップ・メニューを生成
    var popupId = "limitedPopupId";
    var pu = newPopupMenu(elm, popupId, array, item);
    if (receiver) pu.setAttribute("onchange", receiver);
    pu.setAttribute("onmouseover", "showLimitedInfo(this,'" + popupId + "')");
    pu.setAttribute("onmouseout", "closeLimitedInfo()");
    _limitedPopupMenu = pu;
}

///// 文字列長制限メニュー ////////////////////////////////
///////////////////////////////////////////////////////


