
/////////////////////////////////////////////
///// NOA からの継承値 /////////////////////////

// NOA 組込みの場合は patientId() などを直接取得できるが
// 外付けツールにも出来るようあえて以下の仕組みを使う

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

///// NOA からの継承値 /////////////////////////
//////////////////////////////////////////////

var _currentUser;
function setCurrentUser(user){
    _currentUser = user;
}
function currentUser(){
    return _currentUser;
}
function userKanjiName(){
    return noa().userKanjiName(_currentUser);
}

var _layout;
function setLayout(obj){
    _layout = obj;
}
function setLayoutForMode(array, mode){
    // レイアウトの mode() に該当する部分だけを array 要素と置換
    var layoutArray = new Array();
    for (tag in _layout){
        var cell = _layout[tag];
        if (cell.id == mode){
            var rec = array.shift();
            rec.id = mode; // 念のため
            layoutArray.push(rec);
        } else {
            layoutArray.push(cell);
        }
    }
    
    _layout = layoutArray;
}
function layout(){
    // レイアウト・オブジェクト
    // {"ProgressSection.subject":{"label":"主訴","menuType:"3",,,},,,}
    return _layout;
}
function layoutArray(mode){
    // mode に該当するレイアウト・オブジェクトだけを配列に入れ返す
    // layoutArray は numbering 属性でソートした配列
    var layoutArray = new Array();
    for (tag in _layout){
        var cell = _layout[tag];
        if (mode == null)
            layoutArray.push(cell);
        else if (cell.id == mode)
            layoutArray.push(cell);
    }
    
    return layoutArray;
}

//////////////////////////////////////////////
///// Ajax ///////////////////////////////////

function savedLayoutAndBackup(answer){
    // バックアップ・ペーンを閉じる
    document.getElementById("workArea").innerHTML = "";

    var msg = "レイアウト保存とともに バックアップも保存しました";
    showFadeoutInfo("_debug", msg, 1000);
    
    // msg が見えるようスクロール
    var elm = document.getElementById("_debug");
    var pos = getPosition(elm);
    window.scroll(0, pos.y + 10);
}
function savedLayout(answer){
    // バックアップファイルも保存
    var array = layoutArray();
    NRPutArchiveFile(currentUser(), "NOA_LAYOUT", array, savedLayoutAndBackup);
}
function saveLayout(){
    // 編集された cell 配列の一部を {"tag":"label",,,} 形式でサーバへ保存
    // バックアップの保存も行われる
    if (mode() == _insurance){
        alert("保険情報は専用エディターで扱われるので編集内容は反映されません");
        return;
    }
    
    // _list 中の cell に自動 numbering はサーバ側で実施
    NRPostLayout(currentUser(), encodeObject(_list), savedLayout);
}

function revertedLayout(answer){
    //alert(answer);
    
    // layoutArray() を再読み込みするためブラウザーをリロード
    noa().window.location.reload(true);
}
function revertLayout(){
    // mode のレイアウトを工場出荷状態に戻す
    if (confirm("レイアウトを工場出荷状態に戻していいですか"))
        NRRemoveTagAndLabel(currentUser(), revertedLayout);
}

function gotLayoutArchives(answer){
    var obj = JSON.parse(answer);
    var path = obj.path; // "../Users/ohashi/TOOL_MENU"
    var filenames = obj.files; // ["20120905164838.txt","20120905163836.txt"]
    
    // バックアップ操作ペーンを開く
    showBackup(filenames);
}
function getLayoutArchives(){
    // TOOL MENU のアーカイブファイル・リストをサーバへリクエスト
    var elm = document.getElementById("workArea");
    if (elm.innerHTML.length){ // toggle 式に開閉
        elm.innerHTML = "";
        return;
    }
    
    NRGetArchiveFiles(currentUser(), "NOA_LAYOUT", gotLayoutArchives);
}

function gotLayoutAndReload(answer){
    // layoutArray() を再読み込みするためブラウザーをリロード
    //alert(answer);
    noa().window.location.reload(true);
}
function gotLayoutFile(answer){
    //alert(answer); //##
    var array = JSON.parse(answer);
    
    // 読み込んだアーカイブを layoutArray() へセット
    noa().swapLayoutArray(array);

    // サーバへ保存
    NRPostLayout(currentUser(),encodeObject(array), gotLayoutAndReload);
}
function getLayoutFile(){
    // LAYOUT のアーカイブファイルをサーバへリクエスト：バックアップから復元
    var filename = document.getElementById("fileNamePop").value;
    NRGetArchiveFile(currentUser(), "NOA_LAYOUT", filename, gotLayoutFile);
}

function removedArchiveFile(answer){
    //alert(answer); //##
    document.getElementById("workArea").innerHTML = ""; // 削除しないと toggle
    getLayoutArchives();
}
function removeArchiveFile(){
    // アーカイブ・ファイルを削除
    var filename = document.getElementById("fileNamePop").value;
    if (confirm(filename+" を削除していいですか"))
        NRRemoveArchiveFile(currentUser(), "NOA_LAYOUT", filename, removedArchiveFile);
}

function gotPreference(answer){
    // レイアウトをサーバから受取り表示
    var obj = JSON.parse(answer);
    
    _initDebug(false);
    //_debug("=== gotPreference === "+answer);
    _debug("=== gotPreference: サーバから読込み === ");
    for (tag in obj){
        _debug(tag+"->"+obj[tag].label); //##
    }
    _debug("=== 以下はテンプレートから補完 === ");

    // サーバから得たオブジェクトにないものをテンプレートから補完
    var tmpObj = cellTemplate();
    for (tag in tmpObj){
        if (!obj || !obj[tag]){
            obj[tag] = tmpObj[tag];
            
            _debug(tag+"=>"+obj[tag].label); //##
        }
    }
    _debug("=== サーバから読込みと補完を併せたもの === ");
    for (tag in obj){
        _debug(tag+"->"+obj[tag].label+"->"+obj[tag].id); //##
    }

    //alert("内容確認のため一旦停止"); return; //###
    
    setLayout(obj);
    
    openLayoutPanel();
}
function getPreference(){
    // サーバへ currentUser() のレイアウト情報をリクエスト
    var kanjiName = document.getElementById("userPop").value;
    var user = noa().loginNameForkanjiName(kanjiName);
    setCurrentUser(user);
    
	NRGetLayout(currentUser(), gotPreference);
}

///// Ajax ///////////////////////////////////
//////////////////////////////////////////////


//////////////////////////////////////////////
///// ARCHIVE LAYOUT /////////////////////////

function showBackup(filenames){
    // レイアウトのバックアップ操作ペーンを開く
    var elm = document.getElementById("workArea");
    elm.innerHTML = "";
    
    var div = newDIV(elm, "");
    div.style.fontSize = "9pt";
    div.style.fontFamily = "arial, Helvetica";
    div.style.padding = "15px 15px";
    div.style.background = "#ffd";
    div.style.border = "thin solid #833";
    div.style.color = "#833"; // brown
    
    // バックアップから服天
    var dv = newDIV(div, "");
    dv.style.marginBottom = "5px";
    var sp = newSPAN(dv, "");
    sp.style.marginRight = "5px";
    sp.innerHTML = "レイアウトを";
    
    var array = new Array();
    for (num in filenames){
        // ファイル名が _ で始まる削除済みファイルを抜いたものをポップアップ表示
        var name = filenames[num];
        if (name.charAt(0) == "_") continue;
        if (name.indexOf("NOA") > 0) continue;
        
        array.push(name);
    }
    var pm = makePopupMenu(dv, "fileNamePop", array, "");
    setInfoTip("fileNamePop", "過去のバックアップ・ファイル"); // HELP
    
    var bt = newBUTTON(dv, "", "から復元");
    bt.setAttribute("onclick", "getLayoutFile()");
    // バックアップ・ファイル削除アイコン
    var sp = newSPAN(dv, "removeArchiveIcon");
    sp.style.marginRight = "5px";
    setInfoTip("removeArchiveIcon", "選択したバックアップを削除"); // HELP
    var img = newIMAGE(sp, "", "./remove-field.png", "X");
    img.style.height = "11px";
    img.setAttribute("onclick", "removeArchiveFile()");
    
    // 工場出荷状態に戻す
    var dv = newDIV(div, "");
    var sp = newSPAN(dv, "");
    sp.innerHTML = "レイアウトを";
    sp.style.paddingRight = "5px";
    var bt = newBUTTON(dv, "", "工場出荷状態に戻す");
    bt.setAttribute("onclick", "revertLayout()");
}

///// ARCHIVE LAYOUT /////////////////////////
//////////////////////////////////////////////


var _list;
var _mode;

function setMode(mode){
    _mode = mode;
}
function mode(){
    return _mode;
}

function recordForId(id){
    // id に相当する field 属性を返す
    for (num in _list){
        var rec = _list[num];
        if (rec.lid == id) return rec;
    }
    return null;
}

function checkedBox(elm, id){
    // id に相当するレコードの hitAndRun 属性が変更された
    // hitAndRun にチェックが入った項目は NOA に表示されない
    var rec = recordForId(id);
    if (elm.checked)
        rec.hitAndRun = 0;
    else
        rec.hitAndRun = 1;
}

function checkedBox2(elm, id){
    // id に相当するレコードの disabled 属性が変更された
    // disabled にチェックが入った項目は read-only
    var rec = recordForId(id);
    if (elm.checked)
        rec.disabled = 1;
    else
        rec.disabled = 0;
}

function labelChanged(elm, id){
    // id に相当するレコードの label 属性が変更された
    var rec = recordForId(id);
    rec.label = elm.value;
}

function doAddField(){
    // 新規作成したフィールドを _list へ追加
    var rec = new Object();
    
    // hitAndRun
    var isVisible = document.getElementById("newVisibleBox");
    rec.hitAndRun = (isVisible.checked) ? 1 : 0;
    
    // disabled
    var isDisabled = document.getElementById("newFixeBox");
    rec.isDisabled = (isDisabled.isDisabled) ? 1 : 0;
    
    // tag
    var fname = document.getElementById("newFieldNameF").value;
    rec.tag = "UniversalSection." + fname;
    
    // label
    rec.label = document.getElementById("newLabelF").value;
    
    // owner
    rec.owner = currentUser();
    
    // buttonType -- １回のみ選択
    rec.buttonType = 0;
    // menuType -- rotary などメニュー形式
    rec.menuType = 0;
    // menuAction -- メニュー挿入位置
    rec.menuAction = 0;
    // fieldType -- String, Text 形式
    rec.fieldType = 0;
    // editor
    rec.editor = "";
    // id
    rec.id = mode(); // mode 判定用に使う：数値だと、第７世代 NOA の CELL_ID とカブる
    // script
    rec.script = "";
    // study
    rec.study = 0;
    // numbering -- サーバ側で付番
    // bgcolor
    // fontSize
    // fontFamily
    // color

    // 実際には上記のように FieldTable 全属性は不要 Layout に必要なもののみでよい
    _list.push(rec);

    // 登録後の状態を表示
    showFieldList(mode(), _list);
}

function cancelAddField(){
    // 新規フィールド追加エディターをキャンセル：元の画面に戻す
    showFieldList(mode(), _list);
}

function addField(recId){
    // 新規フィールド追加エディターを表示

    // 表示チェック
    var td = document.getElementById("c0");
    var cb = newCHECKBOX(td, "newVisibleBox", "", 1);
    cb.setAttribute("onchange", "checkedBox(this,'"+recId+"')");
    // 固定チェック
    var td = document.getElementById("c1");
    var cb = newCHECKBOX(td, "newFixeBox", "", 0);
    cb.setAttribute("onchange", "checkedBox2(this,'"+recId+"')");
    // タグ
    var td = document.getElementById("c2");
    td.innerHTML = "UniversalSection.";
    td.style.fontSize = "8pt";
    var fd = newFIELD(td, "newFieldNameF", "", 10, "");
    fd.setAttribute("onchange", "labelChanged(this,'"+recId+"')");
    // ラベル
    var td = document.getElementById("c3");
    var fd = newFIELD(td, "newLabelF", "", 10, "");
    fd.setAttribute("onchange", "labelChanged(this,'"+recId+"')");
    // 確定ボタン
    var bt = newBUTTON(td, "", "確定");
    bt.setAttribute("onclick", "doAddField()");
    // とりやめボタン
    var sp = newSPAN(td, recId+".icon");
    sp.style.paddingLeft = "5px";
    setInfoTip(recId+".icon", "この行を削除"); // HELP
    var img = newIMAGE(sp, "", "./remove-field.png", "X");
    img.style.height = "12px";
    img.setAttribute("onclick", "cancelAddField()");
}

function showAddFieldButton(tbl, recId){
    // 新規項目追加ボタンを表示
    var tr = newTR(tbl, "", "");
    var td = newTD(tr, "c0", "");
    var td = newTD(tr, "c1", "");
    var td = newTD(tr, "c2", "");
    var bt = newBUTTON(td, "", "新規項目追加");
    bt.setAttribute("onclick", "addField('" + recId + "')");
    var td = newTD(tr, "c3", "");
}

function removedRecordsForTag(answer){
    showFadeoutInfo("_debug", answer, 1000);
}
function removeCell(tag, label){
    // tag に相当する CELL を削除
    if (!confirm("この項目を削除すると、すべてのカルテの「" + label + "」データも削除されます"))
        return;
    
    var array = new Array();
    for (num in _list){
        var cell = _list[num];
        if (cell.tag != tag)
            array.push(cell);
    }
    _list = array;
    
    // 登録後の状態を表示
    showFieldList(mode(), _list);
    
    if (confirm("【 重要につき再確認 】すべてのカルテから「" + currentUser() + "」所属「" + label + "」の全データを削除していいですか")){
        // UniversalSection から owner, tag の全レコードを削除
        NRRemoveRecordsForTag(currentUser(), tag, removedRecordsForTag);
    }
}

////////////////////////////////////////////////////////
///// DRAG and DROP ////////////////////////////////////

function f_dragstart(event){
    // ドラッグ開始時の処理
    // ドラッグするデータのid名をDataTransferオブジェクトにセット
    event.dataTransfer.setData("text", event.target.id);
}

function f_dragover(event){
    // ドラッグ要素がドロップ要素に重なっている間の処理
    //　dragoverイベントをキャンセルして、ドロップ先の要素がドロップを受け付けるようにする
    event.preventDefault();
}

function f_drop(event){
    // ドロップ時の処理
    // ドラッグされたデータのid名をDataTransferオブジェクトから取得
    var id_name = event.dataTransfer.getData("text");
    
    //id名からドラッグされた要素を取得
    var drag_elm = document.getElementById(id_name);
    
    //ドロップ先にドラッグされた要素を追加
    // event.currentTarget.appendChild(drag_elm);
    moveTo(id_name, event.currentTarget);
    
    //エラー回避のため、ドロップ処理の最後にdropイベントをキャンセルしておく
    event.preventDefault();
}
function moveTo(drop_id, target_node){
    // ドロップされたエレメントをドロップされたターゲット・エレメント位置へ移動
    var target_id = target_node.id;
    if (drop_id == target_node.id) return; // 自分自身は無視
    
    // ドロップするオブジェクトを抜かした配列を生成
    var dropRec;
    var anArray = new Array();
    var records = layoutArray(mode());
    for (num in records){
        var rec = records[num];
        if (rec.tag == drop_id){
            dropRec = rec; // ドロップすべきオブジェクトを記憶
            continue;
        }
        
        anArray.push(rec);
    }
    
    // ドロップすべきオブジェクトをドロップする位置に挿入した配列を生成
    var newRecords = new Array();
    for (num in anArray){
        var rec = anArray[num];
        if (rec.tag == target_node.id)
            newRecords.push(dropRec);
        newRecords.push(rec);
    }
    
    // レイアウトの mode() に該当する部分だけを newRecords 要素と置換
    setLayoutForMode(newRecords, mode());
    
    // レイアウトを再表示
    showFieldList(mode());
}

///// DRAG and DROP ////////////////////////////////////
////////////////////////////////////////////////////////

function showFieldList(mode, records){
    // 基本情報のカスタマイズ画面を開く
    // 画面スイッチ・アンカー
    setMode(mode);
    showSwitchUnchor(mode);

    // フィールド・リスト
	var div = document.getElementById("body");
    div.innerHTML = "";
    var tbl = newTABLE(div, "base-table");
    tbl.style.fontSize = "8pt";
    tbl.style.backgroundColor = "#ffc";
    
    // タイトルを表示
    var tr = newTR(tbl, "", "");
    tr.style.backgroundColor = "#ec9";
    tr.style.borderTop = "thin solid #bbb";
    var td = newTD(tr, "", "表示");
    td.style.paddingTop = "10px";
    var td = newTD(tr, "", "固定");
    td.style.paddingTop = "10px";
    var td = newTD(tr, "", "タグ");
    td.style.paddingTop = "10px";
    var td = newTD(tr, "", "ラベル");
    td.style.paddingTop = "10px";

    if (!records)
        records = layoutArray(mode);
    
    _initDebug(false); //##
    _debug("=== showFieldList ==="); //##
    _debug(mode+" showFieldList->"+encodeObject(records)); //##
    
    // ラベルのリストを表示
    _list = new Array();
    var num = 0;
    for (tag in records){
        var rec = records[tag];

        _debug(tag+"->"+encodeObject(rec)); //##

        rec.owner = currentUser();
        rec.id = mode; // mode を判定するために使う
        rec.lid = num++; // layout 編集に使うための ID
        _list.push(rec);
        
        var tr = newTR(tbl, "", "");
        tr.style.borderBottom = "thin solid #bbb";
       
        // 表示
        var td = newTD(tr, "", "");
        td.style.width = "20px";
        var status = (rec && rec.hitAndRun * 1) ? 0 : 1;
        var cb = newCHECKBOX(td, "", "", status);
        cb.setAttribute("onchange", "checkedBox(this,'"+rec.lid+"')");

        // 固定：read-only
        var td = newTD(tr, "", "");
        td.style.width = "20px";
        var status = (rec && rec.disabled * 1) ? 1 : 0;
        var cb = newCHECKBOX(td, "", "", status);
        cb.setAttribute("onchange", "checkedBox2(this,'"+rec.lid+"')");
        
        // タグ
        var td = newTD(tr, rec.tag, rec.tag);
        td.setAttribute("draggable", "true"); // HTML5: ドラッグ可能にする
        td.setAttribute("ondragstart", "f_dragstart(event)");
        td.setAttribute("ondragover", "f_dragover(event)");
        td.setAttribute("ondrop", "f_drop(event)");

        // ラベル
        var td = newTD(tr, "", "");
        var fd = newFIELD(td, "", "", 10, (rec && rec.label) ? rec.label : "");
        fd.setAttribute("onchange", "labelChanged(this,'"+rec.lid+"')");

        // 削除アイコン
        if (rec.tag.indexOf("UniversalSection") >= 0){
            var sp = newSPAN(td, rec.tag);
            sp.style.paddingLeft = "5px";
            sp.style.paddingRight = "10px";
            setInfoTip(rec.tag, "この行を削除"); // HELP
            var img = newIMAGE(sp, "", "./remove-field.png", "X");
            img.style.height = "12px";
            img.setAttribute("onclick", "removeCell('" + rec.tag + "','" + rec.label + "')");
        }

    }

    if (mode == _insurance){
        var msg = "保険情報は専用エディターで扱われるので編集不要です";
        showFadeoutInfo("_debug", msg, 2000);
    } else {
        // 追加ボタンを生成
        showAddFieldButton(tbl, rec.lid+1);
    }


    
    function showSwitchUnchor(mode){
        // 画面スイッチするボタンを表示
        var elm = document.getElementById("unchorArea");
        elm.innerHTML = "";
        
        // 診療アンカー
        var dv = newDIV(elm, "");
        dv.innerHTML = "診療"
        dv.setAttribute("onclick", "showFieldList('" + _progress + "')");
        if (mode == "P"){
            dv.setAttribute("class", "white-tab");
        } else {
            dv.setAttribute("class", "gray-tab");
        }
        
        // 基本アンカー
        var dv = newDIV(elm, "");
        dv.innerHTML = "基本"
        dv.setAttribute("onclick", "showFieldList('" + _basic + "')");
        if (mode == "B"){
            dv.setAttribute("class", "white-tab");
        } else {
            dv.setAttribute("class", "gray-tab");
        }
        
        // 保険アンカー
        var dv = newDIV(elm, "");
        dv.innerHTML = "保険"
        dv.setAttribute("onclick", "showFieldList('" + _insurance + "')");
        if (mode == "I"){
            dv.setAttribute("class", "white-tab");
        } else {
            dv.setAttribute("class", "gray-tab");
        }
    }
}

function layoutHelp(){
    // HELP を開く
	window.open("./layoutHelp.html","Help"
				,"width=450,height=700,scrollbars=yes,resizable=yes");
}

function openLayoutPanel(){
	var elm = document.getElementById("base");
    elm.innerHTML = "";
    
	// === HEADER ===
    var div = newDIV(elm, "yellow-bar");
    div.style.height = "25px";
	var tbl = newTABLE(div, "base-table");
    tbl.style.fontSize = "9pt";
	var tr = newTR(tbl, "", "");
    // --- LEFT SIDE ---
	var td = newTD(tr, "", "");
    // アンカー・エリア
    var sp = newSPAN(td, "unchorArea");
    // --- RIGHT SIDE ---
	var td = newTD(tr, "right-side", "");
    td.style.with = "20px";
    td.style.paddingRight = "20px";
    // HELP ICON
	var img = newIMAGE(td, "", "./Help.png", "?");
	img.style.height = "18px";
    img.setAttribute("onclick", "layoutHelp()");
    
	// === BODY ===
    var div = newDIV(elm, "body");
    
	// === FOOTER ===
    var div = newDIV(elm, "yellow-bar");
	var tbl = newTABLE(div, "base-table");
    tbl.style.fontSize = "9pt";
	var tr = newTR(tbl, "titleBar", "");
    // --- LEFT SIDE ---
	var td = newTD(tr, "left-side", "");
    // --- RIGHT SIDE ---
	var td = newTD(tr, "right-side", "");
    td.style.paddingRight = "20px";
    var sp = newSPAN(td, "tip-right");
    sp.innerHTML = userKanjiName() + " のレイアウトを";
    var sp = newSPAN(td, "");
    var bt = newBUTTON(sp, "", "保存");
    bt.setAttribute("onclick", "saveLayout()");
    var sp = newSPAN(td, "tip-left");
    var a = newA(sp, "バックアップ", "#", "");
    a.setAttribute("onclick", "getLayoutArchives()");
        
	// === WORK AREA ===
    var div = newDIV(elm, "workArea");

    // ProgressSection を表示
    showFieldList(_progress);
}

function initLayout(){
    // 初期設定パネルを開く前にユーザ・セレクターで対象ユーザを特定
    var elm = document.getElementById("base");
    elm.innerHTML = "";

    var div = newDIV(elm, "yellow-bar");
    div.style.height = "25px";
    div.style.fontSize = "9pt";
    div.style.paddingLeft = "20px";
    
    // ユーザ名選択ポップアップ
    var owner = noa().owner();
    var kanjiName = noa().userKanjiName(owner);
    var pu = makePopupMenu(div, "userPop", noa().userKanjiNames(), kanjiName);
    
    var sp = newSPAN(div, "tip-left");
    sp.innerHTML = "のレイアウトを";

    // LOAD BUTTON
    var bt = newBUTTON(div, "", " 読 込 ");
    bt.setAttribute("onclick", "getPreference()");
}
