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

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){
//    alert("setBirthDate->"+yyyymmdd); //##
    
    _birthDate = yyyymmdd;
}
function birthDate(){
    // 修正後の生年月日
    return _birthDate;
}

var _birthDateAfter;
function setBirthDateAfter(yyyymmdd){
//    alert("setBirthDateAfter->"+yyyymmdd); //##
    
    _birthDateAfter = yyyymmdd;
}
function birthDateAfter(){
    // 修正後の生年月日
    return _birthDateAfter;
}

var _patientId;
function setPatientId(){
    // 正しいカルテ番号
    _patientId = "";
    for (num=0; num < 8; num++){
        // 新規 patientId 設定用ポップアップから数値を読み取る
        _patientId += document.getElementById("pid" + num).value;
    }
}
function patientId(){
    return _patientId;
}

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

var _wrongPatientId;
function setWrongPatientId(id){
    _wrongPatientId = id;
}
function wrongPatientId(){
    // 間違って作成したカルテの番号
    return _wrongPatientId;
}

var _wrongPatientName;
function setWrongPatientName(name){
    _wrongPatientName = name;
}
function wrongPatientName(){
    // 間違って作成したカルテの受診者名
    return _wrongPatientName;
}

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

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

    // アーカイブのタイトル
    var div = newDIV(elm, "");
    var st = wrongPatientId() + " " + wrongPatientName();
    st += " のカルテのアーカイブを確認のため表示";
    st += "<br>* アーカイブとはデータベース内容をバックアップ用文字列にしたものです";
    div.innerHTML = st;
    div.style.color = "#b55"; // brown
    
    // アーカイブ内容を表示する TEXTAREA
    var div = newDIV(elm, "");
    var ta = newTEXTAREA(div, "text", 80, 15, answer);
    
    // 生年月日とカルテ番号の修正エリアを開く
    var div = newDIV(elm, "");
    div.style.marginTop = "5px";
    div.innerHTML = "上のカルテの生年月日を";
    // 生年月日の初期値は、とりあえず誤って作成したカルテのものと同じにしておく
    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 elm = document.getElementById("contentsArea");
    elm.innerHTML = "";
    
    put_archive(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 rec = decodeObject(buff);
	var tag = rec.tag;
	var entryDate = rec.entryDate;
	var updateTime = rec.updateTime;
	var value = rec.value;

	merge_archive(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 = "#f00"; 
    sp.innerHTML = "＊ 登録作業中は、この画面を表示したままにしておいてください";
    
	var text = document.getElementById("text").value;
	// # text に改行が入っていると eval() でエラーになるので "\n" を "<BR/>" に変換
	text = transferCR(text); // "\n" を "<BR/>" に変換
	// # この他 put_archive() 時、データ中の " が ' に置換されてアーカイブされている
	// #   これは server.php の encodeDoubleQuotation() で実施
	// # つまりカルテデータ中の " はアーカイブから復元されると、すべて ' に置換されている
	// #   現データを完全に復元する仕様にするには ' ではなく別の特殊文字列を使い
	// #   eval() で JSON を解凍した後、特殊文字を " に置換しなおす必要あり
	    
	var obj = JSON.parse(text);
    _debug("== mergeToDB->"+encodeObject(obj)); // return; //##
    
	var records = new Array();
	var patientId = "";
	var patientName = "";
	for (tag in obj){
		var val = obj[tag];
        _debug(tag+ "->"+val); //##
        
		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 rec = new Object();
                        rec.tag = tag;
                        rec.entryDate = entryDate;
                        rec.updateTime = updateTime;
                        rec.value = val3;
                        st = encodeObject(rec);
                        records.push(encodeObject(rec));
					}
				}
				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 rec = new Object();
                    rec.tag = tag;
                    rec.entryDate = entryDate;
                    rec.updateTime = updateTime;
                    rec.value = val2;
                    st = encodeObject(rec);
					records.push(encodeObject(rec));
				}
			}
		}
		else
			alert(tag+" **( "+val+" )"); // ここは使われないはず
	}
    _debug("----------"); //##
    
	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 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 obj = objForKey("PatientTable.birthDate");
    var st = JSON.stringify(obj); // TEXTAREA 中の patientId オブジェクト
    var obj1 = changeValueWith(obj, birthDateAfter());
    var st2 = JSON.stringify(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 mmddyy = patientIdWithBirthdate(birthDateAfter()); // 枝番号のないカルテID最初の６桁
    searchMatchedID(mmddyy);
}
function correctPatientId(){
    // 間違ったカルテのカルテ番号を「正しいカルテ番号」に修正
    //_initDebug(true); //##
    _debug("== correctPatientId"); //##

    setPatientId(); // 選択された新規 patientId を記憶
    
    // obj 中の patientId を訂正後の patientId() に置換
    var obj = objForKey("PatientTable.patientId");
    var newObj = new Object();
    for (entryDate in obj){
        var newORec = new Object();
        var rec = obj[entryDate];
        for (updateTime in rec){
            newORec[updateTime] = patientId(); // 修正後のカルテID
        }
        newObj[entryDate] = newORec;
    }
    set_ValueForKey(newObj, "PatientTable.patientId");
    
    // obj 中の patientId を訂正後の patientId() に置換
    var obj = objForKey("PatientTable.birthDate");
    var newObj = new Object();
    for (entryDate in obj){
        var newORec = new Object();
        var rec = obj[entryDate];
        for (updateTime in rec){
            newORec[updateTime] = birthDateAfter(); // 修正後の生年月日
        }
        newObj[entryDate] = newORec;
    }
    set_ValueForKey(newObj, "PatientTable.birthDate");
    
    var buff = JSON.stringify(source());
    document.getElementById("text").value = buff;
    mergeToDB();
}

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

function searcedhMatchedID(answer){
    // key にマッチしたカルテのリストを表示
    var elm = document.getElementById("listArea2");
    elm.innerHTML = "";
    
    var div = newDIV(elm, "");
    div.style.fontSize = "10pt";
    div.style.color = "#b55"; // brown

    var array = JSON.parse(answer);
    if (array.length == 0){
        var sp = newSPAN(div, "");
        sp.innerHTML = "修正された生年月日に一致するカルテは存在しないので";
        sp.style.color = "#f00";
        var tbl = newTABLE(elm, "/base-table");
        var mmddyy = patientIdWithBirthdate(birthDateAfter()); // カルテID最初の６桁
        var newPID = mmddyy + "00";
    } else {
        div.innerHTML = "修正された生年月日に一致する既存カルテは以下の通りです";
        var tbl = newTABLE(elm, "/base-table");
        tbl.style.fontSize = "10pt";
        
        var subNumber;
        for (num in array){
            var rec = array[num];
            var pid = rec.patientId;
            subNumber = pid.substr(6, 2) * 1 + 1; // 次にくるべき枝番号
            
            var tr = newTR(tbl, "", "");
            var td = newTD(tr, "", pid);
            var td = newTD(tr, "", rec.patientKanjiName);
            var td = newTD(tr, "", "最終受診日：" + rec.lastVisitDate);
        }
        
        var snumber = (subNumber < 10) ? "0" + subNumber : "" + subNumber;
        var newPID = pid.substr(0, 6) + snumber;
    }
    
    // 新規 patientId 設定用ポップアップを生成
    var div = newDIV(elm, "");
    var num = newPID.substr(0,1);
    var pu = newPopupMenu(div, "pid0", [num], num);
    var num = newPID.substr(1,1);
    var pu = newPopupMenu(div, "pid1", [num], num);
    var num = newPID.substr(2,1);
    var pu = newPopupMenu(div, "pid2", [num], num);
    var num = newPID.substr(3,1);
    var pu = newPopupMenu(div, "pid3", [num], num);
    var num = newPID.substr(4,1);
    var pu = newPopupMenu(div, "pid4", [num], num);
    var num = newPID.substr(5,1);
    var pu = newPopupMenu(div, "pid5", [num], num);
    var num = newPID.substr(6,1);
    var pu = newPopupMenu(div, "pid6", [0,1,2,3,4,5,6,7,8,9], num);
    var num = newPID.substr(7,1);
    var pu = newPopupMenu(div, "pid7", [0,1,2,3,4,5,6,7,8,9], num);
    
    var sp = newSPAN(div, "");
    sp.style.padding= "0 5px";
    sp.innerHTML = "の カルテID で";

    var bt = newDIV(div, "/whiteButton");
    bt.innerHTML = "新規登録";
    bt.setAttribute("onclick", "correctPatientId()");
    bt.style.padding = "2px 10px";
    bt.style.fontSize = "12pt";
    
    // コメント
    var div = newDIV(elm, "");
    div.style.color = "#b55"; // brown
    div.style.fontSize = "10pt";
    div.style.margin = "3px 0";
    var dv = newDIV(div, "");
    dv.innerHTML = "末尾２桁の枝番号のみ変更可（以下のような場合以外は変更不要）";
    var dv = newDIV(div, "");
    dv.style.paddingLeft = "20px";
    var st = "新規IDが既存IDと重複した場合、既存のカルテ内容へ<br>";
    st += wrongPatientId() + " " + wrongPatientName() + "　の内容が追加挿入されます";
    dv.innerHTML = st;
    
    // コメント
    var div = newDIV(elm, "mergeToDBArea");
    
    // merge 表示エリア
    var div = newDIV(elm, "confirmArea");
}
function searchMatchedID(key){
    // 修正されるべきカルテ番号の先頭6桁に一致する既存のカルテIDを検索
    get_patients(key, searcedhMatchedID); // サーバでアクセス・ログに記憶
//    NRGetPatients(key, searcedhMatchedID);
}

function confirmToChange(patientId, patientKanjiName){
    // 変換の確認をとる
    document.getElementById("patientIdArea").innerHTML = "";
    document.getElementById("contentsArea").innerHTML = "";
    document.getElementById("listArea2").innerHTML = "";
    
    setWrongPatientName(patientKanjiName); // 修正対象の受診者名を記憶
    setWrongPatientId(patientId); // 修正対象のカルテIDを記憶
    
    put_archive(owner(), patientId, showAsJSON);
}

function searched(answer){
    // 検索結果を表示
    //alert("searched->"+answer); //##
    var base2 = document.getElementById("base2");
    base2.innerHTML = "";
    
    // リストアップ・エリア
    var div = newDIV(base2, "listArea");
    var pidArea = newDIV(base2, "patientIdArea");
    
    var array = JSON.parse(answer);
    if (array.length == 0){
        var sp = newDIV(pidArea, "");
        sp.innerHTML = birthDate() + " に該当するものはありません";
        sp.style.fontSize = "10pt";
        sp.style.padding = "10px";
        sp.style.color = "#f55";
    } else {
        var tbl = newTABLE(div, "/base-table");
        tbl.style.fontSize = "10pt";
        tbl.style.marginBottom = "5pt";
        
        for (num in array){
            var rec = array[num];
            var pid = rec.patientId;
            var name = rec.patientKanjiName;
            
            var tr = newTR(tbl, "/record", "");
            tr.setAttribute("onclick", "confirmToChange('"+pid+"','"+name+"')");
            var td = newTD(tr, "", rec.patientId);
            var td = newTD(tr, "", rec.patientKanjiName);
            var td = newTD(tr, "", "最終受診日：" + rec.lastVisitDate);
        }
        
        var sp = newDIV(pidArea, "");
        var st = "該当するカルテが " + array.length + " 件ありました<br>";
        st += "誤って作成したカルテを選択してください";
        sp.innerHTML = st;
        sp.style.color = "#b55"; // brown
        sp.style.fontSize = "10pt";
        sp.style.padding = "5px 10px";
        
        // content area
        var div = newDIV(base2, "contentsArea");
        
        // 再リストアップ・エリア
        var div = newDIV(base2, "listArea2");
    }
}
function search(){
    // 指定された生年月日に該当するカルテをリストアップ
    var patientId = patientIdWithBirthdate(birthDate());
    
    get_patients(patientId, searched); // サーバでアクセス・ログに記憶
//    NRGetPatients(patientId, searched);
}

function initChangeTable(){
    var elm = document.getElementById("base");
    elm.style.backgroundColor = "#ffe";
    
    // === HEADER ==================================
    var div = newDIV(elm, "/yellow-header");
    var dv = newDIV(div, "/left-side");
    dv.innerHTML = "カルテ修正";
    
    // === CONTENTS HEADER =========================
    var base1 = newDIV(elm, "");
    base1.style.padding = "5px 20px";
    base1.style.fontSize = "10pt";
    
    var div = newDIV(base1, "");
    var st = "誤った生年月日で作成してしまったカルテを修正するツールです<br>";
    st += "「生年月日」と「カルテ番号」を修正したカルテを新たに作成します<br>";
    st += "最後に「新規登録」ボタンを押さなければ何も改変されませんので試してみてください";
    div.innerHTML = st;
    div.style.color = "#b55"; // brown
    div.style.paddingBottom = "10px";
    
	// birthDate area
    var div = newDIV(base1, "");
    div.innerHTML = "誤って作成したカルテの生年月日";
    var sp = newSPAN(div, "");
    sp.style.padding = "0px 5px";
    
    // 30才の生年月日を default として表示
    var diff = -60 * 24 * 365 * 30; // 30年前
    var dateTime = dateWthDiff(todayAndTime(), diff);
    var array = dateTimeArray(dateTime);
    var yyyy = array[0];
    var mm = array[1];
    var dd = array[2];
    var pm = newDatePopUp(sp, "birthPop", "昭和", yyyy, mm, dd, false, setBirthDate);

    var bt = newBUTTON(div, "button0", "確定");
    bt.setAttribute("onclick", "search()");
    
    // === CONTENTS ================================
    var base2 = newDIV(elm, "base2");
    base2.style.padding = "5px 20px";
    base2.style.fontSize = "10pt";

    // === FOOTER ==================================
    var div = newDIV(elm, "/yellow-footer");
    div.style.paddingLeft = "10px";
    div.innerHTML = version();
}

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

