
var _records;
function setGroupRecords(objct){
    // レコード数が１００を超えるほどになると処理がコケるので
    // なるべく軽くするためオブジェクト形式を配列形式に変換
    _records = objct;
}
function groupRecords(){
	return _records;
}

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

function gotTable(){
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//if (debugMode()) alert(value); //##
		var array = value.split("<SEPARATOR>");
		if (array.length > 1){
			var obj = JSON.parse(array[1]);
//			var obj = eval('(' + array[1] + ')');
			obj = pureRecords(obj); // $row の数値添字を取り除く
			//if (debugMode()) alert("gotTable:"+encodeObject(obj)); //##
            setGroupRecords(obj);
			showRecords();
			showMessageBar("");
		} else
			showMessageBar(value);
	} else 
		showMessageBar("Loading GroupTable ...");
	
	function pureRecords(objects){
		// $row の数値添字を取り除く
		var recs = new Array();
		for (var i=0,ct=objects.length; i < ct; i++){
			var obj = objects[i];
			var array = new Array();
			for (key in obj){
				if (! isDigit(key)) array[key] = obj[key];
			}
			recs.push(array);
		}
		return recs;
	}
}
function getTable(owner, table, order){
	// table の内容をサーバへリクエスト
	xmlHttpObject = createXMLHttpRequest(gotTable);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		var array = new Array();
		array['owner'] = owner;
		array['table'] = table;
		array['order'] = order;
		var val = encodeObject(array);
		
		var st = "sysServer.php?command=GET_TABLE_SOURCE"
		+ "&value=" + encodeSTRING(val);
        
        document.getElementById("message").innerHTML = st;
        //alert("getTable->"+st); //##
        
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function gotArchive(){
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		_debug("gotArchive->"+value); //##
        
		var array = value.split("<SEPARATOR>");
		if (array.length > 1){
			// ### JSON に含まれる改行を encode してから eval する
			var val = transferCR(array[1]);
            _debug(val); //##
            
			var obj = JSON.parse(val);
            _debug("<p>obj->"+encodeObject(obj)+"</p>"); //##
            
			// ### object 中の encode された改行を decode する
			obj = decodeEncodedCR(obj);
            _debug("<p>obj->"+encodeObject(obj)+"</p>"); //##
			
            setGroupRecords(obj);
            showRecords();
		} 
	} 
	
	function decodeEncodedCR(array){
		// obj 中の encode された改行を decode する
		for (var i=0,ct=array.length; i < ct; i++){
			var newObj = new Object();
			var obj = array[i];
			for (key in obj){
				var val = obj[key];
				newObj[key] = transferToCR(val);
			}
			array[i] = newObj;
		}
		return array;
	}
}
function getArchive(path){
	// 選択されたユーザのバックアップ・データをサーバへリクエスト
	xmlHttpObject = createXMLHttpRequest(gotArchive);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		var array = new Array();
		array['owner'] = document.getElementById("userPopup").value;
		array['tableType'] = "GROUP";
		array['filename'] = path;
		var val = encodeObject(array);
		
		var st = "sysServer.php?command=GET_ARCHICE"
		+ "&value=" + encodeSTRING(val);
		//alert(st); //##
        
        _initDebug(false); //##
        _debug("<p>getArchive-> "+st+"</p>"); //##
        
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function loadedBackupedArchive(){
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//alert("loadedBackupedArchive ===\n"+value);//##
		var array = value.split("<SEPARATOR>");
		if (array.length > 1){
            var obj = JSON.parse(array[1]);
            
            // バックアップファイルのポップアップを表示
            showBackupSelector(obj);
		}
	} 
}
function loadBackupedArchive(){
    // バックアップ・ファイル名リストをリクエスト
    //alert("loadBackupedArchive:"+owner); //##
	xmlHttpObject = createXMLHttpRequest(loadedBackupedArchive);
	if (xmlHttpObject){
		var array = new Array();
		array['owner'] = document.getElementById("userPopup").value;
		array['folder'] = "GROUP";
		var args = encodeObject(array);
		
		var st = "./sysServer.php?command=GET_ARCHIVED_LIST"
		+ "&value=" + encodeSTRING(args);
		//alert(st); //return; //##
        
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function removedGroupTable(){
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//if (debugMode()) _debug("<p>"+value+"</p>");//##
        
		var array = value.split("<SEPARATOR>");
		if (array.length > 1){
			showRecords();
		} 
	} 
}
function removeGroupTable(obj){
	// obj を PriceList から削除
	xmlHttpObject = createXMLHttpRequest(removedGroupTable);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		var rec = new Object();
		rec['owner'] = obj.owner;
		rec['subject'] = obj.subject;
		
		var st = "./sysServer.php?command=REMOVE_GROUP_MENU"
		+ "&value=" + encodeSTRING(encodeObject(rec));
        
		//if (debugMode()) _debug(st); //return; //##
        
		xmlHttpObject.open("GET", encodeURI(st), false);
		xmlHttpObject.send(null);
	}
}

function replacedGroupTable(){
	// DB の FieldTable が空になった
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		//if (debugMode()) _debug("<p>"+value+"</p>"); //##
        
		var array = value.split("<SEPARATOR>");
		if (array.length > 1){
			mergeCycle();
		} 
	} 
}
function replaceGroupTable(){
	// DB の FieldTable を空にしてからデータソースを書込む
	xmlHttpObject = createXMLHttpRequest(replacedGroupTable);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		var array = new Array();
		array['owner'] = document.getElementById("userPopup2").value;
		array['table'] = "ProgressSection";
		array['patientId'] = "GroupMenu";
		var val = encodeObject(array);
		
		var st = "./sysServer.php?command=CLEAR_TABLE"
		+ "&value=" + encodeSTRING(val);
		//if (debugMode()) _debug("<p>== replaceGroupTable ==<br>"+st+"</p>"); //##
        
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function mergedWithGroup(){
	// 各テーブルの存在がチェックされた
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
        _debug("<p>== mergedWithGroup ==<br>"+value+"<br>====</p>"); //##
        
		var array = value.split("<SEPARATOR>");
		if ((array.length > 1) && (array[1].length)){
			showMessage("_message", value);
            _debug("<p>"+value+"</p>"); //##
		} 
		mergeCycle();
	} 
}
function mergeWithGroup(obj){
	// データ・ソースを DB とマージ
	xmlHttpObject = createXMLHttpRequest(mergedWithGroup);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		// ## obj に含まれた owner は操作者のものなので userPopup2 の値を指定する
        var owner = document.getElementById("userPopup2").value;
        obj.owner = owner;
        
		var st = "./sysServer.php?command=MERGE_GROUP"
		+ "&owner=" + document.getElementById("userPopup2").value
		+ "&value=" + encodeSTRING(encodeObject(obj));
        
		_debug("<p>"+st+"</p>"); //return;//## かなり頻繁
        
		xmlHttpObject.open("GET", encodeURI(st), true);
		xmlHttpObject.send(null);
	}
}

function puttedGroupTable(obj){
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
		_debug("<p>"+value+"</p>"); //##
        
		var array = value.split("<SEPARATOR>");
		if (array.length > 1){
            // DB 内容を再表示
            var logname = document.getElementById("userPopup").value;
            var tableName = "ProgressSection";
            var order = "`subject`";
            getTable(logname, tableName, order);
		} 
	} 
}
function putGroupTable(obj){
	// obj を FieldTable に追加
	// FieldTable に同じ tag, id があれば上書き
	xmlHttpObject = createXMLHttpRequest(puttedGroupTable);
	if (xmlHttpObject){ // GETパラメータ付きでリクエスト送信
		// ## obj に含まれた owner は操作者のものなので ポップアップのユーザ名 を指定する
        // ## このエディターから保存の場合は userPopup
        var owner = document.getElementById("userPopup").value;
        obj.owner = owner;
        
		var st = "./sysServer.php?command=PUT_GROUP"
		+ "&value=" + encodeSTRING(encodeObject(obj));

        _debug("<p>"+st+"</p>"); //return;//## かなり頻繁

		xmlHttpObject.open("GET", encodeURI(st), false);
		xmlHttpObject.send(null);
	}
}

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



function showBackupSelector(filenames){
    // バックアップ・ファイルのリストを選択してファイルをロード
    var items = new Array();
    for (num in filenames){
        var name = filenames[num];
        if (name.charAt(0) == '.') continue;
        items.push(name);
    }
    var elm = document.getElementById("fileNamesArea");
    elm.innerHTML = "";
    var pu = makePopupMenu(elm, "filePop", items, "");
    
    // removeButtonArea の操作：バックアップファイルの削除ボタン
    var elm = document.getElementById("removeButtonArea");
    elm.innerHTML = " ";
    var bt = newBUTTON(elm, "", "サーバから削除");
    bt.setAttribute("onclick", "removeBackupFile('GROUP')");
}

function load(){
	// ユーザポップアップとソースポップアップに応じたデータを読込む
    var logname = document.getElementById("userPopup").value;
	var src = document.getElementById("sourcePopup").value;

    if (src == "テンプレート"){
        // バックアップデータを表示
        var filename = "./GROUP.txt";
        showController("テンプレート ( " + filename + " ) ");
        
        getArchive(filename);
    } else if (src == "バックアップ"){
        // 過去ログからピックアップ
        //alert("load->"+logname+"->"+src); //##
        
        var filename = document.getElementById("filePop").value;
        //alert("load->"+filename); //##
        showController(logname + " 用バックアップ ( " + filename + " ) ");
        
        getArchive(filename);
    } else if (src == "データベース"){
        showController(logname + " 用データベース ");
        
		var tableName = "ProgressSection";
		var order = "`subject`";
        getTable(logname, tableName, order);
    }
}

var _archive;
var _archiveName;
function putArchive(filename){
	// データ・ソースを文字列ファイルとして保存	
	var recs = groupRecords();
	if (! recs){
		alert("データ・ソースが読み込まれていません");
		return;
	}
    
    _initDebug(false); //##
    _debug("recs->"+encodeObject(recs)); //##
    _debug("--------"); //##

	var array = new Array();
    for (i in recs){
		var obj = recs[i];
		//array.push(JSON.stringify(obj)); // --- うまく機能しない
		array.push(object2json(obj));
	}
	
	// [{"owner":"","tag":"","menu":"",,},{"owner":"",,},,] 形式
	var val = "[" + array.join(",") + "]";

    _debug("filename->"+filename+" val->"+val); //return; //##
	
	_archive = val;
	_archiveName = filename;
    archiveTableSource("C_L_E_A_T_E__F_I_L_E"); // サーバを新規ファイル受入れ状態にする
}

var _num;
function mergeCycle(){
	// Ajax で DB との間でリカーシブルに merge を行う
	var array = groupRecords();
	if (_num < array.length){
		var obj = array[_num++];
        mergeWithGroup(obj);
	} else {
        hideMessage("_message");
        
        // DB 内容を再表示
        var logname = document.getElementById("userPopup").value;
		var tableName = "ProgressSection";
		var order = "`subject`";
        getTable(logname, tableName, order);
        
		alert("データへの書込み終了しました");
    }
}

function save(){
	// ユーザポップアップとソースポップアップに応じたデータを書込む
    //if (debugMode()) _initDebug(true); else _initDebug(false); //##
    
	var src = document.getElementById("sourcePopup2").value;
	if (src == "バックアップ"){
		putArchive("GROUP");
	} else if (src == "テンプレート"){
		putArchive("./GROUP.txt");
	} else if (src == "データベース"){
		var elm = document.getElementById("isOverWrite");
        var st = (elm.checked)
        ? "ここに表示されたデータによって完全に置換されます"
        : "ここに表示されたデータとマージされます。すでに同じ tag, menu を持つレコードは置換されません。差分のみが追加されます。";
        
        _initDebug(false); //##
		
		if (confirm("データベースは、" + st)){
			// データ・ソースを DB とマージ
			//showMergeLog(); // マージのログを表示するエリアを用意
			_num = 0; // _num を 0 にセットしてから mergeCycle() を廻す
			if (elm && elm.checked)
				replaceGroupTable();
			else
				mergeCycle();
		}
	}
}

function removeCheckedRecords(){
	// チェックされたレコードをすべて削除
	var array = new Array();
	var recs = groupRecords();
    for (i in recs){
		var elm = document.getElementById("cb."+i);
		if (! elm.checked)
			array.push(recs[i]); // チェックの入らないものだけをピックアップ
	}
	setGroupRecords(array);
    showRecords();
}

function removeRecord(row){
	// row 行レコードを削除
	var array = groupRecords();
	var obj = array[row];
	if (confirm(obj.subject + " を削除していいですか")){
		array.splice(row, 1);
		
		setEditorId("");
		var elm = document.getElementById("directEdit");
		if (elm && elm.checked){
			// 直接データベースの obj を削除
            //if (debugMode()) _initDebug(true); else _initDebug(false); //##
			removeGroupTable(obj);
		} else
			showRecords();
	}
}

function changeRecord(row){
	// row 行レコードを変更
    _initDebug(true); //##

	var obj = new Object();
	obj.subject = document.getElementById("subject").value;
	obj.object = document.getElementById("object").value;
	obj.examination = document.getElementById("examination").value;
	obj.prescription = document.getElementById("prescription").value;
	obj.disease = document.getElementById("disease").value;
	obj.treatment = document.getElementById("treatment").value;
	obj.assessment = document.getElementById("assessment").value;
	obj.plan = document.getElementById("plan").value;
	obj.freq = document.getElementById("freq").value;
    
    _debug("changeRecord->"+encodeObject(obj)+"<br>"); //##
    
    // 新規レコードの場合もあるので obj は新たに起こしたものを使う
    groupRecords()[row] = obj;

	setEditorId("");
	var elm = document.getElementById("directEdit");
    
	if (elm && elm.checked){
		// 直接データベースの obj を更新
        _debug("check->"+elm.checked); //##
        putGroupTable(obj);
	} else {
		showRecords();
	}
}

function showNewEditor(){
	// 新規レコード作成エディターを開く
	// ## 新規レコードボタンに showEditor(row) を action として設定しても
	// ## その時点では row が決まっていない可能性があるため、この機能を独立させる
	var row = groupRecords().length;
    openEditor(row);
}

function openEditor(row){
	// row 行レコードの編集パネルを開く
	var obj = groupRecords()[row];
	if (!obj){
		obj = new Object();
		obj.subject = "新規レコード";
        // obj は「変更」ボタンが押されてから groupRecords に追加される
	}
	
	// 以前開いていたエディターあれば閉じる
	var old_eid = editorId();
	var isClosed = closeEditor();
	
	// 目的エディターが今閉じたエディターなら、閉じただけで終了
	var eid = editorIdForRow(row);
	
	if (isClosed && (eid == old_eid)) return;
	
	// エディターを開く領域を記憶
	setEditorId(eid);
    
    //if (debugMode()) alert(encodeObject(obj)); //##

    // レコード編集ペーンを表示
	var elm = document.getElementById(eid);
	elm.innerHTML = "";
	var tbl = newTABLE(elm, "subTable");
	tbl.style.border = "solid #fc0 5px";
	tbl.style.textAlign = "left";
	tbl.style.backgroundColor = "yellow";
	
	// title
	var tr = newTR(tbl, "editor_title", "");
	var td = newTD(tr, "", "");
	td.setAttribute("colspan", "2");
	var img = newIMAGE(td, "icon", "./close.png", "close");
	img.setAttribute("onclick", "closeEditor()");
	var tx = newTEXT(td, "　" + obj.subject + " を編集");
	
	// contents
	makeTextField(tbl, "subject", obj);
	makeTextField(tbl, "object", obj);
	makeTextField(tbl, "examination", obj);
	makeTextField(tbl, "prescription", obj);
	makeTextField(tbl, "disease", obj);
	makeTextField(tbl, "treatment", obj);
	makeTextField(tbl, "assessment", obj);
	makeTextField(tbl, "plan", obj);
	makeField(tbl, "freq", obj, true);
	makeField(tbl, "owner", obj, false);
	makeField(tbl, "entryDate", obj, false);
	makeField(tbl, "updateTime", obj, false);
	
	// comment
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "", "");
	var td = newTD(tr, "comment", "編集内容はバックアップやデータベースに書込まない限り保存されません ");
	
	// footer
	var tr = newTR(tbl, "editor_title", "");
	var td = newTD(tr, "controller", "");
	td.setAttribute("colspan", "2");
	td.style.textAlign = "right";
	var dataSource = document.getElementById("sourcePopup").value;
	if (dataSource == "データベース"){
        var owner = document.getElementById("userPopup").value;
		var cb=newCHECKBOX(td,"directEdit",owner + " のデータベースを直接編集 ",false);
	}
	var bt = newBUTTON(td, "", "削除");
	var action = "removeRecord('" + row + "')";
	bt.setAttribute("onclick", action);
	var bt = newBUTTON(td, "", "変更");
	var action = "changeRecord('" + row + "')";
	bt.setAttribute("onclick", action);
    
    // Editor が見えないことがあるので該当位置へスクロールしておく
    var pos = getPosition(bt);
	window.scroll(0, pos.y);
	
	function makeTextField(tbl, key, obj){
		var tr = newTR(tbl, "", key);
		var td = newTD(tr, "", "");
		var val = (obj[key]) ? obj[key] : "";
		var fd = newTEXTAREA(td, key, "50", "5", val);
	}
	
	function makeField(tbl, key, obj, status){
		var tr = newTR(tbl, "", key);
		if (status){
			var td = newTD(tr, "", "");
			var val = (obj[key]) ? obj[key] : "";
			var fd = newFIELD(td, key, "", "70", val);
		} else {
			var td = newTD(tr, "", obj[key]);
		}
	}
}

function checkAll(elm){
	// checkBox の全てにチェックを入れる
	var status = elm.checked;
	var recs = groupRecords();
    for (i in recs){
		var elm = document.getElementById("checkArea."+i);
		elm.innerHTML = "";
		var cb = newCHECKBOX(elm, "cb."+i, "", status);
	}
}

function find(){
	// 検索を実行
	var key = document.getElementById("keyF").value;
	var array = groupRecords();
	var count = 0;
    for (i in array){
		var tr = document.getElementById("row"+i);
		var obj = array[i];
		var found = false;
		if (key.length){
			var st = obj.subject + obj.examination + obj.treatment;
			if (st.indexOf(key) >= 0) found = true;
		}
		
		if (found){ // key が含まれていた行の色を変える
			tr.style.backgroundColor = "#ff0";
			count++;
		} else
			tr.style.backgroundColor = "#fff";
	}
	
	if (count)
		alert(count + " 個の該当レコードを見つけました。黄色い行が該当レコードです。スクロールしてみてください");
	else if (key.length > 0)
		alert(key + " を含むレコードは見つかりませんでした");
}

function showRecords(){
	// レコードを表示する
	var elm = document.getElementById("resultArea");
	elm.innerHTML = "";
	var tbl = newTABLE(elm, "base-table");
	
	// title
	var tr = newTR(tbl, "title-bar", "");
	var td = newTD(tr, "", "");
	td.style.width = "10 px";
	var cb = newCHECKBOX(td, "", "", false);
	cb.setAttribute("onclick", "checkAll(this)");
	var td = newTD(tr, "", "subject");
	var td = newTD(tr, "", "examination");
	//var td = newTD(tr, "", "prescription");
	var td = newTD(tr, "", "treatment");
	
	// records
	var array = groupRecords();
    for (i in array){
		var obj = array[i];
        _debug(i+"->"+encodeObject(obj));  //##
               
		var tr = newTR(tbl, "row"+i, "");
        tr.style.fontSize = "10pt";
		
		// check box
		var td = newTD(tr, "checkArea."+i, "");
		td.style.width = "10 px";
		var cb = newCHECKBOX(td, "cb."+i, "", false);

		var td = newTD(tr, "", obj.subject);
		td.setAttribute("onmouseout", "resetColor(this,'black','white')");
		td.setAttribute("onmouseover", "setColor(this, 'yellow', 'blue')");
		td.setAttribute("onclick", "openEditor('"+i+"')");
		
		var td = newTD(tr, "", obj.examination);
		//var td = newTD(tr, "", obj.prescription);
		var td = newTD(tr, "", obj.treatment);
		
		// 編集エリアを生成しておく
		var eid = editorIdForRow(i);
		var tr = newTR(tbl, "", "");
		var td = newTD(tr, eid, "");
		td.setAttribute("colspan", "5");
	}
	
	// 編集エリアを生成しておく
	var eid = editorIdForRow(array.length);
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, eid, "");
	td.setAttribute("colspan", "9");
	
	// save ボタンを表示
	showSaveButtons();
}

function initGroupMenu(){
	var elm = document.getElementById("base");
	elm.innerHTML = "";
    
    // HEADER
    var div = newDIV(elm, "");
	var tbl = newTABLE(elm, "base-table");
	var tr = newTR(tbl, "title-bar", "");
    // TITLE
	var td = newTD(tr, "left-side", "");
    td.setAttribute("onclick", "suser()");
    var sp = newSPAN(td, "markArea");
    var tx = newTEXT(td, "GroupMenu 編集");
	// HELP icon
	var td = newTD(tr, "right-side", "");
	var im = newIMAGE(td, "", "./Help.png", "?");
     im.setAttribute("onclick", "tableHelp()");
	im.style.height = "21px";
	im.style.verticalAlign = "bottom";

	// ロード・エリア
    var div = newDIV(elm, "loadButtonArea");
    div.style.paddingLeft = "10px";
	var sp = newSPAN(div, "userListArea"); // ユーザリストを表示
	var tx = newTEXT(div, " の ");
	var sp = newSPAN(div, "sourceListArea"); // データソースを表示
	var sp = newSPAN(div, "fileNamesArea"); // テンプレートのリストを表示
	var tx = newTEXT(div, " を ");
	var bt = newBUTTON(div, "", "読込む");
	bt.setAttribute("onclick", "load()");
	var sp = newSPAN(div, "removeButtonArea"); // テンプレートのリスト削除ボタン
    
	// セーブ・エリア
    var div = newDIV(elm, "saveButtonArea");
    div.style.paddingLeft = "10px";
    
	// データ表示エリア
    var div = newDIV(elm, "controlArea");
	
	// footer
    var div = newDIV(elm, "");
	var tbl = newTABLE(div, "base-table");
	var tr = newTR(tbl, "title-bar", "");
	var td = newTD(tr, "left-side", version());
	
	// ユーザ・ポップアップを読込む
	selectUserAndLoadStructure();
}

function version(){
	return "Ver.121008";
}
