
var _source;
function setObject(obj){
    _source = obj;
}
function objForKey(key){
    // カルテのオブジェクト
    return _source[key];
}

var _container; // Global 変数
function setContainer(patientId, array){
	_container = new Object();
	_container.patientId = patientId;
	_container.records = array;
	_container.index = 0;
}
function container(){
	return _container;
}
function incrementIndexOfContainer(){
	return _container.index++;
}
function currentRecordOfContainer(){
	var ix = _container.index;
	
	if (ix < _container.records.length)
		return _container.records[ix];
	else
		return null;
}

var _birthDate;
function setBirthDate(yyyymmdd){
    // 生年月日が _bdate で確定された
    if (mode() == _befor)
        _birthDate = yyyymmdd;
}
function setBirthDateAfter(yyyymmdd){
    if (mode() == _after)
        _birthDate = yyyymmdd;
}
function birthDate(){
    return _birthDate;
}

var _befor = 0;
var _after = 1;
function setMode(mode){
    _mode = mode;
}
function mode(){
    // 修正前か後かを返す
    return _mode;
}

var _patientId;
function setPatientId(){
    // 正しいカルテ番号
    var mmddyy = patientIdWithBirthdate(birthDate()); // 枝番号のないカルテID最初の６桁
    var num0 = document.getElementById("num01").value;
    var num1 = document.getElementById("num11").value;
    
    _patientId = mmddyy + num0 + num1;
}
function patientId(){
    return _patientId;
}

function wrongPatientId(){
    // 間違って作成したカルテの番号
    var mmddyy = patientIdWithBirthdate(birthDate()); // 枝番号のないカルテID最初の６桁
    var num0 = document.getElementById("num00").value;
    var num1 = document.getElementById("num10").value;
    var patientId = mmddyy + num0 + num1;
    
    return patientId;
}

function owner(){
	return document.getElementById("_owner").value;
}

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

function showAsJSON(answer){
    // サーバからの JSON 形式でマッピングされたデータを表示
    if (answer.length < 3){
        alert(wrongPatientId() + " のカルテは存在しません");
        return;
    }
    
	var obj = JSON.parse(answer);
    setObject(obj);
    
    var elm = document.getElementById("contentsArea");
    elm.innerHTML = "";

    // アーカイブのタイトル
    var div = newDIV(elm, "");
    var name = firstValueOf(obj['NameSection.patientKanjiName']);
    div.innerHTML = wrongPatientId() + " " + name + " のカルテをアーカイブしました ";
    
    // アーカイブ内容を表示する TEXTAREA
    var div = newDIV(elm, "");
    var ta = newTEXTAREA(div, "text", 80, 25, answer);
    
    // 生年月日とカルテ番号の修正エリアを開く
    var div = newDIV(elm, "");
    div.style.marginTop = "5px";
    div.innerHTML = "生年月日を";
    // 生年月日の初期値は、とりあえず誤って作成したカルテのものと同じにしておく
    setMode(_after); // 修正後を示す
    var st = birthDate();
    var array = st.split("-");
    var yyyy = array[0];
    var mm = "" + array[1];
    var dd = "" + array[2];
    var pm = newDatePopUp(div, "datePop", "", yyyy, mm, dd, false, setBirthDateAfter);
    var tx = newTEXT(div, " に ");
    var bt = newBUTTON(div, "button2", "修正");
    bt.setAttribute("onclick", "correctBirthDate()");
    
    // correct area
    var div = newDIV(elm, "patientIdArea1");
}
function getItems(){
    // この患者の全データをアーカイブし保存するようサーバへ依頼
    var bt = document.getElementById("button0");
    bt.setAttribute("Disabled");
    var bt = document.getElementById("button1");
    bt.setAttribute("Disabled");
    
    var elm = document.getElementById("contentsArea");
    elm.innerHTML = "";
    var dv = newDIV(elm, "");
    dv.style.paddingLeft = "10pt";
    dv.style.color = "#00f";
    dv.style.fontSize = "9pt";
    dv.innerHTML = "... Wait a minutes";
    
    NRPutArchive(owner(), wrongPatientId(), showAsJSON);
}

function merged(answer){
	// サーバからの JSON 形式でマッピングされたデータを表示
	var ix = incrementIndexOfContainer();
	var count = container().records.length;
	
	// answer は debug 用メッセージのみ
	document.getElementById("text").value
	= "(" + ix+ " / " + count + ")\n" + answer;
	
	mergeItems();
}
function mergeItems(){
	// このデータをマージするようサーバへ依頼
	// ### buff の長さが 8310 文字を越えるとサーバ転送エラーになるので
	// ### １レコードずつサーバへ転送してマージ依頼
	var pid = container().patientId;
	var buff = currentRecordOfContainer();
	if (buff == null){
        // マージ作業終了後の確認
        var elm = document.getElementById("confirmArea");
        elm.innerHTML = "";
        var div = newDIV(elm, "");
        var sp = newSPAN(div, "");
        sp.style.background = "#00f";
        sp.style.color = "#ff0";
        sp.style.marginTop = "10px";
        sp.style.padding = "2px 10px";
        sp.innerHTML = pid + " のカルテが作成されました。カルテを開いて確認してください";
        
        var div = newDIV(elm, "");
        div.innerHTML = "訂正前の誤カルテはそのまま残っています（ 左メニューの「カルテ削除」で削除できます）";
		return;
	}
	
	var ary = decodeArgs(buff);
	var tag = ary[0];
	var entryDate = encodeSTRING(ary[1]);
	var updateTime = encodeSTRING(ary[2]);
	var value = encodeSTRING(ary[3]);
    
	NRMergeArchive(owner(), pid, tag, entryDate, updateTime, value, merged);
}

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

function mergeToDB(){
    // 修正されたアーカイブを元に DB へ修正されたカルテを登録
	// JSON データをサーバ・データと merge
	var elm = document.getElementById("confirmArea");
    var sp = newSPAN(elm, "");
    sp.style.color = "brown";
    sp.style.padding = "0px 10px";
    sp.innerHTML = "登録作業中は、この画面を表示したままにしておいてください";
    
	var text = document.getElementById("text").value;
	// # text に改行が入っていると eval() でエラーになるので "\n" を "<BR/>" に変換
	text = transferCR(text); // "\n" を "<BR/>" に変換
	// # この他 NRPutArchive() 時、データ中の " が ' に置換されてアーカイブされている
	// #   これは server.php の encodeDoubleQuotation() で実施
	// # つまりカルテデータ中の " はアーカイブから復元されると、すべて ' に置換されている
	// #   現データを完全に復元する仕様にするには ' ではなく別の特殊文字列を使い
	// #   eval() で JSON を解凍した後、特殊文字を " に置換しなおす必要あり
	
	//var obj = eval('(' + text + ')');
	var obj = JSON.parse(text);
	var records = new Array();
	var patientId = "";
	var patientName = "";
	for (tag in obj){
		var val = obj[tag];
		if (typeof(val) == "object"){
			for (entryDate in val){
				var val2 = val[entryDate];
                if (typeof(val2) == "object"){
					for (updateTime in val2){
						var val3 = val2[updateTime];
						// table.field, entryDate, updateTime のレコードを探し
						// みつからなければ DB へ merge する
						if (isSame(tag,"PatientTable.patientId"))
							patientId = val3;
						else if (isSame(tag,"NameSection.patientKanjiName"))
							patientName = val3;
						var field = fieldWithTag(tag);
						if (isSame(field, "patientId")) continue;
						if (isSame(field, "entryDate")) continue;
						if (isSame(field, "updateTime")) continue;
						var st = tag + "_|_" + entryDate + "_|_" + updateTime;
						records.push(st + "_|_" + val3);
					}
				}
				else { // updateTime が省略されている場合はこちらで処理される
					if (isSame(tag,"PatientTable.patientId"))
						patientId = val2;
					else if (isSame(tag,"NameSection.patientKanjiName"))
						patientName = val2;
					var field = fieldWithTag(tag);
					if (isSame(field, "patientId")) continue;
					if (isSame(field, "entryDate")) continue;
					if (isSame(field, "updateTime")) continue;
					var st = tag + "_|_" + entryDate + "_|_" + entryDate;
					records.push(st + "_|_" + val2);
				}
			}
		}
		else
			alert(tag+" **( "+val+" )"); // ここは使われないはず
	}
    
	if (patientId.length == 0)
		alert("カルテID を取り出せません");
	else {
        //alert("merge:"+patientId+":"+patientName); //##
		setContainer(patientId, records); // サーバへの転送用オブジェクトを初期化
		mergeItems();
	}
	
	function fieldWithTag(tag){
		var array = tag.split(".");
		return array[1];
	}
}

function askToMerge(){
    // 修正されたデータを DB にマージするか問いかける
    var dv = document.getElementById("mergeToDBArea");
    dv.innerHTML = "ハイライトされた修正を確認したら 修正された " + patientId() + " のカルテを DB へ ";
    var bt = newBUTTON(dv, "", "登録");
    bt.setAttribute("onclick", "mergeToDB()");
}

function valueOfObject(obj){
    // obj 中に含まれる最終オブジェクトすなわち value を返す
    for (key in obj){
        var subObj = obj[key];
        if (typeof(subObj) == "object")
            return valueOfObject(subObj);
        else
            return subObj;
    }
    return null;
}
function changeValueWith(obj, val){
    // obj 中に含まれる最終オブジェクトすなわち value を返す
    // ##### このやり方では元の obj 自体を修正できていない ######
    var newObj = new Object();
    for (key in obj){
        var subObj = obj[key];
        if (typeof(subObj) == "object")
            newObj[key] = changeValueWith(subObj, val);
        else {
            newObj[key] = val;
        }
    }
    return newObj;
}
function correctBirthDate(){
    var bt = document.getElementById("button2");
    bt.setAttribute("Disabled");

    // 間違ったカルテのカルテ番号を「正しいカルテ番号」に修正
    var obj = objForKey("PatientTable.birthDate");
    var st = object2json(obj); // TEXTAREA 中の patientId オブジェクト
    var obj1 = changeValueWith(obj, birthDate());
    var st2 = object2json(obj1); // 修正した patientId オブジェクト
    
    // TEXTAREA 中の PatientTable.patientId 値を修正
    var buff = document.getElementById("text").value;
    
    buff = buff.replace(st, st2);
    document.getElementById("text").value = buff;
    // 修正部分をハイライト
    window.find(st2);
    
    // 次へ進むアンカーを表示
    var div = document.getElementById("patientIdArea1");
    div.innerHTML = "";
    var dv = newDIV(div, "");
    dv.style.paddingLeft = "20px";
    dv.innerHTML = "ハイライトされた修正部分を確認したら ";
    var a = newA(dv, "次へ", "#", "");
    a.setAttribute("onclick", "makePatientId(1)"); // 正しいカルテ番号への訂正行を生成
}
function correctPatientId(){
    // 間違ったカルテのカルテ番号を「正しいカルテ番号」に修正
    var bt = document.getElementById("button3");
    bt.setAttribute("Disabled");
    
    setPatientId();

    var obj = objForKey("PatientTable.patientId");
    var st = object2json(obj); // TEXTAREA 中の patientId オブジェクト
    var obj1 = changeValueWith(obj, patientId());
    var st2 = object2json(obj1); // 修正した patientId オブジェクト
    // TEXTAREA 中の PatientTable.patientId 値を修正
    var buff = document.getElementById("text").value;
    buff = buff.replace(st, st2);
    document.getElementById("text").value = buff;
    // 修正部分をハイライト
    window.find(st2);
    
    askToMerge();
}

function firstValueOf(obj){
	// obj を文字列がでる最後まで掘る
	for (key in obj){
		var childObj = obj[key];
	}
    if (typeof(childObj) == "object")
		return firstValueOf(childObj);
	else
		return childObj;
}

function makePatientId(num){
    // 生年月日を元に patientId を生成し表示
    var div = document.getElementById("patientIdArea"+num);
    div.innerHTML = "";

    // 修正すべき カルテID の指定
    var dv = newDIV(div, "");
    var sp = newSPAN(dv, "");
    sp.innerHTML = (num == 0) ? "誤って作成してしまったカルテのカルテ番号 " : "正しいカルテ番号 ";
    var mmddyy = patientIdWithBirthdate(birthDate()); // 枝番号のないカルテID最初の６桁
    
    var sp = newSPAN(dv, "");
    sp.innerHTML = mmddyy;
    makePopupMenu(sp, "num0"+num, [0,1,2,3,4,5,6,7,8,9], 0);
    makePopupMenu(sp, "num1"+num, [0,1,2,3,4,5,6,7,8,9], 0);
    
    var sp = newSPAN(dv, "");
    sp.style.padding = "0px 5px";
    if (num == 0){
        sp.innerHTML = "を";
        var bt = newBUTTON(dv, "button1", " 指定 ");
        bt.setAttribute("onclick", "getItems()");
    } else {
        sp.innerHTML = "に";
        var bt = newBUTTON(dv, "button3", "修正");
        bt.setAttribute("onclick", "correctPatientId()");
    }

    // コメント
    var dv = newDIV(div, "");
    dv.style.paddingLeft = "20px";
    dv.innerHTML = "カルテID ８桁の頭６桁は生年月日から決定されます。枝番号２桁を指定してください";
    
    var dv = newDIV(div, "correctBirthDateArea");
    
    if (num == 1){
        var dv = newDIV(div, "mergeToDBArea");
        var dv = newDIV(div, "confirmArea");
        dv.style.color = "brown";
        dv.style.marginTop = "10px";
    }
}

function initChangeTable(){
    var elm = document.getElementById("base");
    
    var div = newDIV(elm, "title-bar");
    div.innerHTML = "カルテ修正";
    
    var div = newDIV(elm, "");
    div.style.marginTop = "5px";
    div.style.paddingLeft = "20px";
    div.innerHTML = "誤った生年月日で作成してしまったカルテの「生年月日」と「カルテ番号」を修正し、正しいカルテとして登録します。";

    var div = newDIV(elm, "");
    div.style.paddingLeft = "20px";
    div.innerHTML = "誤って作成してしまったカルテに入力された生年月日";
	// birthDate area
    setMode(_befor); // 修正前を示す
    var sp = newSPAN(div, "");
    sp.style.padding = "0px 5px";
    var pm = newDatePopUp(sp, "birthPop", "昭和", 1942, 3, 23, false, setBirthDate);

    var sp = newSPAN(div, "");
    sp.style.padding = "0px 5px";
    sp.innerHTML = "を";
    
    var bt = newBUTTON(div, "button0", "指定");
    bt.setAttribute("onclick", "makePatientId(0)");

    // patientId area
    var div = newDIV(elm, "patientIdArea0");
    div.style.paddingLeft = "20px";

    // 修正エリア
    var div = newDIV(elm, "correctBirthdayArea");
    div.style.paddingLeft = "20px";

    // content area
    var div = newDIV(elm, "contentsArea");
    div.style.paddingLeft = "20px";
    
    // footer
    var div = newDIV(elm, "title-bar");
    div.style.marginTop = "5px";
    div.style.paddingLeft = "10px";
    div.innerHTML = version();
}

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

