
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 _patientId;
function setPatientId(pid){
	_patientId = pid;
	document.getElementById("_pid").innerHTML = _patientId;
}
function patientId(){
    if (!_patientId) _patientId = parent().patientId();
	return _patientId;
}

function patientName(){
    return (parent()) ? parent().patientKanjiName() : "";
}

function owner(){
	return parent().owner();
}

///// カルテからの継承値 ///
/////////////////////////

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

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 obj = currentRecordOfContainer();
	if (obj == null){
        // mergeItems() のサイクルが終了する
        alert("データの merge が終了しました");
        return;
    }

	var pid = container().patientId;
	var tag = obj.tag;
	var entryDate = obj.entryDate;
	var updateTime = obj.updateTime;
	var value = obj.value;

	merge_archive(owner(), pid, tag, entryDate, updateTime, value, merged);
}

function showArchive(answer){
	// サーバからの JSON 形式でマッピングされたバックアップデータを表示
    // answer の構造体そのままで良いのだが、日本語が encode されていて
    // 読めないので、一旦 JSON decode し、それを文字列として表示させる
    try {
        // JSON を decode し日本語文字列を読めるようにする
        var obj = JSON.parse(answer);
        
        // 読めるようになった日本語文字列を text に表示
        document.getElementById("text").value = JSON.stringify(obj);
    } catch (err) {
        alert("JSON としての解析ができません -- " + err); // Error: Invalid argument.
    }
}
function loadArchive(){
	// patientId のバックアップを読み出して表示する
	var pid = patientId();
	if (pid.length == 8){
		setPatientId(pid);
        var args = new Object();
        args["patientId"] = pid;
        NRCall("GET_ARCHIVE", args, showArchive);
	} else
		alert("カルテID: "+ pid +" は間違いです");
}

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

function puttedArchive(answer){
	// サーバからの JSON 形式でマッピングされたデータを表示
    //alert("puttedArchive->"+answer);
	var obj = JSON.parse(answer); // NOA の JSON データ
    // 日本語文字列として読めるよう変換
    var buff = JSON.stringify(obj);
    
    //alert("puttedArchive->"+encodeObject(obj)); //##
    
    var name = firstValueOf(obj['NameSection.patientKanjiName']);
    if (name){
        var elm = document.getElementById("_nameArea");
        elm.innerHTML = name;
    }
	
	var elm = document.getElementById("contentsArea");
	elm.innerHTML = "";
	var ta = newTEXTAREA(elm, "text", 40, 25, buff);
    //	var ta = newTEXTAREA(elm, "text", 40, 25, answer);
    
	var msg = patientId() + " のカルテをバックアップしました";
    showFadeoutInfo("message", msg, 1000);
}
function putArchive(){
	// この患者の全データをバックアップし保存するようサーバへ依頼
	put_archive(owner(), patientId(), puttedArchive);
}

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


function jsonToString(obj, indent){
	// object を JSON 形式文字列に変換して返す
	var buff = '{\n';
	var num=0;
	for (key in obj){
		var val = obj[key];
		if (isSame(val.toString(), "[object Object]") > 0){
			// lib.js とは違って key を最初から順番に打ち直す
			//key = (parentid.length == 0) ? num++ : parentid+"."+num++;
			buff += space(indent) + '"' + key + '":' + jsonToString(val, indent+1) + ',\n';
		}
		else
			buff += space(indent) + '"' + key + '":"' + val + '",\n';
	}
	buff = buff.substr(0, buff.length - 2); // 末尾の余計な ',' を削除
	buff += '}';
	return buff;
	
	function space(indent){
		var ln = "";
		for (var i=0; i < indent; i++){
			ln += "\t";
		}
		return ln;
	}
}

function chartObject(){
    // text 内の文字列からカルテ・オブジェクトを返す
    var text = document.getElementById("text").value;
    if (text.length == 0){
        alert("テキストが空です");
        return null;
    }
    
	// # 改行が入っていると JSON.parse() でエラーになるので "\n" を "<br>" に変換
    text = transferCR(text); // "\n" を "<br>" に変換
    try {
        var obj = JSON.parse(text);
        return obj;
    } catch(err){
        alert("JSON としての解析ができません -- " + err); // Error: Invalid argument.
        return null;
    }
}

function includedPatientId(){
    // バックアップに埋め込まれた patientId を返す
    var obj = chartObject();
    if (obj){
        // text からオブジェクトが解析できた
        var pidObj = obj['PatientTable.patientId'];
        if (pidObj){
            for (edate in pidObj){
                var eobj = pidObj[edate];
                for (udate in eobj){
                    var pid = eobj[udate];
                    return pid;
                }
            }
        }
    }
    return null;
}

function findPatientId(){
    //　バックアップの中から patientId を検索
    var pid = includedPatientId();
    if (pid){
        //document.getElementById("_debug").innerHTML = pid;
        // 両端を " で括らないと 画像URL なども拾ってしまう
        var key = '"' + pid + '"';
        window.find(key);
        
        // このままだと "pid" のように " を含んだ部分が選択されているので
        // 純粋に pid だけの選択にするため、以下を実行
        
        // 検索にヒットし選択された部分すなわち "pid" を取得
        var sel = window.getSelection(); // HTML5
        // 選択された文字列の先頭を選択
        sel.collapseToStart();
        // その位置から " の括りのない pid で再検索
        window.find(pid);
    }
}

function merge(){
	// JSON データをサーバ・データと merge
	// # put_archive() 時、データ中の " が ' に置換されてバックアップされている
	// #   これは server.php の encodeDoubleQuotation() で実施
	// # つまりカルテデータ中の " はバックアップから復元されると、すべて ' に置換されている
	// #   現データを完全に復元する仕様にするには ' ではなく別の特殊文字列を使い
	// #   eval() で JSON を解凍した後、特殊文字を " に置換しなおす必要あり
    //_initDebug(true); //##
    _debug("== merge"); //##
    
    var patientId = includedPatientId();
    //_debug("patientId->"+patientId); //##
    
    var pidOriginal = document.getElementById("_pid").innerHTML;
    //_debug("pidOriginal->"+pidOriginal); //##
    
    if (patientId != pidOriginal){
        // text 中に patientId があれば、それが patientId() と一致しているかチェック
        // もし異なっていれば、それを patientId() にセットして merge
        var message = "マージしようとするデータは " + pidOriginal + " とは異なる ID\n"
        + patientId + " を含んでいるため ID " + patientId + "\n"
        + "のカルテへマージします。いいですか ？";
        if (! confirm(message))
            return;
    }
    if (!patientId){
		alert("カルテID を取り出せません");
        return;
    }

    setPatientId(patientId);
	var records = new Array();
	var patientName = "";
    var obj = chartObject();
	for (tag in obj){
        var array = tag.split(".");
        var field = array[1];
        if (isSame(field, "patientId")) continue;
        if (isSame(field, "entryDate")) continue;
        if (isSame(field, "updateTime")) continue;

		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 value = val2[updateTime];
						// table.field, entryDate, updateTime のレコードを探し
						// みつからなければ DB へ merge する
                        if (isSame(tag,"NameSection.patientKanjiName"))
                            patientName = value;
                        var rec = new Object();
                        rec.tag = tag;
                        rec.entryDate = entryDate;
                        rec.updateTime = updateTime;
                        rec.value = value;
						records.push(rec);
					}
				}
			}
		} else {
			alert(tag + " **( "+val+" ) -> "+typeof(val)); // ここは使われないはず
        }
	}
    
    _debug("patientName->"+patientName); //##
    
    //_debug(encodeObject(records)); //return; //##
	
    setContainer(patientId, records); // サーバへの転送用オブジェクトを初期化
    document.getElementById("_nameArea").innerHTML = patientName;
    
    mergeItems();
}

function empty(){
	var elm = document.getElementById("text");
	elm.value = "";
	elm.focus();
}

function initArchiver(){
	var elm = document.getElementById("base");

    // HEADER
    var div = newDIV(elm, "/tool-header");
	var tbl = newTABLE(div, "/base-table");
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "/left-side", "");
    if (patientId()){
        var sp = newSPAN(td, "_pid", "");
        sp.innerHTML = patientId();
        setPatientId(patientId());
        var sp = newSPAN(td, "_nameArea", "");
        sp.innerHTML = patientName();
        sp.style.paddingLeft = "10px";
    } else {
        var dv = newDIV(elm, "");
        dv.innerHTML = "バックアップ対象のカルテが開いていません";
        dv.style.color = "#f00";
        dv.style.fontSize = "12px";
        dv.style.padding = "5px";
    }
    // Help
	var td = newTD(tr, "/right-side", "");
    td.style.paddingRight = "20px";
	var im = newIMAGE(td, "", "./help.png", "?");
	im.setAttribute("onclick", "openHelp('./archiverHelp.html')");
	im.style.height = "18px";
	im.style.verticalAlign = "bottom";
    
    // BODY
    if (patientId()){
        var div = newDIV(elm, "/tool-body"); // var div = newDIV(elm, "bodyArea");
        div.style.fontSize = "9pt";
        div.style.padding = "10px";
        
        // バックアップ作成
        var dv = newDIV(div, "");
        dv.innerHTML = "カルテをバックアップし ";
        var bt = newDIV(dv, "/whiteButton");
        bt.innerHTML = "保存";
        bt.setAttribute("onclick", "putArchive()");
        
        // BUTTONS
        var dv = newDIV(div, "");
        dv.innerHTML = "カルテのバックアップを ";
        var bt = newDIV(dv, "/whiteButton");
        bt.innerHTML = "読込";
        bt.setAttribute("onclick", "loadArchive()");
        // patientId 検索・アンカー
        var dv = newDIV(div, "");
        dv.style.textAlign = "right";
        var sp = newSPAN(dv, "/anchor");
        var a = newA(sp, "カルテID検索", "#", "");
        a.setAttribute("onclick", "findPatientId()");
        // クリアー・アンカー
        var sp = newSPAN(dv, "/anchor");
        var a = newA(sp, "画面クリア", "#", "");
        a.setAttribute("onclick", "empty()");
        
        // CONTENTS
        var dv = newDIV(div, "contentsArea");
        var ta = newTEXTAREA(dv, "text", 45, 25, "");
        
        // BUTTONS
        var dv = newDIV(div, "");
        dv.innerHTML = "このバックアップを ";
        dv.style.marginBottom = "5px";
        var bt = newDIV(dv, "/fixButton");
        bt.innerHTML = "DB へ追加";
        bt.setAttribute("onclick", "merge()");
    }

    // FOOTER
    var div = newDIV(elm, "/tool-footer");
    var dv = newDIV(div, "/left-side");
    dv.innerHTML = version();
    dv.style.position = "relative";
    dv.style.marginTop = "5px";

	ta.focus();
    
    // iFrame なら toggleButton にツール名を表示
    var bt = tools().elmFor("toggleButton");
    if (bt) bt.innerHTML = "バックアップ・ツール";
}

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