
var _owner;
function setOwner(val){
    _owner = val;
}
function owner(){
	return _owner;
}

var _hid;
function setHospitalId(val){
    _hid = val;
}
function hospitalId(){
	return _hid;
}

var _hname;
function setHospitalName(val){
    _hname = val;
}
function hospitalName(){
	return _hname;
}
function setArguments(){
	// parent から URI に添付して転送されたパラメータを解析して記憶
	var elm = document.getElementById("_value");
    //alert("=== setArguments ->" + elm.value); //##
	if (elm && elm.value){
        var st = decodeSTRING(elm.value);
        var obj = decodeObject(st);
        setOwner(obj.owner);
        setHospitalId(obj.hospitalId);
        setHospitalName(obj.hospitalName);
        
        //alert(encodeObject(obj)); //##
        
        if (owner() && hospitalId()) return true;
	}
	return false;
}

var _submenus;
function initSubMenu(){
	_submenus = new Array();
}
function addSubMenu(menuItem, action){
	var obj = new Object();
	obj.item = menuItem;
	obj.action = action;
	_submenus.push(obj);
}
function subMenus(){
	return _submenus;
}

var _records;
function setRecords(obj){
	_records = obj;
}
function recordForEntryDate(dataAndId){
	return _records[dataAndId];
}

var _hasMonthlyMode;
function setHasMonthlyMode(status){
    _hasMonthlyMode = status;
}
function hasMonthlyMode(){
    return  _hasMonthlyMode;
}

var _layoutObj;
function setLayoutObj(obj){
    // レイアウトを決める属性
    //alert("setLayoutObj->"+encodeObject(obj)); //##
    
    _layoutObj = obj;
    
    showTimeZonePop(obj.timeZone);
    setControls(obj.checkBox);
    setPlanColumnConf(obj.plan);
    setDailyColumnConf(obj.day);
    setMonthlyColumnConf(obj.month);
}
function timeZone(){
    // val: "0900-1200,1500-1700"
    return _layoutObj.timeZone.split(",");
}
function checkArray(){
    // ヘッダー行のコントロール属性：カンマで区切られた文字列を配列にして返す
    return _layoutObj.checkBox.split(",");
}
function firstItem(){
    // 初期表示項目："日計表" などの文字列で返す
    return _layoutObj.firstItem;
}
function planArray(){
    // 予定表の属性：カンマで区切られた文字列を配列にして返す
    return _layoutObj.plan.split(",");
}
function dayArray(){
    // 日計表の属性：カンマで区切られた文字列を配列にして返す
    return _layoutObj.day.split(",");
}
function monthArray(){
    // 月計表の属性：カンマで区切られた文字列を配列にして返す
    return _layoutObj.month.split(",");
}

/////////////////////////////////////////////

var _sectionCode = ""; // Global 変数
var _groupCode = ""; // Global 変数

var _isDaily = 0;
var _isMonthly = 1;
var _isPlan = 2;
var _mode = _isDaily;
function setMode(mode){
	_mode = mode;
}
function mode(){
	return _mode;
}

var _timeStamp = ""; // Global 変数
function timeStamp(){
	return _timeStamp;
}
function setTimeStamp(datetime){
	_timeStamp = datetime;
}

function sectionCode(){
	return _sectionCode;
}
function setSectionCode(st){
	_sectionCode = st;
}

function groupCode(){
	return _groupCode;
}
function setGroupCode(st){
	_groupCode = st;
}

var _itemArray; // = new Array(); // Global 変数

function initItemArray(){
	_itemArray = new Array();
}
function addItemArray(item){
	_itemArray.push(item);
}
function removeItemArray(number){
	for (var i=_itemArray.length-1; i >= 0; i--){
		var _item = _itemArray[i];
		if (number == _item.number) _itemArray.splice(i, 1);
	}
}
function countOfItemArray(){
	return _itemArray.length;
}
function itemAtIndexOf(ix){
	// itemArray の ix 番目の item を返す
	return (ix < _itemArray.length) ? _itemArray[ix] : null;
}
function itemOfNumber(number){
	// number を ID とする item を返す
	var count = _itemArray.length;
	for (var i=0; i < count; i++){
		var item = _itemArray[i];
		if (item.number == number) return item;
	}
	return null;
}

function setWeek(date){
	// 指定された年月日の曜日を埋め込む
	var week = weekOfDate(date); // lib.js
	var td = document.getElementById("weekArea");
	td.innerHTML = " (" + week + ") ";
}

var _sortOrder;
function setSortOrder(order){
	// "1" or "0" or null
	_sortOrder = (order && (order == "1")) ? "1" : "0";
	//alert("setSortOrder:"+_sortOrder); //##
}
function sortOrder(){
	return _sortOrder;
}
function toggleSortOrder(){
	// 受付時刻でソート・逆ソートを交互に変換
	_sortOrder = (_sortOrder * 1 > 0) ? "0" : "1";
	//alert(_sortOrder); //##
	putSortOrder(_sortOrder);
}

/////////////////////////////////////
///// POLLING ///////////////////////

function polling(){
	// 再帰的に実行する内容を記述
	switch (mode()){
		case _isMonthly:
			return;
		default:
			getDailyList();
			break;
	}
    
	// ポップアップ年月日が本日以外ならポーリングしない
    if (!isToday()) return;
    
    // 初期設定パネルが開いているならポーリングしない
    // 初期設定パネルでの Ajax が polling での Ajax と衝突するのを防ぐため
    if (document.getElementById("_floatPanel").innerHTML.length) return;
    
    // 一定時刻ごとに再帰処理
    setTimeout(polling, 3000);
}

///// POLLING ///////////////////////
/////////////////////////////////////



///////////////////////////
/// CONFIGRATION //////////

var _hasDatetime;
function setHasDatetimeButton(status){
	_hasDatetime = status;
}
function hasDatetimeButton(){
	return _hasDatetime;
}

var _hasPlan;
function setHasPlanButton(status){
	_hasPlan = status;
}
function hasPlanButton(){
	return _hasPlan;
}

var _hasVisitorList;
function setHasVisitorList(status){
	_hasVisitorList = status;
}
function hasVisitorList(){
	return _hasVisitorList;
}

var _hasTotal;
function setHasTotal(status){
    _hasTotal = status;
}
function hasTotal(){
    return _hasTotal;
}

var _hasAverage;
function setHasAverage(status){
	_hasAverage = status;
}
function hasAverage(){
	return _hasAverage;
}

var _daylyColumnConf;
function setDailyColumnConf(buff){
	// labels = array("時刻,PID,,,") 形式
    if (buff){
        var labels = buff.split(",");
        var array = new Array();
        var objects = daylyItems(); // preference.js
        for (i in labels){
            var label = trim(labels[i]);
            if (label.length == 0) continue;
            if (hasMember(dayArray(), label) == 0) continue;
            
            var obj = objects[label];
            if (obj) array.push(obj);
        }
        _daylyColumnConf = array;
    }
}
function daylyColumnConf(){
	// 日計表構成を返す
	return _daylyColumnConf;
}

var _planColumnConf;
function setPlanColumnConf(buff){
	// labels = array("時刻,PID,,,") 形式
    if (buff){
        var labels = buff.split(",");
        var array = new Array();
        var objects = planItems(); // preference.js
        for (i in labels){
            var label = trim(labels[i]);
            if (label.length == 0) continue;
            if (hasMember(planArray(), label) == 0) continue;
            
            var obj = objects[label];
            if (obj) array.push(obj);
        }
        _planColumnConf = array;
    }
}
function planColumnConf(){
	// 予定表構成を返す
	return _planColumnConf;
}

var _monthlyColumnConf;
function setMonthlyColumnConf(buff){
	// labels = array("時刻,PID,,,") 形式
    if (buff){
        var labels = buff.split(",");
        var array = new Array();
        var objects = monthlyItems(); // preference.js
        for (i in labels){
            var label = trim(labels[i]);
            if (label.length == 0) continue;
            if (hasMember(monthArray(), label) == 0) continue;
            
            var obj = objects[label];
            if (obj) array.push(obj);
        }
        _monthlyColumnConf = array;
    }
}
function monthlyColumnConf(){
	// 月計表構成を返す
	return _monthlyColumnConf;
}

/// CONFIGRATION //////////
///////////////////////////



///////////////////////////
/// Ajax による処理 /////////

function checkDB(){
	// NOA database 構造をチェックし必要なら最新構造にする
	xmlHttpObject = createXMLHttpRequest();
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		var st = "/XNOA/server.php?command=CHECK_DB";
		//alert(st);
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function puttedSortOrder(){
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//alert("puttedSortOrder:\n"+value);//##
		var ary = value.split("<SEPARATOR>");
		if (ary.length > 1){
			// polling が機能していれば不要
			getDailyList();
		}
	}
}
function putSortOrder(order){
	// 受付時刻による表示順を昇順・降順で反転させる
	xmlHttpObject = createXMLHttpRequest(puttedSortOrder);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		var array = new Array();
		array['owner'] = owner();
		array['sortOrder'] = order;
		var val = encodeObject(array);
		
		var st = "./frontServer.php"
		+ "?command=PUT_SORT_ORDER"
		+ "&value=" + val;
		//alert("putSortOrder ---\n"+st); //return; //##
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function gotLayoutParts(){
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//alert("gotLayoutParts:\n"+value);//##
        
        // まずテンプレートを元に属性を設定
        var obj = new Object();
        obj.checkBox = layoutChecksTemplate();
        obj.firstItem = "予定表";
        obj.timeZone = "0900-1200";
        obj.plan = planTemplate();
        obj.day = dayTemplate();
        obj.month = monthTemplate();

        // サーバからのデータのあるものは上書き
		var array = value.split("<SEPARATOR>");
		if (array.length > 1){
            if (array[1].length){
                var rec = decodeObject(array[1]);
                //alert("gotLayoutParts:\n"+encodeObject(rec));//##
                if (rec.checkBox) obj.checkBox = rec.checkBox;
                if (rec.firstItem) obj.firstItem = rec.firstItem;
                if (rec.timeZone) obj.timeZone = rec.timeZone;
                if (rec.plan) obj.plan = rec.plan;
                if (rec.day) obj.day = rec.day;
                if (rec.month) obj.month = rec.month;
            }
		}
        
        setLayoutObj(obj);
        checkDB();
	}
}
function getLayoutParts(){
	// レイアウトをサーバへリクエスト
	xmlHttpObject = createXMLHttpRequest(gotLayoutParts);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
        var args = new Array();
        args['owner'] = owner();
        
		var st = "./frontServer.php?command=GET_LAYOUT_PARTS"
        + "&value=" + encodeObject(args);
		//alert(st);//##
        
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function removedPatient(recNumber){
	// 再来患者が削除されたことを確認
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//alert(value);//##
		var ary = value.split("<SEPARATOR>");
		if (ary.length > 1){
			// polling on では不要だが off の時のため設置
			getDailyList();
		}
	}
}
function removePatient(dataAndId){
	// entryDate のレコード削除をリクエスト
	//alert("removePatient ---\n"+dataAndId); //##
	var rec = recordForEntryDate(dataAndId);
	var st = rec.entryDate + " " + rec.kanjiName;

	if (confirm("(" + st + ") を削除します")){
		xmlHttpObject = createXMLHttpRequest(removedPatient);
		if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
			var st = "./frontServer.php"
			+ "?command=REMOVE_PATIENT"
			+ "&entryDate="+rec.entryDate
			+ "&patientId="+rec.patientId;
			//alert("removePatient ---\n"+st); return; //##
			xmlHttpObject.open("GET", encodeURI(st), true);
			xmlHttpObject.send(null);
		}
	}
}

function gotDailyList(){
	// 当日の来院患者リストを表示
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//alert("gotDailyList ---\n"+value); //== polling を切っておくこと
		
		// mode により、患者登録フィールドを表示・非表示
		var elm1 = document.getElementById("registArea");
		elm1.style.visibility = "visible";
        if (!isToday()) elm1.style.visibility = "hidden";
        
		var elm2 = document.getElementById("toolButton");
		elm2.style.visibility = "visible";
		
		var ary = value.split("<SEPARATOR>");
		if (ary.length > 1){
			// obj.timeStamp, obj.message, obj.sortOrder, obj.records
			//var obj = JSON.parse(ary[1]); // ### old MAC で動かない？ ###
			var obj = eval('(' + ary[1] + ')');
			//alert(encodeObject(obj)); //##
			
			// リストを降順・昇順で表示する時に使う
			setSortOrder(obj.sortOrder);
			kickMessage(obj.message);
			setRecords(obj.records);
            
			// タイムスタンプによる処理
			var ts = obj.timeStamp;
            // heat beat
            var date = new Date();
            document.getElementById("message").innerHTML = date.toString();
			if (ts == "same"){ // サーバが更新されていなかった
				return;
			} else if (ts == "empty"){	// タイムスタンプがなかった
				setTimeStamp(ts);	// タイムスタンプを記憶
			} else {	// サーバのタイムスタンプが更新されていた
				setTimeStamp(timeStamp);	// タイムスタンプを記憶
			}

			// obj.records の処理
			var elm = document.getElementById("resultsArea");
			elm.innerHTML = "";
			var tbl = newTABLE(elm, "frontTable");
            tbl.style.fontSize = "10pt";

			// タイトル
			var tr = titleDescription(tbl);
			// 日計表
			var recs = obj.records;
			var row = 0;
			for (dateAndId in recs){
				var rec = recs[dateAndId];
				rec.dateAndId = dateAndId;
				if (matchInOut(rec.inOut))
					recordDescription(tbl, rec, row++); // 登録者行
			}
			// 集計行
			dailyTotalDescription(tbl);
		}
	}
	
	function matchInOut(inOut){
		var td = document.getElementById("inpatient");
		if (!td) return true; // inpatient が指定されていなければ true
		
		// inOut が「外来/入院」チェックボックスと一致する場合のみ表示
		// rec.inout = ["on", ""|"0"]
		if ((inOut == "on") || (inOut * 1 > 0)){ // 入院チェックボックス
			return document.getElementById("inpatient").checked;
		}
		else { // 外来チェックボックス
			return document.getElementById("outpatient").checked;
		}
	}
}
function getDailyList(){
	// 指定日の受診者リストをリクエスト
    
    // 診療時間帯ポップアップが生成されるまで多少タイムラグがあるのでこの間はスキップ
    var elm = document.getElementById("timeZonePopup");
    if (!elm) return;

	xmlHttpObject = createXMLHttpRequest(gotDailyList);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
        // 診療時間帯の指定があれば timeZone と timeStamp を指定
        var zone = document.getElementById("timeZonePopup").value;
        var stamp = "";
        if (zone && (zone == "全日")){
            zone = "0000-2400";
            stamp = timeStamp();
        }
        
        var array = new Array();
        array['timeZone'] = zone;
		array['owner'] = owner();
		array['entryDate'] = pageDate();
		array['timeStamp'] = stamp;
		var val = encodeObject(array);
		
		var entryDate = pageDate();
		var st = "./frontServer.php"
		+ "?command=GET_DAILY"
		+ "&value=" + val;
        
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function gotMonthlyList(){
	// 再来患者が登録されたことを確認
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
        //alert("gotMonthlyList->"+value); //##
		var ary = value.split("<SEPARATOR>");
		if (ary.length > 1){
			var buff = ary[1];
			// frontServer から送られたリストを itemArray にセット
			var elm = document.getElementById("resultsArea");
			elm.innerHTML = "";
			var tbl = newTABLE(elm, "frontTable");
            tbl.style.fontSize = "10pt";
			
			// registArea を空にする
			var elm = document.getElementById("registArea");
			elm.style.visibility = "hidden";
			var elm = document.getElementById("toolButton");
			elm.style.visibility = "hidden";
            
			var tr = titleDescription(tbl);
			if (buff.length){
				initItemArray();
				var records = buff.split("_||_");
                var rows = 0;
                for (num in records){
					var ln = records[num];
					if (ln.length > 0){
						var tr = monthlyDescription(tbl, ln);
						if (Math.floor(num / 2) * 1 == (num / 2)){
							tr.style.backgroundColor="#fff";
						} else {
							tr.style.backgroundColor="#dfc";
                        }
						rows++;
					}
				}
				monthlyTotalDescription(tbl, rows);
			}
		} else
			document.getElementById("resultsArea").innerHTML = value;
	} else 
		document.getElementById("resultsArea").innerHTML = "Loading monthlyList ...";
}
function getMonthlyList(){
	// 指定月の受診者リストをリクエスト
	xmlHttpObject = createXMLHttpRequest(gotMonthlyList);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
        var zone = document.getElementById("timeZonePopup").value;
        if (zone && (zone == "全日"))
            zone = "0000-2400";

		var elm = document.getElementById("inpatient");
		var inStatus = (elm.checked) ? 1 : 0;
		var elm = document.getElementById("outpatient");
		var outStatus = (elm.checked) ? 1 : 0;
		var entryDate = pageDate();

        var args = new Array();
        args['timeZone'] = zone;
		args['entryDate'] = encodeSTRING(entryDate);
		args['in'] = inStatus;
		args['out'] = outStatus;
        
        var st = "./frontServer.php"
        + "?command=GET_MONTHLY_LIST"
        + "&value=" + encodeObject(args);

		//alert("getMonthlyList --\n"+st); //return; //##
        
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}


function showInsListPanel(){
	// 指定月の健保受診者リストをリクエスト
    window.open("./insList.html", "", "width=400 height=700"); 
}

function registedNewPatient(patientId){
	// NOA:patientRegister からの返事を受け取る
    
	registPatient(patientId, todayAndTime(), false); // 新患登録された pateintId を受付
}

function registedPatient(){
	// 再来患者が登録されたことを確認
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//alert("registedPatient:\n"+value); //###
        
		var ary = value.split("<SEPARATOR>");
		if (ary.length > 1){
			var obj = eval('(' + ary[1] + ')');
			switch (obj.mode * 1){
				case 1: // 既に登録済み
					if (confirm(obj.message + "\n同日再診で登録しますか？")){
						registPatient(obj.patientId, obj.entryDate, true);
					}
					break;
				case 2: // レコード更新
				case 3: // 新規レコード追加
					getDailyList(); // polling off の時のため設置
					break;
				default:
					alert(obj.message);
					openPatientRegister(); // 新患登録
					break;
			}
		}
		document.getElementById("message").innerHTML = "";
	}
	else 
		document.getElementById("message").innerHTML = "Loading...";
}
function registPatient(patientId, entryDate, duplicate){
	// 再来患者を登録する
    //alert("registPatient:"+patientId+"->"+entryDate); //## 111016

	if (patientId.length == 0) return;
	
	xmlHttpObject = createXMLHttpRequest(registedPatient);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
        //### どういうわけか jellyFish ではこの後 server でコケるので
        //### patientId フィールドに patientId を入力しておく
        //document.getElementById("patientId").value = patientId;
        // ### 以前の patientId が残っていると使いにくいとのことで空白とする
        document.getElementById("patientId").value = "";
        
		var st = "./frontServer.php"
		+ "?command=PUT_PATIENT"
		+ "&value=" + args(patientId, entryDate, duplicate);
        
		//alert("registPatient:\n"+st); //###
        
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
	
	function args(patientId, entryDate, duplicate){
		// ### arguments() という関数名は Firefox ではエラーになる
		var ary = new Array();
		ary[0] = entryDate; // "2008-12-01 21:06:02"
		ary[1] = patientId;
		ary[2] = ""; //document.getElementById("ed_patientKanjiName").value;
		ary[3] = userCode(); //document.getElementById("ed_userCode").value;
		ary[4] = ""; //document.getElementById("ed_inOut").value;
		ary[5] = ""; //document.getElementById("ed_newPatient").value;
		ary[6] = groupCode(); //document.getElementById("ed_groupCode").value;
		ary[7] = ""; //document.getElementById("ed_insFee").value;
		ary[8] = ""; //document.getElementById("ed_ownFee").value;
		ary[9] = ""; // 未収金：これが空だと PatientTable の未収金が使われる
		ary[10] = ""; //document.getElementById("ed_receive").value;
		ary[11] = owner();
		ary[12] = (duplicate) ? "" : "regist_mode";
		ary[13] = ""; //anotherId;
		return ary.join("_|_");
	}
}

function changedPatient(){
	// 再来患者が登録されたことを確認
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//alert("changedPatient:\n"+value); //###
		var ary = value.split("<SEPARATOR>");
		if (ary.length > 1){
		 getDailyList(); // polling off の時のため設置
		}
		document.getElementById("message").innerHTML = "";
	}
	else 
		document.getElementById("message").innerHTML = "Loading...";
}
function changePatient(patientId, entryDate, dateTime){
	// patientId, entryDate のレコードを args 内容に変更
	xmlHttpObject = createXMLHttpRequest(changedPatient);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		var args = new Array();
		args['patientId'] = patientId;
		args['entryDate'] = entryDate;
		args['owner'] = owner();
		args['plan'] = ""; // 予約を無しにする
		args['newEntryDate'] = dateTime; // entryDate を本日のタイムスタンプにする

		var st = "./frontServer.php"
		+ "?command=PUT_PLAN"
		+ "&value=" + encodeObject(args);
		//alert("changePatient:\n"+st); //###
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
	
}	

function puttedBill(){
	// 再来患者が登録されたことを確認
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//alert("puttedBill:\n"+value);//###
	}
}
function putBill(patientId, entryDate, receive, mishuu){
	// 再来患者を登録する
	//xmlHttpObject = createXMLHttpRequest(_debug);
	xmlHttpObject = createXMLHttpRequest(puttedBill);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		// mishuu: "2009-01-30 19:16:00,3650" 形式
		var st = "./frontServer.php?command=PUT_BILL"
		+ "&entryDate="+ encodeSTRING(entryDate)
		+ "&value=" + patientId+"_|_"+receive+"_|_"+entryDate+","+mishuu;
		//alert("putBill:\n"+st); //return; //###
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function savedPlan(){
	// 再来患者が登録されたことを確認
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//alert("savedPlan:\n"+value);//###
	}
}
function savePlan(patientId, entryDate, plan){
	// 編集された plan を FrontTable へ保存
	xmlHttpObject = createXMLHttpRequest(savedPlan);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		var array = new Array();
		array["owner"] = owner();
		array["patientId"] = patientId;
		array["entryDate"] = entryDate;
		array["plan"] = plan;

		var st = "./frontServer.php?command=PUT_PLAN"
		+ "&value=" + encodeObject(array);

		//alert("savePlan:\n"+st); //return; //###
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function gotUserTable(){
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
        //alert("gotUserTable->"+value); //##
		var array = value.split("<SEPARATOR>");
		if (array.length > 1){
			var obj = eval('(' + array[1] + ')');
			//alert("gotUserTable->"+encodeObject(obj)); //##
            
            setUserTable(obj);
            
            // footer にユーザ名を表示
            var elm = document.getElementById("kanjiNameArea");
            var kanjiName = kanjiNameFor(owner());
            elm.innerHTML = "取扱: "+ kanjiName + " @ " + hospitalName();
            
            // サーバへ owner() 用のレイアウトをリクエスト
            getLayoutParts();
		}
	}
}
function getUserTable(){
    // ユーザ情報をサーバへリクエスト
	xmlHttpObject = createXMLHttpRequest(gotUserTable);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		var st = "./frontServer.php?command=GET_USERS";
        
		//alert("savePreference:\n"+st); //return; //###
        
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

/// Ajax による処理 /////////
///////////////////////////

function openingCheck(){
	window.open("../MoneyCheck","MonyCheck"
						  ,"width=850,height=750,scrollbars=yes,resizable=yes");
}

function openAge(){
    // 年齢計算ツール
	window.open("../AGE","AGE","width=400,height=150,resizable=yes");
}

function setKanjiName(kanjiName){
	var elm = document.getElementById("kanjiNameArea");
	elm.innerHTML = "取扱: "+ kanjiName + " @ " + hospitalName();
}



////////////////////////////////
/// neuron.js による処理 /////////

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 closePatientList(){
	// 患者リストを閉じる
	document.getElementById("paientListArea").innerHTML = "";
}
function patientSelected(patientId){
	// 患者リストから１患者が選択された
    
	// 患者リストを閉じる
	closePatientList();

	// 選択された patientId を検索欄に転記
	document.getElementById("patientId").value = patientId;
    registPatient(patientId, todayAndTime(), false);
}
function gotPatients(answer){
	// 検索条件にマッチした患者リストを表示
	var records = eval('('+answer+')');
	records.sort(cmp_LVD); // 最終受診日順にソート
	
	var patientIdAndName;
	var count = records.length;
	if (count == 1){
		// patientId の受診者を FrontTable へ追加
        var patientId = records[0].patientId;
        registPatient(patientId, todayAndTime(), false);
	} else {
        var dom = document.getElementById("paientListArea");
        dom.innerHTML = "";
        var tbl = newTABLE(dom, "baseTable");
        tbl.style.margin = "2px 0px";
        var tr = newTR(tbl, "header", "");
        var td = newTD(tr, "", "");
        td.style.width = "17px";
        td.style.paddingLeft = "5px";
        var img = newIMAGE(td, "", "./close.png", "close");
        img.setAttribute("onclick","closePatientList()");
        img.style.height = "12px";
        var td = newTD(tr, "", "カルテ番号");
        var td = newTD(tr, "", "氏名");
        var td = newTD(tr, "", "ローマ字");
        var td = newTD(tr, "", "最終受診日");
        
        for (var r=0; r < count; r++){
            var rec = records[r];
            var kanji = (rec.patientKanjiName) ? rec.patientKanjiName : "";
            patientIdAndName = rec.patientId + ":" + kanji;
            var romaji = (rec.patientRomajiName) ? rec.patientRomajiName : "";
            var lvd = (rec.lastVisitDate) ? rec.lastVisitDate : "";
            var tr = newTR(tbl, "record", "");
            var action = "patientSelected('" + rec.patientId + "')";
            tr.setAttribute("onclick", action);
            setChangeColor(tr, '#000','#fff');
            var td = newTD(tr, "", "");
            var td = newTD(tr, "", rec.patientId);
            var td = newTD(tr, "", kanji);
            var td = newTD(tr, "", romaji);
            var td = newTD(tr, "", lvd);
        }
        var tr = newTR(tbl, "header", "");
        var td = newTD(tr, "", records.length + " レコード ");
        td.setAttribute("colspan", "5");
        td.style.paddingLeft = "20px";
    }
	
	
	function cmp_LVD(a, b){
		// 最終受診日で比較
		var st = a.lastVisitDate; //##
		var ary = st.split("-");
		var lvd = ary.join("/");
		var timea = new Date(lvd).getTime();
		var st = b.lastVisitDate; //##
		var ary = st.split("-");
		var lvd = ary.join("/");
		var timeb = new Date(lvd).getTime();
		
		return (timeb - timea);
	}
}
function registOldPatient(){
	// 本日の受診者を日計表に登録
	var elm = document.getElementById("patientId");
	var patientId = elm.value;
	elm.value = "";
	if (patientId.length > 0){
		// patientId の受診者を FrontTable へ追加
		NRGetPatients(patientId, gotPatients);
	} else {
		// 新患登録
		openPatientRegister();
	}
	
	function patientIdWithBirthDate(year, month, day){
		// 生年月日から patientId を計算して返す
		// 年は西暦であること
		if (year < 1900) return "???"; // エラー
		
		var yy = year % 100;
		var mm = (month < 10) ? "0" + month : month;
		var dd  = (day < 10) ? "0" + day : day;
		
		return mm + dd + yy;
	}
}

/// neuron.js による処理 /////////
////////////////////////////////



function pageDate(){
	var elm = document.getElementById("datePop");
	if (elm){
		return elm.value;
	} else {
		var now = todayAndTime();
		return now.substr(0, 10);
	}
}

function makeDateString(td){
	var st = todayAndTime().substr(0, 10); // lib.js
	var array = st.split("-");
    
    var sp = newSPAN(td, "");
    sp.style.fontSize = "12pt";
    sp.style.padding = "0px 8px";
    sp.innerHTML = array[0]+"年"+array[1]+"月"+array[2]+"日";
}

function isToday(){
	// 本日のページなら true そうでなければ false を返す
	var now = todayAndTime();
	var entryDate = pageDate(); // dom.js
	
	return (isSameDate(entryDate, now)) ? true : false;
}

function modeSelected(elm){
	// 日計表、月計表、予定表のポップアップメニューが選択された
	var value = elm.value;
	if (value == "月計表"){
		setMode(_isMonthly);
		getMonthlyList();
	} else if (value == "予定表"){
		setMode(_isPlan);
		showSelectedPage();
	} else { // 日計表
		setMode(_isDaily);
		showSelectedPage();
	}
    
    // 診療時間帯による表示エリアを隠す
    closeRegistWithDateTime();
}

function setControls(buff){
	// ヘッダー行のコントロール構成を設定
	var inOut = false;
    var showMultiDate = false;
	var menus = ["予定表","日計表"]; // 常に表示
	var items = buff.split(",");
    for (i in items){
		var label = items[i];
        
		if (label == "入院・外来表示") inOut = true;
		if (label == "他日も表示"){ // 月計表も表示されるようになる
			showMultiDate = true; // 年月日ポップアップが表示される
            setHasMonthlyMode(true); // 診療時間帯表示に反映
			menus.push("月計表"); // 月計表 が指定されている場合のみ
		}
		if (label == "患者受付"){
			makeRegistField(); // 受診者登録を生成
		}
		if (label == "日時指定受付") 
            setHasDatetimeButton(true);
		if (label == "予約ツール"){
			setHasPlanButton(true);
		}
		if (label == "今月の受診者リスト") setHasVisitorList(true);
		if (label == "合計を表示") setHasTotal(true);
		if (label == "平均値を表示") setHasAverage(true);
	}
	
	// 入院、外来のチェックボックスを生成
	if (inOut){
		var td = document.getElementById("inOutArea");
		td.innerHTML = "";
		var ip = newCHECKBOX(td, "outpatient", "外来", 1);
		ip.setAttribute("onclick", "showSelectedPage()");
		var ip = newCHECKBOX(td, "inpatient", "入院", 0);
		ip.setAttribute("onclick", "showSelectedPage()");
	}
    
	// 年月日を生成する makeDatePopupButtons() で polling がキックされるので
    // その前に日計表ポップアップメニューを生成し setMode() を実行しておく
	var td = document.getElementById("modePopupArea");
	td.innerHTML = "";
	var pu = makePopupMenu(td, "modePopup", menus, firstItem());
	pu.setAttribute("onchange", "modeSelected(this)");
    if (firstItem() == "日計表")
        setMode(_isDaily);
    else if (firstItem() == "月計表")
        setMode(_isMonthly);
    else
        setMode(_isPlan);
    
    // 年月日ポップアップを生成
	var td = document.getElementById("dateArea");
	td.innerHTML = "";
	if (showMultiDate){
		makeDatePopupButtons(td, "YYMMDD", todayAndTime()); // polling をキック
	} else {
		makeDateString(td);
        polling(); // makeDatePopupButtons() の代わりにここでキック
    }
    
	// 道具メニューのサブメニューを生成
	initSubMenu();
    addSubMenu("始業点検", "openingCheck()");
    addSubMenu("年齢計算", "openAge()");
	if (hasDatetimeButton()) addSubMenu("日時指定受付", "registWithDateTime()");
	if (hasPlanButton()) addSubMenu("予約ツール", "openBooking()");
    if (hasVisitorList()) addSubMenu("今月の受診者リスト", "showInsListPanel()");
    addSubMenu("電子カルテへメッセージ", "showMessageFromFRONT()");
    if (isSuperUser())
        addSubMenu("初期設定", "openPreference()");
}

function timeZoneSelected(elm){
    // 診療時間帯ポップアップが選択された
    var zone = elm.value;
	var mode = document.getElementById("modePopup").value;
    if (mode == "月計表"){
        setTimeStamp("");
        getMonthlyList();
    } else {
        if (zone == "全日")
            setTimeStamp("");
        
        // 過去の日付のものも表示できるようにする
        if (!isSameDate(today(), pageDate()))
            setTimeStamp("");
        
        getDailyList();
    }
}
function showTimeZonePop(zone){
    // 診療時間帯ポップアップメニューを生成
    // timeZone() = ["全日", "0900..1200", "1500..1700"];
    var zones = ["全日"];
    var items = zone.split(",");
    for (num in items) zones.push(items[num]);
    
	var td = document.getElementById("timeZonePopupArea");
	td.innerHTML = "";
    var pu = makePopupMenu(td, "timeZonePopup", zones, "全日");
	pu.setAttribute("onchange", "timeZoneSelected(this)");
}

function showDaily(date){
	// 月計表で選択された日の日計表を表示
	
	// 年月日ポップアップを選択された年月日で再設定
	var elm = document.getElementById("dateArea");
	makeDatePopupButtons(elm, "YYMMDD", date);
	
	setMode(_isDaily);
	showSelectedPage();
}

function showSelectedPage(){
	// 年月日ポップアップメニューで指定された日計表を開く：newDatePopUp() のレシーバ
	setWeek(pageDate()); // 指定された年月日の曜日を表示
	setTimeStamp("");
	polling();
}

function changeReservation(buttonElm, patientId, entryDate){
	// 予約時刻を受診時刻に変更
	var now = todayAndTime();

	if (isSameDate(entryDate, now)){
		if (confirm(entryDate + " で予約の方が"
					+ "\n実際にいま来院されました。"
					+ "\n受付時刻を現在のタイムスタンプに変更しますか？")){
			// patientId, entryDate のレコードの plan を空にし entryDate を now へ
			changePatient(patientId, entryDate, now);
		}
	} else {
		alert(entryDate + " は本日ではないので変更不可");
	}
}

function openInsViewer(pid, date){
    // InsViewer を開く
    var args = "patientId=" + pid + "&currentDate=" + date;
    window.open("../InsViewer?" + args, "_blank");
}

var _count;
var _insCount;
var _honin;
var _kazoku;
var _kokuho;
var _point;
var _ownFee;
var _mishuu;
var _newPatient;
function titleDescription(tbl){
	// 日計または月計ヘッダーを生成
	_count = 0;
	_insCount = 0; // 健保使用回数
	_honin = 0;
	_kazoku = 0;
	_kokuho = 0;
	_point = 0;
	_ownFee = 0;
	_mishuu = 0;
	_newPatient = 0;
	
	// daylyColumnConf() を元にヘッダー生成
	var tr = newTR(tbl, "title", "");
	if (mode() == _isDaily)
		array = daylyColumnConf();
	else if (mode() == _isMonthly)
		array = monthlyColumnConf();
	else
		array = planColumnConf();
    
    for (i in array){
		var col = array[i];

		if (col.id == "entry"){
			var td = newTD(tr, "", "");
			var a = newA(td, col.label, "#", "");
			a.setAttribute("onclick", "toggleSortOrder()");
		} else if (col.type == "numeric")
			var td = newTD(tr, "title_num", col.label);
		else if (col.type == "center")
			var td = newTD(tr, "title_center", col.label);
		else
			var td = newTD(tr, "", col.label);
        
        td.style.paddingLeft = "5px";
	}
    td.style.paddingRight = "5px";
	return tr;
}	
function recordDescription(tbl, rec, row){
	// 日計レコードを生成
	var honin = honin(rec);
	var kazoku = kazoku(rec);
	var kokuho = kokuho(rec);
	var point = point(rec);
	var reserved = isReserved(rec);
	var ownFee = (rec.ownFee) ? rec.ownFee : 0;
	var mishuu = (rec.mishuu) ? rec.mishuu : 0;
	var receive = (rec.receive) ? rec.receive : 0;
	var newPatient = isNewPatient(rec);
	//	alert(encodeObject(rec)); //##
	_count += 1;
	_honin += honin * 1;
	_kazoku += kazoku * 1;
	_kokuho += kokuho * 1;
	_point += point * 1;
	_ownFee += ownFee * 1;
	_mishuu += mishuu * 1;
	_newPatient += newPatient;
	if (point > 0) _insCount++; // 健保を使用した回数
	var total = honin * 1 + kazoku * 1 + kokuho * 1 + ownFee * 1 - mishuu*1;
	
	// daylyColumnConf() を元にレコード生成
	var tr = (isInPatient(rec))
		? newTR(tbl, "inRecord", "") : newTR(tbl, "record", "");
	
	if (mode() == _isDaily)
		var array = daylyColumnConf();
	else if (mode() == _isPlan)
		var array = planColumnConf();
	
    for (i in array){
		var col = array[i];
		var td = newTD(tr, col.type, "");
        td.style.paddingLeft = "5px";
		var val = valueWithId(col);
		
		if (isInPatient(rec)){
			// 入院の場合は背景色を青緑色に設定
			tr.style.backgroundColor = "#6fc";
        } else if (reserved){
			tr.style.backgroundColor = "#fee";
		} else { // １行おきに背景色を変える
			var bgcolor = (Math.floor(row / 2) == (row / 2)) ? "#fff" : "#bff";
			tr.style.backgroundColor = bgcolor;
		}

		//alert("entryDate("+rec.entryDate+")"); //##
		
		// アクションを設定
		if (isSame(col.id, "reserved")){
			if (reserved){
				var bt = newBUTTON(td, "", "予約");
				var pid = rec.patientId;
                var date = rec.entryDate;
                var action = "changeReservation(this,'"+pid+"','"+date+ "')";
				bt.setAttribute("onclick", action);
			} else {
				var tx = newTEXT(td, "");
			}
		} else if (isSame(col.id, "message")){
            var bt = newBUTTON(td, "", "伝達");
            var msg = "--- " + rec.patientId + " " + rec.kanjiName + "さん ---";
            var action = "showMessageFromFRONT('" + msg + "')";
            bt.setAttribute("onclick", action);
		} else if (isSame(col.id, "viewer")){
            var bt = newBUTTON(td, "", "閲覧");
            var st = rec.patientId + "','" + rec.entryDate;
            bt.setAttribute("onclick", "openViewer('" + st + "')");
		} else if (isSame(col.id, "edit")){
			td.style.textAlign = "center";
			var action = "openPatientEditor('" + rec.dateAndId + "')";
			var bt = newBUTTON(td, "", "修正");
			bt.setAttribute("onclick", action);
		} else if (isSame(col.id, "bill")){
			td.style.textAlign = "center";
			var bt = newBUTTON(td, "", "会計");
			var action = "openBill('" + rec.dateAndId + "')";
			bt.setAttribute("onclick", action);
		} else if (isSame(col.id, "patientId")){
			var tx = newTEXT(td, val);
			td.setAttribute("onclick", action);
		} else if (isSame(col.id, "anotherId")){
			var tx = newTEXT(td, val);
		} else if (isSame(col.id, "name")){
			var plan = trim(rec.plan);
			if (plan.length){
				// 実施計画がある場合のみマウスに反応して編集パネルを開ける
				setMouseOverColor(td, bgcolor);
				var action = "openPlanEditor('" + rec.dateAndId + "')";
				td.setAttribute("onclick", action);
			}
			var tx = newTEXT(td, val);
        } else if (isSame(col.id, "plan")){
            // '//' から後を表示
            var ary = val.split('//');
            var tx = newTEXT(td, ary[0]); 
		} else if (isSame(col.id, "point")){
			var tx = newTEXT(td, point);
		} else if (isSame(col.id, "image")){ // 保険証画像
            var sp = newSPAN(td, "/insurance");
            setScanDateWith(sp, rec.scanDateTime);
            var action = "openInsViewer('"+rec.patientId+"','"+rec.entryDate+"')";
            sp.setAttribute("onclick", action);
		} else
			var tx = newTEXT(td, val);
        
        if (i == 0) td.style.paddingLeft = "5px";
	}
	
    function daysBetween(datetime1, datetime2){
        // datetime1, datetime2 間の日数を返す
        // 両日の０時０分０秒同士で計算するので、多少誤差が出る可能性あり
        var date1 = datetime1.substr(0, 10) + " 00:00:00";
        var date2 = datetime2.substr(0, 10) + " 00:00:00";
        var seconds = secondsBetween(date1, date2);
        return seconds / (60 * 60 * 24);
    }
	
    function setScanDateWith(elm, filename){
        // filename から 日付を抽出して返す
        // filename = "03234202_20120113165123.JPG" 形式
        elm.innerHTML = "画像はありません";
        elm.setAttribute("class", "noInsurance");
        if (filename){
            var array = filename.split("_");
            if (array.length == 2){
                var st = array[1];
                var yyyy = st.substr(0, 4);
                var mm = st.substr(4, 2);
                var dd = st.substr(6, 2);
                var hour = st.substr(8, 2);
                var min = st.substr(10, 2);
                var sec = st.substr(12, 2);
                var dateTime = yyyy+"-"+mm+"-"+dd+" "+hour+":"+min;
                elm.innerHTML = dateTime;
                elm.setAttribute("class", "insurance");
                
                var pastDays = daysBetween(dateTime, pageDate());
                if (pastDays > 30){
                    // 一定日数を越えたものは「経過日数」表示
                    elm.innerHTML += " ( " + pastDays + " 日経過)";
                    //elm.style.color = "#f00";
                }
            }
        }
    }
	
	function setMouseOverColor(elm, bgcolor){
		// マウスが載ると色が変わる
		elm.setAttribute("onmouseover", "setColor(this, '#ff0', '#00f')");
		var action = "setColor(this,'black','" + bgcolor + "')"
		elm.setAttribute("onmouseout", action);
	}
	
	function valueWithId(col){
		if (isSame(col.id, "entry"))
			return timeOf(rec);
		else if (isSame(col.id, "patientId"))
			return rec.patientId;
		else if (isSame(col.id, "anotherId"))
			return rec.anotherId;
		else if (isSame(col.id, "name"))
			return rec.kanjiName;
		else if (isSame(col.id, "newPatient"))
			return (newPatient > 0) ? "*" : "";
		else if (isSame(col.id, "honin"))
			return honin.toString();
		else if (isSame(col.id, "kazoku"))
			return kazoku.toString();
		else if (isSame(col.id, "kokuho"))
			return kokuho.toString();
		else if (isSame(col.id, "ownFee"))
			return ownFee.toString();
		else if (isSame(col.id, "honin"))
			return honin.toString();
		else if (isSame(col.id, "total"))
			return total.toString();
		else if (isSame(col.id, "wait"))
			return waitingMinutes(rec);
		else if (isSame(col.id, "allWait"))
			return allWaitingMinutes(rec);
		else if (isSame(col.id, "finish"))
			return endTime(rec).toString();
		//else if (isSame(col.id, "user"))
		//	return rec.owner;
		else if (isSame(col.id, "mishuu"))
			return rec.mishuu;
		else if (isSame(col.id, "receive"))
			return rec.receive;
		else if (isSame(col.id, "change"))
			return rec.receive - total;
		else if (isSame(col.id, "plan"))
			return rec.plan;
		else if (isSame(col.id, "image"))
			return rec.scanDateTime;
		else
			return ".";
	}
	
	function isReserved(rec){
		// 登録年月日より以前に更新されていれば予約と判断
		if (rec.entryDate > rec.updateTime)
			return true;
		else
			return false;
	}
	
	function reservationOf(rec){
		// 予約行なら「予約」ボタンを返す
		return (reserved) ? "RSV" : "";
	}
	
	function timeOf(rec){
		// "2007-08-29 12:05:00" 形式を "12:05:00" 形式にして返す
		// "00:00:00" の場合は "" を返す
		var time = rec.entryDate.substr(11, 5);
		return (isSame(time, "00:00:00") > 0) ? "" : time;
	}
	
	function isNewPatient(rec){
		if (rec.newPatient * 1 > 0)
			return 1;
		else 
			return 0;
	}
	
	function point(rec){
		return (rec.point) ? rec.point : 0;
	}
	
	function isInPatient(rec){
		return (rec.inOut * 1 > 0) ? true : false;
	}
	
	function honin(rec){
		return (rec.groupCode == 0) ? rec.insFee : 0;
	}
	
	function kazoku(rec){
		return (rec.groupCode == 1) ? rec.insFee : 0;
	}
	
	function kokuho(rec){
		return (rec.groupCode == 2) ? rec.insFee : 0;
	}
	
	function waitingMinutes(rec){
		// 受付時刻から診療終了までの経過時間を分で返す
        // endTIme: 診療終了時刻をあらわす
		var entry = rec.entryDate;
		if (!entry ) return "";
		
		var now = (rec.endTime) ? rec.endTime : todayAndTime();
		var min = Math.floor(secondsBetween(entry, now) / 60);
		
		// 一日以上経過している場合は "..." で表す
		return (min < 60 * 24) ? min + " 分" : "...";
	}
	
	function allWaitingMinutes(rec){
		// 受付時刻から会計終了までの経過時間を分で返す
		var entry = rec.entryDate;
		if (!entry ) return "";
		
		var now = (rec.checkOutTime) ? rec.checkOutTime : todayAndTime();
		var min = Math.floor(secondsBetween(entry, now) / 60);
		
		// 一日以上経過している場合は "..." で表す
		return (min < 60 * 24) ? min + " 分" : "...";
	}
	
	function endTime(rec){
        // endTIme: 診療終了時刻をあらわす
		// endTime は "2008-05-04 15:34:34" のような形式なので時刻のみ返す
		var st = rec.endTime;
		if (!st ) return "";
		
		var array = st.split(" ");
		return array[1].substr(0, 5);
	}
}
function dailyTotalDescription(tbl){
	// 日計合計行を生成
	var total = _honin + _kazoku + _kokuho + _ownFee - _mishuu;
    var confs = (mode() == _isPlan) ? planColumnConf() : daylyColumnConf();
    
	if (hasTotal()){
        var tr = newTR(tbl, "", "");
        for (i in confs){
            var col = confs[i];
            var val = valueWithId(col).toString();
            var td = newTD(tr, col.type, val);
            
            if (i == 0) td.style.paddingLeft = "5px";
        }
    }
	
	if (hasAverage() && (mode() != _isPlan)){
		var tr = newTR(tbl, "average", "");
        for (i in confs){
			var col = confs[i];
			var val = averageWithId(col).toString();
			var td = newTD(tr, col.type, val);
            
            if (i == 0) td.style.paddingLeft = "5px";
		}
	}
	
	function valueWithId(col){
		if (isSame(col.id, "entry"))
			return "合計";
		else if (isSame(col.id, "patientId"))
			return _count+" 名";
		else if (isSame(col.id, "newPatient"))
			return _newPatient;
		else if (isSame(col.id, "honin"))
			return _honin;
		else if (isSame(col.id, "kazoku"))
			return _kazoku;
		else if (isSame(col.id, "kokuho"))
			return _kokuho;
		else if (isSame(col.id, "point"))
			return _point;
		else if (isSame(col.id, "ownFee"))
			return _ownFee;
		else if (isSame(col.id, "total"))
			return total;
		else if (isSame(col.id, "mishuu"))
			return _mishuu;
		else
			return "";
	}
	
	function averageWithId(col){
		if (isSame(col.id, "entry"))
			return "平均";
		else if (isSame(col.id, "honin"))
			return average(_honin, _count);
		else if (isSame(col.id, "kazoku"))
			return average(_kazoku, _count);
		else if (isSame(col.id, "kokuho"))
			return average(_kokuho, _count);
		else if (isSame(col.id, "point"))
			return average(_point, _insCount);
		else if (isSame(col.id, "ownFee"))
			return average(_ownFee, _count);
		else if (isSame(col.id, "total"))
			return average(total, _count);
		else
			return "";

		function average(val, count){
			return (count == 0) ? 0 : Math.round(val / count);
		}
	}
}	

function monthlyDescription(tbl, ln){
	var ary = decodeArgs(ln);
	// ary[] 内容は frontServer の calcSum() で定義
	var count = ary[0] * 1;
	var date = ary[1];
	var honin = ary[2] * 1;
	var kazoku = ary[3] * 1;
	var kokuho = ary[4] * 1;
	var ownFee = ary[5] * 1;
	var mishuu = ary[6] * 1;
	var inOut = ary[8] * 1;
	var newPatient = ary[9] * 1;
	var point = ary[10] * 1;
	_count += count;
	if (point > 0) _insCount++;
	_honin += honin;
	_kazoku += kazoku;
	_kokuho += kokuho;
	_ownFee += ownFee;
	_mishuu += mishuu;
	_newPatient += newPatient;
	_point += point;
	var tr = newTR(tbl, "record", "");
	
	var array = monthlyColumnConf();
    for (i in array){
		var col = array[i];
		var val = valueWithId(col, ary);
		var td = newTD(tr, col.type, val);
        td.style.paddingLeft = "5px";
		
		// アクションを設定
		if (isSame(col.id, "entry")){
			var a = newA(td, date, "#", "");
			var action = "showDaily('"+date+"')";
			a.setAttribute("onclick", action);
			a.setAttribute("onmouseover", "setColor(this, '#ff0', '#00f')");
			a.setAttribute("onmouseout", "setColor(this, '#000', '#fff')");
			
			// week
			var week = " " + weekOfDate(date);
			var tx = newTEXT(td, week);
		}
	}
    td.style.paddingRight = "5px"; // 最後の TD のみに設定
	return tr;
	
	function valueWithId(col, ary){
		var count = ary[0] * 1;
		var date = ary[1];
		var honin = ary[2] * 1;
		var kazoku = ary[3] * 1;
		var kokuho = ary[4] * 1;
		var ownFee = ary[5] * 1;
		var mishuu = ary[6] * 1;
		var inOut = ary[8] * 1;
		var newPatient = ary[9] * 1;
		var point = ary[10] * 1;
		var total = honin + kazoku + kokuho + ownFee - mishuu;
		
		if (isSame(col.id, "count"))
			return count.toString();
		else if (isSame(col.id, "newPatient"))
			return newPatient.toString();
		else if (isSame(col.id, "honin"))
			return honin.toString();
		else if (isSame(col.id, "kazoku"))
			return kazoku.toString();
		else if (isSame(col.id, "kokuho"))
			return kokuho.toString();
		else if (isSame(col.id, "ownFee"))
			return ownFee.toString();
		else if (isSame(col.id, "total"))
			return total.toString();
		else if (isSame(col.id, "mishuu"))
			return mishuu.toString();
		else if (isSame(col.id, "point"))
			return point.toString();
		else
			return "";
	}
}
function monthlyTotalDescription(tbl, dayCount){
	// 日計合計行を生成
	var total = _honin + _kazoku + _kokuho + _ownFee - _mishuu;
	var tr = newTR(tbl, "", "");
	var array = monthlyColumnConf();
    for (i in array){
		var col = array[i];
		var val = valueWithId(col, dayCount);
		var td = newTD(tr, col.type, val);
        td.style.paddingLeft = "5px"; 
	}
    td.style.paddingRight = "5px"; // 最後の TD のみに設定
	
	if (hasAverage()){
		var tr = newTR(tbl, "average", "");
        for (i in array){
			var col = array[i];
			var val = averageWithId(col, dayCount).toString();
			var td = newTD(tr, col.type, val);
            td.style.paddingLeft = "5px"; 
        }
        td.style.paddingRight = "5px"; // 最後の TD のみに設定
	}
	
	function valueWithId(col, dayCount){
		if (isSame(col.id, "entry"))
			return "合計 " + dayCount +" 日";
		else if (isSame(col.id, "count"))
			return _count+" 名";
		else if (isSame(col.id, "newPatient"))
			return _newPatient.toString();
		else if (isSame(col.id, "honin"))
			return _honin.toString();
		else if (isSame(col.id, "kazoku"))
			return _kazoku.toString();
		else if (isSame(col.id, "kokuho"))
			return _kokuho.toString();
		else if (isSame(col.id, "ownFee"))
			return _ownFee.toString();
		else if (isSame(col.id, "honin"))
			return honin.toString();
		else if (isSame(col.id, "total"))
			return total.toString();
		else if (isSame(col.id, "mishuu"))
			return _mishuu.toString();
		else if (isSame(col.id, "point"))
			return _point.toString();
		else
			return "";
	}
	
	function averageWithId(col, dayCount){
		if (isSame(col.id, "entry"))
			return "平均";
		else if (isSame(col.id, "count"))
			return Math.round(_count / dayCount) + "名";
		else if (isSame(col.id, "newPatient"))
			return Math.round(_newPatient / dayCount);
		else if (isSame(col.id, "honin"))
			return Math.round(_honin / dayCount);
		else if (isSame(col.id, "kazoku"))
			return Math.round(_kazoku / dayCount);
		else if (isSame(col.id, "kokuho"))
			return Math.round(_kokuho / dayCount);
		else if (isSame(col.id, "ownFee"))
			return Math.round(_ownFee / dayCount);
		else if (isSame(col.id, "total"))
			return Math.round(total / dayCount);
		else if (isSame(col.id, "point"))
			return Math.round(_point / _insCount);
		else
			return "";
	}
}	

function registOldTimePatient(){
	// 指定した日時の受診者を日計表に登録
	var id = "_YYMMDD";
	var patientId = document.getElementById(id+".patientId").value;
    var entryDate = document.getElementById("datePop").value;
	var hour = document.getElementById(id+".hour").value;
	var min = document.getElementById(id+".minute").value;
	var sec = document.getElementById(id+".second").value;
	if (hour < 10) { hour = "0" + hour; }
	if (min < 10) { min = "0" + min; }
	if (sec < 10) { sec = "0" + sec; }
	var dateTime = entryDate + " " + hour + ":" + min + ":" + sec;
    
	registPatient(patientId, dateTime, false);
}

function openPatientEditor(dateAndId){
	// 患者会計レコードの編集パネルを開く
	var url = "./patientEditor.php?dateAndId=" + dateAndId
	+ "&owner=" + owner()
	+ "&isSuperUser=" + isSuperUser();
	//alert(url); //##
	var w = window.open(encodeURI(url),
						"patientEditor",
						"width=250,height=600,resizable=yes");
}

function openPlanEditor(dataAndId){
	// plan 編集パネルを開く
	var rec = recordForEntryDate(dataAndId);
	if (newPlan = prompt("実施計画 編集パネル", rec.plan)){
		savePlan(rec.patientId, rec.entryDate, newPlan);
	}
}

function openBill(dateAndId){
	// 会計パネルを開く
	var url = "./billEditor.php?dateAndId=" + dateAndId
	+ "&owner=" + owner()
	+ "&isSuperUser=" + isSuperUser();
	//alert("openBill ---\n"+url); //##
	var w = window.open(encodeURI(url),
		"会計パネル",
		"width=350,height=320,resizable=yes");
}

function openViewer(patientId, currentDate){
    // カルテの簡易閲覧パネルを開く
    var url = "viewer.php?hospitalId=" + hospitalId()
    + "&owner=" + owner()
    + "&patientId=" + patientId
    + "&currentDate=" + currentDate;
	window.open(url,"viewr","width=600,height=1000,scrollbars=yes,resizable=yes");
}

function openPatientRegister(){
	// 新患登録パネルを開く
	// ## patientRegister からの受け口として receiver を用意しておくこと
	// ## receiver に添えるパラメータは patientRegister との間で暗黙の了解
	var obj = new Array();
	obj["owner"] = owner();
	obj["hospitalId"] = hospitalId()
	obj["receiver"] = "registedNewPatient";
	obj["frontmode"] = "yes";
	var url = "/XNOA/patientRegister.php?value=" + encodeObject(obj);
	//alert(url); //##
    
	var w = window.open(encodeURI(url),
						"patientRegister",
						"width=500,height=350,resizable=yes");
}

function makeDatePopupButtons(elm, id, date){
	// idで指定されたエレメント上に年月日のポップアップメニューを生成し elm へ追加
	var yy = date.substr(0, 4) * 1;
	var mm = date.substr(5, 2) * 1;
	var dd = date.substr(8, 2) * 1;
    
	var sp = document.getElementById(id);
    if (sp) 
        sp.innerHTML = "";
    else
        sp = newSPAN(elm, id);

    // 戻り値 showSelectedPage で polling がキックされる
    newDatePopUp(sp, "datePop", "平成", yy, mm, dd, false, showSelectedPage);
	
	// 指定された年月日の曜日を埋め込む
	setWeek(date);
}

function closeRegistWithDateTime(){
	var elm = document.getElementById("maintenanceArea");
	elm.innerHTML = "";
}
function registWithDateTime(){
	// 日時指定受付を開く
	var elm = document.getElementById("maintenanceArea");
	if (elm.innerHTML.length == 0){
		elm.innerHTML = "";
        elm.style.fontSize = "11px";
        elm.style.textAlign = "left";
        elm.style.backgroundColor = "#ffa";
		
		// メンテ作業の種別を選択するポップアップメニューを生成
		var im = newIMAGE(elm, "", "./close.png", "?");
		im.setAttribute("onclick", "closeRegistWithDateTime()");
		im.style.height = "12px";
		im.style.verticalAlign = "middle";
		var tx = newTEXT(elm, "　日時指定で受付 ");
		var id = "_YYMMDD";
		var pu = makeDatePopupButtons(elm, id, todayAndTime());
		
		var tx = newTEXT(elm, "　");
		var hours = makeArray(0, 24);
		var sl = makePopupMenu(elm, id+".hour", hours, 10);
		var tx = newTEXT(elm, ":");
		var minutes = makeArray(0, 60);
		var sl = makePopupMenu(elm, id+".minute", minutes, 30);
		var tx = newTEXT(elm, ":");
		var sec = makeArray(0, 60);
		var sl = makePopupMenu(elm, id+".second", sec, 0);
		var tx = newTEXT(elm, " ");
		
		var ip = newFIELD(elm, id+".patientId", "　カルテID ", 9, "");
		var bt = newBUTTON(elm, "", "再来登録");
		bt.setAttribute("onclick", "registOldTimePatient()");
	} else
		elm.innerHTML = "";
}

function changePasswd(){
	// パスワードを変更
	setPasswd(owner());
}

function makeRegistField(){
	// カルテID、再来受付、新患登録などのボタンを生成
	var elm = document.getElementById("registArea");
	elm.innerHTML = "";
	
	if (! isToday()){
		var tx = newTEXT(elm, "患者登録は本日のページで");
		elm.style.color = "#888";
		return;
	} else
		elm.style.color = "#000";
	
	var ip = newFIELD(elm, "patientId", "　カルテID", 9, "");
	ip.setAttribute("onchange", "registOldPatient()");
	var bt = newBUTTON(elm, "", "患者受付");
	bt.setAttribute("onclick", "registOldPatient()");
}

function hideSubmenu(){
	// サブ・メニューを閉じる
	var elm = document.getElementById("_submenu");
	elm.style.visibility = "hidden";
}
function closeSubMenu(){
	// どういう訳か hideSubmenu() を直接読むとうまく動作しない
	hideSubmenu();
}
function showSubMenu(elm){
	// メイン・メニューにマウスがのった時、サブ・メニューを生成表示
	// メニュー CELL の位置やサイズを検出
	var x = elm.offsetLeft + elm.offsetParent.offsetLeft + elm.offsetParent.offsetParent.offsetLeft;
	var y = elm.offsetTop + elm.offsetParent.offsetTop + elm.offsetParent.offsetParent.offsetTop;
	var h = elm.offsetHeight;
	var w = elm.offsetWidth;
	
	// サブ・メニューを生成
	var elm = document.getElementById("_submenu"); // noa.php
	elm.innerHTML = "";
	elm.style.left = x; // 表示するx座標
	elm.style.top = y + h; // 表示するy座標
	elm.style.visibility = "visible";
	
	// tbl にサブメニューを表示
	var tbl = newTABLE(elm, "");
	tbl.style.fontSize = "10pt";
	tbl.style.border = "thin solid #aaa";
	tbl.style.backgroundColor = "#fff";
	tbl.style.fontFamily = "arial, Helvetica";
	
	// サブメニューの各項目設定
	var array = subMenus();
    for (i in array){
		var obj = array[i];
		var tr = newTR(tbl, "", "");
		var td = newTD(tr, "", obj.item);
		td.style.padding = "2px 5px";
        setChangeColor(td, '#000','#fff');
		td.setAttribute("onclick", "doAction('" + obj.action +"')");
	}

	// サブメニュー消去用
	var elm = document.getElementById("resultsArea");
	elm.setAttribute("onmouseover","closeSubMenu()");
}
function doAction(action){
	// サブメニューを消し action を実行
	closeSubMenu();
	eval(action);
}

function helpTimeZone(){
    // 診療時間帯指定のヘルプを開く
	window.open("./timeZoneHelp.html","Help"
				,"width=450,height=700,scrollbars=yes,resizable=yes");
}

function openBooking(){
	// 予約ツールを開く
	window.open("../Booking","Booking"
				,"width=900,height=700,scrollbars=yes,resizable=yes");
}

function frontHelp(){
	window.open("./frontHelp.html","Help"
				,"width=450,height=700,scrollbars=yes,resizable=yes");
}

function showFront(){
	// テンプレートで FRONT のヘッダー部分を生成
	var elm = document.getElementById("base");
	elm.innerHTML = "";

    // ===== HEADER ===================
    var div = newDIV(elm, "");
    div.style.border = "thin solid #aaa";
    div.style.backgroundColor = "#aec";
	var tbl = newTABLE(div, "frontTable");
	tbl.style.fontSize = "10pt";
	var tr = newTR(tbl, "", "");
    // === LEFT SIDE ===
    var td = newTD(tr, "", "");
	// 入院、外来のチェックボックスを生成
    var sp = newSPAN(td, "inOutArea");
    sp.style.paddingLeft = "5px";
	// 年月日ポップアップメニューを生成
    var sp = newSPAN(td, "dateArea");
    sp.style.paddingLeft = "5px";
    var sp = newSPAN(td, "weekArea");
	// 日計・月計表ポップアップメニューのエリア
    var sp = newSPAN(td, "modePopupArea");
	// 診療時間帯ポップアップメニューのエリア
    var sp = newSPAN(td, "timeZonePopupArea");
	// 患者登録欄エリア
    var sp = newSPAN(td, "registArea");
	// オプション・ボタンは getDailyList() で生成
    var sp = newSPAN(td, "toolButton");
    sp.innerHTML = "道具";
	sp.setAttribute("onmouseover","showSubMenu(this)");
    
    // === RIGHT SIDE ===
	var td = newTD(tr, "", "");
    td.style.textAlign = "right";
    td.style.paddingRight = "5px";
    td.style.width = "20px";
	// ヘルプ・ボタン
	var im = newIMAGE(td, "", "./Help.png", "?");
	im.setAttribute("onclick", "frontHelp()");
	im.style.height = "18px";
	im.style.verticalAlign = "middle";
    
    // ===== MESSAGE SHELTER ===================
    var div = newDIV(elm, "messageShelterArea");
    div.style.paddingLeft = "10px";
    div.style.textAlign = "left";
    div.style.fontSize = "11pt";
	// 検索結果表示エリア
    var div = newDIV(elm, "paientListArea");
	// 管理ペーン
    var div = newDIV(elm, "maintenanceArea");
    div.style.paddingLeft = "10px";

    // ===== CONTENTS ===================
    var div = newDIV(elm, "");
	var tbl = newTABLE(div, "frontTable");
	tbl.style.fontSize = "10pt";
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "resultsArea", "");
    td.setAttribute("colspan", "2");
    
    // ===== FOOTER ===================
    var div = newDIV(elm, "");
    div.style.border = "thin solid #aaa";
    div.style.backgroundColor = "#aec";
    div.style.height = "25px";
	var tbl = newTABLE(div, "frontTable");
	tbl.style.fontSize = "10pt";
	var tr = newTR(tbl, "", "");
    // === LEFT SIDE ===
	var td = newTD(tr, "kanjiNameArea", "");
    // === RIGHT SIDE ===
	var td = newTD(tr, "", "");
	td.style.textAlign = "right";
	td.style.paddingRight = "10px";
    var sp = newSPAN(td, "");
    sp.style.paddingRight = "10px";
    sp.innerHTML = version();
    
	// メッセージエリア
	var dv = newDIV(base, "message");
    
	// サーバへユーザ・リストをリクエスト
	// その返事を待って年月日ポップアップメニューで指定されたページを開く
    getUserTable();
}

function initFront(){
	// ユーザを認証
    // Booking など周辺ツールから参照されるための名称をつける
    window.name = "FRONT"; // ### Booking が親を識別するため必要
    
	if (setArguments()){ // URI に owner,hospitalId が添付されてきた
		showFront();
	} else {			// owner,hospitalId が添付されていない
		initLogin(); // login パネルを生成
	}
}

function version(){
	return "FRONT Ver.121115";
}

