
function modeMenus(){
    return ["予定表" ,"日計表"]; // 月計表が初期値であることはない
}

function layoutChecks(){
    // レイアウト属性のチェックボックスの id とラベル名の対応
    var obj = new Object();
    
    obj.inOutBox = "入院・外来表示";
    obj.acceptanceBox = "患者受付";
    obj.totalBox = "合計を表示";
    obj.averageBox = "平均値を表示";
    obj.monthlyBox = "他日も表示";
    obj.insImageBox = "保険証画像を編集可とする";
    obj.dateTimeBox = "日時指定受付";
    obj.planBox = "予定表";
    obj.hasMonthlyBox = "月計表示"; // 予約ツールより後に置く
    obj.visitorBox = "今月の受診者リスト";

    return obj;
}
function layoutChecksTemplate(){
    var array = new Array();
    var obj = layoutChecks();
    for (alias in obj){
        var label = obj[alias];
        array.push(label);
    }
    return array.join(",");
}

function planItems(){
    // 予定表の項目名リスト
    var array = new Array();
    array["予約"] = newObj("reserved", "予約", "");
    array["受付"] = newObj("entry", "受付", "");
    array["カルテID"] = newObj("patientId", "カルテID", "");
    array["氏名"] = newObj("name", "氏名", "");
    array["実施計画"] = newObj("plan", "実施計画", "");
    array["伝達"] = newObj("message", "伝達", "");
    array["診療待"] = newObj("wait", "診療待", "numeric");
    array["会計待"] = newObj("allWait", "会計待", "numeric");
    array["閲覧"] = newObj("viewer","閲覧", "");
    array["合計"] = newObj("total","合計", "numeric", 1);
    array["保険証確認"] = newObj("image", "保険証確認", "");
    array["修正"] = newObj("edit","修正", "center", 1);
    return array;
}
function planTemplate(){
    var array = new Array();
    var obj = planItems();
    for (alias in obj){
        var rec = obj[alias];
        if (rec.disabled) continue;
        
        array.push(rec.label);
    }
    return array.join(",");
}

function daylyItems(){
    // 日計表の項目名リスト
    // default の日計表構成を規定
    var array = new Array();
    array["予約"] = newObj("reserved", "予約", "");
    array["受付"] = newObj("entry", "受付", "");
    array["カルテID"] = newObj("patientId","カルテID", "");
    array["another ID"] = newObj("anotherId","another ID", "");
    array["氏名"] = newObj("name","氏名", "strings");
    array["新患"] = newObj("newPatient","新患", "numeric", 1);
    array["伝達"] = newObj("message", "伝達", "");
    array["本人"] = newObj("honin","本人", "numeric");
    array["家族"] = newObj("kazoku","家族", "numeric");
    array["国保"] = newObj("kokuho","国保", "numeric");
    array["点数"] = newObj("point","点数", "numeric");
    array["自費"] = newObj("ownFee","自費", "numeric");
    array["合計"] = newObj("total","合計", "numeric");
    array["修正"] = newObj("edit","修正", "center", 1);
    array["閲覧"] = newObj("viewer","閲覧", "");
    array["診療待"] = newObj("wait","診療待", "numeric");
    array["会計待"] = newObj("allWait","会計待", "numeric");
    array["終了"] = newObj("finish","終了", "");
    //array["記録"] = newObj("user","記録", "strings");
    array["会計"] = newObj("bill","会計", "center");
    array["受取"] = newObj("receive","受取", "numeric");
    array["釣銭"] = newObj("change","釣銭", "numeric");
    array["未収"] = newObj("mishuu","未収", "numeric");
    return array;
}
function dayTemplate(){
    var array = new Array();
    var obj = daylyItems();
    for (alias in obj){
        var rec = obj[alias];
        if (rec.disabled) continue;
        
        array.push(rec.label);
    }
    return array.join(",");
}

function monthlyItems(){
    // 月計表の項目名リスト
    var array = new Array();
    array["日付"] = newObj("entry", "日付", "");
//    array["日付"] = newObj("entry", "年月日", "");
    array["人数"] = newObj("count","人数", "numeric");
    array["新患"] = newObj("newPatient","新患", "numeric");
    array["本人"] = newObj("honin","本人", "numeric");
    array["家族"] = newObj("kazoku","家族", "numeric");
    array["国保"] = newObj("kokuho","国保", "numeric");
    array["点数"] = newObj("point","点数", "numeric");
    array["自費"] = newObj("ownFee","自費", "numeric");
    array["合計"] = newObj("total","合計", "numeric");
    array["未収"] = newObj("mishuu","未収", "numeric");
    return array;
}
function monthTemplate(){
    var array = new Array();
    var obj = monthlyItems();
    for (alias in obj){
        var rec = obj[alias];
        if (rec.disabled) continue;
        
        array.push(rec.label);
    }
    return array.join(",");
}

function newObj(id, label, type, status){
	var obj = new Object();
	obj.id = id;
	obj.label = label;
	obj.type = type;
	obj.disabled = status;
	return obj;
}

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


////////////////////////////////////////////////////
/// Ajax による処理 //////////////////////////////////

function savedPreference(answer){
    //alert("savedPreference->"+answer); //##
    
    closeFloatPanel();
    
    // currentUser() の初期設定を再読み込みし FRONT を再表示
    window.location.reload(true);
}
function savePreference(){
    // 初期設定全般をサーバへ保存
    var args = new Object();
    args["owner"] = currentUser(); // ユーザごとの設定を保存
    args["checkBox"] = encodeSTRING(checkStrings());
    var item = document.getElementById("firstPopItem").value;
    args["firstItem"] = encodeSTRING(item);
    args["plan"] = encodeSTRING(planStrings());
    args["day"] = encodeSTRING(dayStrings());
    args["month"] = encodeSTRING(monthStrings());
    
	_callServer("PUT_LAYOUT_PARTS", "frontServer.php", args, savedPreference);
}

function getPreference(){
    // currentUser() のユーザのレイアウト設定を読み込む
    var kanjiName = document.getElementById("userPop").value;
    setCurrentUser(lognameForKanji(kanjiName));
    
    showPreference();
}

/// Ajax による処理 //////////////////////////////////
////////////////////////////////////////////////////



function makeHeaderParts(td){
    // ヘッダーに表示するパーツを生成
    var array = controls();
    
    var inOut = hasMember(array, "入院・外来表示");
    var hasMonthlyMode = hasMember(array, "月計表示");
    var acceptance = hasMember(array, "患者受付");
    var total = hasMember(array, "合計を表示");
    var average = hasMember(array, "平均値を表示");
    
    var div = newDIV(td, "/clearfix");
    // === LEFT SIDE =====
    var dv = newDIV(div, "/left-side");
    dv.style.paddingLeft = "0";
    dv.style.width = "90%";
    var cb = newCHECKBOX(dv, "inOutBox", "入院・外来表示", inOut);
    var cb = newCHECKBOX(dv, "hasMonthlyBox", "月計表示", hasMonthlyMode);
    var cb = newCHECKBOX(dv, "acceptanceBox", "患者受付", acceptance);
    var cb = newCHECKBOX(dv, "totalBox", "合計を表示", total);
    var cb = newCHECKBOX(dv, "averageBox", "平均値を表示", average);
}
function checkStrings(){
    // チェックボックスの属性
    var array = new Array();
    var obj = layoutChecks();
    for (alias in obj){
        var label = obj[alias];
        var elm = document.getElementById(alias);
        if (elm && elm.checked) array.push(label);
    }
    return array.join(",");
}

function makeModeMenu(td){
    // モード・メニュー設定ペーンを生成
    var array = controls();
    var item = (firstItem()) ? firstItem() : "";
    
    var div = newDIV(td, "");
    var monthly = hasMember(array, "他日も表示"); // lib.js
    var cb = newCHECKBOX(div, "monthlyBox", "他日も表示", monthly);
    var planTool = hasMember(array, "予定表"); // lib.js
    var cb = newCHECKBOX(div, "planBox", "予定表", planTool);
    var insImage = hasMember(array, "保険証画像を編集可とする"); // lib.js
    var cb = newCHECKBOX(div, "insImageBox", "保険証画像を編集可とする", insImage);
    var sp = newSPAN(div, "");
    sp.innerHTML = "初期表示項目";
    sp.style.paddingLeft = "15px";
    var pm = newPopupMenu(div, "firstPopItem", modeMenus(), item);
}

function makeTools(td){
    // 道具メニューに表示する項目を生成
    var array = controls();
    var dateTime = hasMember(array, "日時指定受付"); // lib.js
    var visitor = hasMember(array, "今月の受診者リスト");
    
    var div = newDIV(td, "");
    var cb = newCHECKBOX(div, "dateTimeBox", "日時指定受付", dateTime);
    var cb = newCHECKBOX(div, "visitorBox", "今月の受診者リスト", visitor);
}

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

function _isChecked(id){
    // elm の子供の checkBox の status を返す
    var elm = document.getElementById(id);
    return document.getElementById(elm.childNodes[0].id).checked;
}
function isChecked(label, mode){
    // elm の子供の checkBox の status を返す
    switch (mode * 1){
        case _isPlan: return document.getElementById(label + ".planBox").checked;
        case _isDaily: return document.getElementById(label + ".dayBox").checked;
        case _isMonthly: return document.getElementById(label + ".monthBox").checked;
        default: return true;
    }
}

function suffix(id){
    // "氏名.p" から "p" を返す
    var array = id.split(".");
    if (array.length > 1)
        return array[1];
    else
        return "";
}

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

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

function f_drop(event, mode){
    // ドロップ時の処理
    // ドラッグされたデータの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, mode);
    
    //エラー回避のため、ドロップ処理の最後にdropイベントをキャンセルしておく
    event.preventDefault();
}
function moveTo(drop_id, target_node, mode){
    // ドロップされたエレメントをドロップされたターゲット・エレメント位置へ移動
    var target_id = target_node.id;
    var mySuffix = suffix(target_id);
    if (suffix(drop_id) != mySuffix) return; // 同類同志でなければ無視
    if (drop_id == target_node.id) return; // 自分自身は無視

    // target_id の兄弟 node の配列を生成
    var array = new Array();
    var children = target_node.parentNode.childNodes;
    for (num in children){
        var node = children[num];
        if (!node.id) continue;
        if (node.id == drop_id) continue;
        
        // 移動する node を抜いた node の配列を生成
        array.push(node.id);
    }
    //alert("->"+encodeObject(array)); //##

    // drop_id の位置と target_id の位置をスワップ
    // 順序入れ替え操作はチェックの有無にとらわれず実施する必要あり
    for (num in array){
        var id = array[num]; // id は "氏名.p" 型式
        
        // target_node.id の位置に drop_id node を挿入
        if (id == target_node.id){
            array.splice(num, 0, drop_id);
            break;
        }
    }
    //alert("swapped->"+encodeObject(array)); //##
    
    // チェックの入ったものだけを配列にとりこむ
    var newArray = new Array();
    for (num in array){
        var id = array[num]; // id は "氏名.p" 型式
        var ary = id.split(".");
        var label = ary[0];

        if (isChecked(label, mode)){
            // id の checkBox にチェックが入っていれば登録
            newArray.push(label);
        }
    }
    //alert("checked->"+mode+"->"+encodeObject(newArray)); //##
    
    // 生成された array の順番で parentNode の子供を再描画
    // チェックの入っていないものは最後にまとめて表示される
    switch (mode * 1){
        case _isPlan:
            var elm = document.getElementById("planParent");
            elm.innerHTML = "";
            makePlan(elm, newArray);
            break;
        case _isMonthly:
            var elm = document.getElementById("monthParent");
            elm.innerHTML = "";
            makeMonthly(elm, newArray);
            break;
        default:
            var elm = document.getElementById("dayParent");
            elm.innerHTML = "";
            makeDaily(elm, newArray);
            break;
    }
}

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

var _planArray;
function makePlan(td, layoutArray){
    // 予定表レイアウトを layoutArray の順番で生成
    //alert("makePlan layoutArray->"+encodeObject(layoutArray)); //##
    td.innerHTML = "";
    var tbl = newTABLE(td, ""); // 巾は任意のまま
    tbl.style.fontSize = "9pt";
    var tr = newTR(tbl, "", "");

    // layoutArray にあるものをチェックされた checkBox として生成
    // layoutArray の順番で生成される
    _planArray = new Array();
    for (num in layoutArray){
        var label = layoutArray[num];
        var td = newTD(tr, "", "");
        td.style.margin = "0px 0px";
        td.style.padding = "0px 0px";
        td.setAttribute("id", label + ".p");
        td.setAttribute("draggable", "true"); // HTML5: ドラッグ可能にする
        td.setAttribute("ondragstart", "f_dragstart(event)");
        td.setAttribute("ondragover", "f_dragover(event)");
        td.setAttribute("ondrop", "f_drop(event,'" + _isPlan + "')");
        var cb = newCHECKBOX(td, label + ".planBox", label, 1);
        
        _planArray.push(label);
    }
    //alert("makePlan checked ->"+encodeObject(_planArray)); //##
   
    // layoutArray になかったものをチェックなしの checkBox として生成
    // planItems() の順番で生成される
    var planObj = planItems();
    for (alias in planObj){
        var rec = planObj[alias];

        if (hasMember(layoutArray, rec.label)) continue;
        
        var td = newTD(tr, "", "");
        td.style.margin = "0px 0px";
        td.style.padding = "0px 0px";
        td.setAttribute("id", rec.label + ".p");
        td.setAttribute("draggable", "true"); // HTML5: ドラッグ可能にする
        td.setAttribute("ondragstart", "f_dragstart(event)");
        td.setAttribute("ondragover", "f_dragover(event)");
        td.setAttribute("ondrop", "f_drop(event,'" + _isPlan + "')");
        var status = 0; // (rec.disabled) ? 0 : 1;
        var cb = newCHECKBOX(td, rec.label + ".planBox", rec.label, status);

        _planArray.push(rec.label);
    }
    //alert("makePlan-->"+encodeObject(_planArray)); //##
}
function planStrings(){
    // 予定表の設定を文字列："受付,カルテID,氏名" 形式にして返す
    if (!_planArray) _planArray = planArray();
    
    //alert("planStrings==>"+encodeObject(_planArray)); //##
    
    var array = new Array();
    for (num in _planArray){
        var label = _planArray[num];
        
        // チェックボックスにチェックされたもののみを planString() に取り込む
        var box = document.getElementById(label + ".planBox");
        if (box.checked) array.push(label);
    }
    
    return array.join(",");
}

var _dayArray;
function makeDaily(td, layoutArray){
    // 日計表レイアウト設定
    //alert("makeDaily layoutArray ==>"+encodeObject(layoutArray)); //##
    
    td.innerHTML = "";
    var tbl = newTABLE(td, ""); // 巾は任意のまま
    tbl.style.fontSize = "9pt";
    var tr = newTR(tbl, "", "");
    
    // layoutArray にあるものをチェックされた checkBox として生成
    // layoutArray の順番で生成される
    _dayArray = new Array();
    for (num in layoutArray){
        var label = layoutArray[num];
        var td = newTD(tr, "", "");
        td.style.margin = "0px 0px";
        td.style.padding = "0px 0px";
        td.setAttribute("id", label + ".d");
        td.setAttribute("draggable", "true"); // HTML5: ドラッグ可能にする
        td.setAttribute("ondragstart", "f_dragstart(event)");
        td.setAttribute("ondragover", "f_dragover(event)");
        td.setAttribute("ondrop", "f_drop(event,'" + _isDaily + "')");
        var cb = newCHECKBOX(td, label + ".dayBox", label, 1);
        
        _dayArray.push(label);
    }
    //alert("checked ==>"+encodeObject(_dayArray)); //##
    
    // layoutArray になかったものをチェックなしの checkBox として生成
    var recs = daylyItems();
    for (alias in recs){
        var rec = recs[alias];
        
        if (hasMember(layoutArray, rec.label)) continue;
        
        //alert(rec.layout+"->"+rec.disabled); //##
        
        var td = newTD(tr, "", "");
        td.style.margin = "0px 0px";
        td.style.padding = "0px 0px";
        td.setAttribute("id", rec.label + ".d");
        td.setAttribute("draggable", "true"); // HTML5: ドラッグ可能にする
        td.setAttribute("ondragstart", "f_dragstart(event)");
        td.setAttribute("ondragover", "f_dragover(event)");
        td.setAttribute("ondrop", "f_drop(event,'" + _isDaily + "')");
        var status = 0; // (rec.disabled) ? 0 : 1;
        var cb = newCHECKBOX(td, rec.label + ".dayBox", rec.label, status);
        
        _dayArray.push(rec.label);
    }
    //alert("terminate ==>"+encodeObject(_dayArray)); //##
}
function dayStrings(){
    // 日計表の設定を文字列にして返す
    // "受付,カルテID,氏名" 形式
    if (!_dayArray) _dayArray = dayArray();

    var array = new Array();
    for (num in _dayArray){
        var label = _dayArray[num];

        // チェックボックスにチェックされたもののみを planString() に取り込む
        var box = document.getElementById(label + ".dayBox");
        if (box.checked) array.push(label);
    }
    return array.join(",");
}

var _monthArray;
function makeMonthly(td, layoutArray){
    // 月計表レイアウト設定
    td.innerHTML = "";
    var tbl = newTABLE(td, ""); // 巾は任意のまま
    tbl.style.fontSize = "9pt";
    var tr = newTR(tbl, "", "");
    
    // layoutArray にあるものをチェックされた checkBox として生成
    _monthArray = new Array();
    for (num in layoutArray){
        var label = layoutArray[num];
        var td = newTD(tr, "", "");
        td.style.margin = "0px 0px";
        td.style.padding = "0px 0px";
        td.setAttribute("id", label + ".m");
        td.setAttribute("draggable", "true"); // HTML5: ドラッグ可能にする
        td.setAttribute("ondragstart", "f_dragstart(event)");
        td.setAttribute("ondragover", "f_dragover(event)");
        td.setAttribute("ondrop", "f_drop(event,'" + _isMonthly + "')");
        var cb = newCHECKBOX(td, label + ".monthBox", label, 1);
        
        _monthArray.push(label);
    }
    
    // layoutArray になかったものをチェックなしの checkBox として生成
    var recs = monthlyItems();
    for (alias in recs){
        var rec = recs[alias];
        
        if (hasMember(layoutArray, rec.label)) continue;
        
        var td = newTD(tr, "", "");
        td.style.margin = "0px 0px";
        td.style.padding = "0px 0px";
        td.setAttribute("id", rec.label + ".m");
        td.setAttribute("draggable", "true"); // HTML5: ドラッグ可能にする
        td.setAttribute("ondragstart", "f_dragstart(event)");
        td.setAttribute("ondragover", "f_dragover(event)");
        td.setAttribute("ondrop", "f_drop(event,'" + _isMonthly + "')");
        var status = 0; // (rec.disabled) ? 0 : 1;
        var cb = newCHECKBOX(td, rec.label + ".monthBox", rec.label, status);
        
        _monthArray.push(rec.label);
    }
}
function monthStrings(){
    // 月計表の設定を文字列にして返す
    // "年月日,人数,合計" 形式
    if (!_monthArray) _monthArray = monthArray();
    
    //alert("monthStrings->"+encodeObject(_monthArray)); //##
    
    var array = new Array();
    for (num in _monthArray){
        var label = _monthArray[num];

        // チェックボックスにチェックされたもののみを planString() に取り込む
        var box = document.getElementById(label + ".monthBox");
        if (box.checked) array.push(label);
    }
    return array.join(",");
}

function prefHelp(){
	window.open("./frontPrefHelp.html","Help"
				,"width=450,height=700,scrollbars=yes,resizable=yes");
}

function showPreference(){
    // 初期設定パネルを開く
    var elm = document.getElementById("contentsArea");
    elm.innerHTML = "";

	var tbl = newTABLE(elm, "");
	tbl.style.fontSize = "10pt";
	tbl.style.width = "100%";
    
    // ヘッダー・ツールの設定
    var tr = newTR(tbl, "", "");
    var td = newTD(tr, "/prefLabel", "表示する部品");
    var td = newTD(tr, "/prefVal", "");
    makeHeaderParts(td);
   
    // モード・メニューの設定
    var tr = newTR(tbl, "prefTR", "");
    var td = newTD(tr, "/prefLabel", "帳票メニュー");
    var td = newTD(tr, "/prefVal", "");
    makeModeMenu(td);
 
    // 道具メニューの設定
    var tr = newTR(tbl, "", "");
    var td = newTD(tr, "/prefLabel", "道具メニュー");
    var td = newTD(tr, "/prefVal", "");
    makeTools(td);

    // 予定表レイアウト設定
    var tr = newTR(tbl, "", "");
    var td = newTD(tr, "/prefLabel", "予定表");
    var td = newTD(tr, "planParent/prefVal", "");
    makePlan(td, planArray());

    // 日計表レイアウト設定
    var tr = newTR(tbl, "", "");
    var td = newTD(tr, "/prefLabel", "日計表");
    var td = newTD(tr, "dayParent/prefVal", "");
    td.style.paddingRight = "10px";
    makeDaily(td, dayArray());

    // 月計表レイアウト設定
    var tr = newTR(tbl, "", "");
    var td = newTD(tr, "/prefLabel", "月計表");
    var td = newTD(tr, "monthParent/prefVal", "");
    td.style.paddingRight = "10px";
    makeMonthly(td, monthArray());
    
    // 表のレイアウト設定
    var div = newDIV(elm, "/clearfix");
    div.style.fontSize = "9pt";
    var dv = newDIV(div, "/left-side");
    var kanjiName = userKanjiNameOf(currentUser());
    dv.innerHTML = kanjiName + " の FRONT レイアウト";
    dv.style.width = "400px";
    dv.style.paddingTop = "5px";
    var dv = newDIV(div, "/right-side");
    // BACK UP
    var sp = newSPAN(dv, "tipLeft");
    sp.style.paddingRight = "15px";
    sp.style.position = "relative";
    sp.style.top = "3px";
    var a = newA(sp, "バックアップ", "#", "");
    a.setAttribute("onclick", "getBackup()");
    // SAVE BUTTON
    var bt = newDIV(dv, "/fixButton");
    bt.innerHTML = "保存";
    bt.setAttribute("onclick", "savePreference()");
    
    // バックアップ・ペーン
    var div = newDIV(elm, "backupPane");
}

function openPreference(){
    // 初期設定パネルを開く前にユーザ・セレクターで対象ユーザを特定
    var w = 900;
	var x = 50; // 表示するx座標
	var y = 100; // 表示するy座標
    var title = "レイアウト初期設定";
    var elm = openSeeThroughPanel("_floatPanel", x, y, w, title, "prefHelp()");
    if (!elm){
        alert("_floatPanel がないのでパネルを表示できません"); return;
    }
    elm.style.padding = "5px";
    var div = newDIV(elm, "contentsArea");
    // ユーザ選択ポップアップメニュー
    var kanjiName = userKanjiNameOf(owner());
    var pu = newPopupMenu(div, "userPop", userNames(), kanjiName);
    var sp = newSPAN(div, "");
    sp.innerHTML = "のレイアウトを";
    sp.style.fontSize = "9pt";
    sp.style.padding = "0 3px";
    // LOAD BUTTON
    var bt = newDIV(div, "/whiteButton");
    bt.innerHTML = "読込";
    bt.setAttribute("onclick", "getPreference()");
}
