
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;
}

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

function noa(){
    if (window.opener.name == "noa"){
        return window.opener;
    } else if (window.opener.name == "tools"){
        return window.opener.top.noa;
    } else if (window.top.noa){
        return window.top.noa;
    } else {
        alert("ERROR *** archiveer.js: window.opener としての NOA が見つかりません");
        return null;
    }
}

var _patientId;
function setPatientId(pid){
	_patientId = pid;
	document.getElementById("_pid").innerHTML = _patientId;
}
function patientId(){
    if (!_patientId) _patientId = noa().patient_id();
	return _patientId;
}

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

function owner(){
	return noa().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){
        alert("データの merge が終了しました");
        return;
    }

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

    //alert("obj->"+encodeObject(obj)); //##
    
	NRMergeArchive(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();
	//var pid = prompt("カルテID:", patientId());
	if (pid.length == 8){
		setPatientId(pid);
		NRGetArchive(pid, showArchive);
	} else
		alert("カルテID: "+ pid +" は間違いです");
}

function firstValueOf(obj){
    // テスト用：obj を文字列がでる最後まで掘る
    for (key in obj){
        var childObj = obj[key];
    }
    if (typeof(childObj) == "object")
//    if (isSame(childObj.toString(),"[object 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("_debug", msg, 3000);
}
function putArchive(){
	// この患者の全データをバックアップし保存するようサーバへ依頼
	NRPutArchive(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
	// # NRPutArchive() 時、データ中の " が ' に置換されてバックアップされている
	// #   これは server.php の encodeDoubleQuotation() で実施
	// # つまりカルテデータ中の " はバックアップから復元されると、すべて ' に置換されている
	// #   現データを完全に復元する仕様にするには ' ではなく別の特殊文字列を使い
	// #   eval() で JSON を解凍した後、特殊文字を " に置換しなおす必要あり
    var patientId = includedPatientId();
    var pidOriginal = document.getElementById("_pid").innerHTML;
    if (patientId != pidOriginal){
        // text 中に patientId があれば、それが patientId() と一致しているかチェック
        // もし異なっていれば、それを patientId() にセットして merge
        var message = "マージしようとするデータは " + pidOriginal + " とは異なる ID\n"
        + patientId + " を含んでいるため、この ID " + patientId + "\n"
        + "のカルテへマージします。いいですか ？";
        if (confirm(message))
            setPatientId(patientId);
        else
            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)); // ここは使われないはず
        }
	}
    
    //alert(encodeObject(records)); //return; //##
	
    setContainer(patientId, records); // サーバへの転送用オブジェクトを初期化
    document.getElementById("_nameArea").innerHTML = patientName;
    
    mergeItems();
}

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

function help(){
	// ヘルプパネルを表示
	window.open("./archiverHelp.html","Help"
				,"width=450,height=700,scrollbars=yes,resizable=yes");
}

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

    _initDebug(false); //##
    _debug("patient_id->"+noa().patient_id()); //##
    _debug("patientId->"+patientId()); //##

    // 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(td, "");
        dv.innerHTML = "バックアップ対象のカルテが開いていません";
        dv.style.color = "#f00";
        dv.style.fontSize = "12px";
    }
    // Help
	var td = newTD(tr, "right-side", "");
    td.style.paddingRight = "20px";
	var im = newIMAGE(td, "", "./Help.png", "?");
	im.setAttribute("onclick", "help()");
	im.style.height = "18px";
	im.style.verticalAlign = "bottom";
    
    // BODY
    if (patientId()){
        var div = newDIV(elm, "bodyArea");
        div.style.padding = "10px 10px";
        div.style.fontSize = "10px";
        
        // バックアップ作成
        var dv = newDIV(div, "");
        dv.innerHTML = "カルテをバックアップし ";
        var bt = newBUTTON(dv, "", "保存");
        bt.setAttribute("onclick", "putArchive()");
        
        // BUTTONS
        var dv = newDIV(div, "");
        dv.innerHTML = "カルテのバックアップを ";
        var bt = newBUTTON(dv, "", "読込");
        bt.setAttribute("onclick", "loadArchive()");
        // patientId 検索・アンカー
        var sp = newSPAN(dv, "/space-5");
        var a = newA(sp, "カルテID検索", "#", "");
        a.style.fontSize = "9pt";
        a.setAttribute("onclick", "findPatientId()");
        // クリアー・アンカー
        var sp = newSPAN(dv, "/space-5");
        var a = newA(sp, "画面クリア", "#", "");
        a.style.fontSize = "9pt";
        a.setAttribute("onclick", "empty()");
        
        // CONTENTS
        var dv = newDIV(div, "contentsArea");
        var ta = newTEXTAREA(dv, "text", 40, 25, "");
        
        // BUTTONS
        var dv = newDIV(div, "");
        dv.innerHTML = "このバックアップを ";
        var bt = newBUTTON(dv, "", "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();
}

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