
/////
///// 患者ごとの記述を司るクラス
/////

///// 以下のパラメータは chart.js でしか使わないので dataCentar.js には収容しない

var _addPageDateTime;
function setAddPageDateTime(dateTime){
    _addPageDateTime = dateTime;
}
function addPageDateTime(){
    // ページ追加すべき日時を返す
    return _addPageDateTime;
}

var _isReserved;
function setIsReserved(status){
    _isReserved = status;
}
function isReserved(){
    // 予約ページであるか否かを返す
    return _isReserved;
}

function editorElementForTag(tag){
    // tag に相当する 入力欄 エレメントを返す
    var elm = window.top.noa.document.getElementById(tag + ".value");
    if (elm)
        return elm;
    else
        return window.top.tools.document.getElementById(tag + ".value");
}

function valueElementForTag(dateTime, tag){
    // dateTime, tag に相当する 値表示欄 エレメントを返す
    var elm = window.top.noa.document.getElementById(dateTime+"."+tag+".val");
    if (elm)
        return elm;
    else
        return window.top.tools.document.getElementById(dateTime+"."+tag+".val");
}



//////////////////////////////////////////////
///// マルチスレッド ////////////////////////////

function WKGetPage(owner, patientId, dateTime){
    // WK で始まる関数名は multi thread
    // Worker を使いマルチスレッドで 基本情報ページを更新
    // DB とのやりとりは getPageWorker.js で設定
    _debug("== WKGetPage"); //##
    
    var obj = new Object();
    obj["owner"] = owner;
    obj["patientId"] = patientId;
    obj["dateTime"] = dateTime;
    var noaString = encodeObject(obj);
    _debug("noaString->"+noaString); //##
    
    var worker = new Worker('./getPageWorker.js');
    worker.postMessage(noaString); // ### worker に命令書 noaString を送る ###
    
    worker.onmessage = function (event) {
        // ### worker の処理したデータを受け取る ###
        var answer = event.data; // ### worker からの返答 ###
        //document.getElementById("alertArea").innerHTML = answer;

        openBasicPage(answer);
    }
}

///// マルチスレッド ////////////////////////////
//////////////////////////////////////////////

///////////////////////////////////////////////////////
///// PAGE ////////////////////////////////////////////

function removedPage(answer){
    // ページ削除を画面に反映させる
    openChart(patientId());
}
function removePage(dateTime){
    // dateTime のページを削除
	if (userCode() != "all"){
		alert("アクセス・コード: "+userCode()+" なのでページ削除権限がありません");
	} else if (confirm(dateTime + " のページを削除しますか")){
		setCurrentDate("");
        var args = new Object();
        args["owner"] = owner();
		args["patientId"] = patientId();
		args["entryDate"] = dateTime;
		args["timeLimit"] = timeLimit();

        NRCall("REMOVE_PAGE", args, removedPage);
	}
}
function removeTodayPage(){
    // レッド・マイナス・アイコンから起動される
    removePage(currentDate());
}

function addedPage(answer){
    // 新規ページを追加
    openChart(patientId()); // ### old NOA ###
}
function addPage(dateTime){
    // dateTime の新規ページを追加
    _debug("== addPage"); //##
    _debug("dateTime->"+dateTime); //##

    if (!patientId()){
        alert("カルテが読込まれていません");
    } else if (userCode() != "all"){
		// アクセスコード４（参照・修正・削除許可）以外ならページ追加をしない
		alert("アクセス・コード: "+userCode()+" なので新規ページ追加権限がありません");
    } else if (isSameDate(dateTime, currentDate())){
		// 同じ日付のページがすでに存在する
		if (confirm(dateTime + " と同じ日付のページ（ "+currentDate()+" ）はすでにあります。同日再診として追加しますか？")){
            add_page(dateTime);
		}
	} else {
		// dateTime のページが存在しなかった
		if (isSameDate(dateTime, today())){
			// dateTime が本日なら、新規ページを追加
            add_page(dateTime);
		} else {
			// dateTime が本日ではなかった
			if (confirm(dateTime + " は本日ではありません。追加しますか？")){
                add_page(dateTime);
			}
		}
	}

    
    function add_page(dateTime){
        // dateTime のページを追加
        //_initDebug(true); //##
        _debug("== add_page->"+dateTime); //##
        
        setCurrentDate(dateTime);
        
        var templateTitle = newPageTemplate(); // localStorage.js
        if (templateTitle){
            // ページ・テンプレートを反映したページを追加
            addPageWithTemplate(templateTitle);
        } else {
            // 白紙のページを追加
            var pid = patientId();
            var container = new Array();
            
            put_page(owner(), pid, dateTime, timeLimit(), container, addedPage);
        }
    }
}

var _templateTitle;
function addPageWithTemplateDone(answer){
    // ページ・テンプレートを反映したページを追加
    var array = JSON.parse(answer);
    setTemplateMenu(array);
    
    addPageWithTemplate(_templateTitle);
}
function addPageWithTemplate(templateTitle){
    // ページ・テンプレートを反映したページを追加
    // すでにページ・テンプレートが記憶されていればサーバへ取りに行かない
    var obj = groupTemplateObjectForTitle(templateTitle);
    if (obj && obj.value){
        // obj.value に tag 毎にセットする値が入っている
        var dateTime = currentDate();
        var val = transferToCR(obj.value); // HTML 改行を全て "\n" に変換
        var container = decodeObject(val);
        put_page(owner(),patientId(),dateTime,timeLimit(),container,addedPage);
    } else {
        _templateTitle = templateTitle;
        
        var args = new Object();
        args["owner"] = owner();
        NRCall("GET_MENU_TEMPLATE", args, addPageWithTemplateDone);
    }
}

function addTodayPage(){
    // グリーン・プラス・アイコンから起動される
    openAddPagePanel(todayAndTime());
}

///// PAGE ////////////////////////////////////////////
///////////////////////////////////////////////////////


function showReadWriteMarker(elm, isActive, dateTime){
    // ページの読書状態を表すコントローラ表示
    elm.innerHTML = "";
    if (isActive){
        if (isSameDate(dateTime, today())){
            // 本日なら無条件に readOnly を否定
            setIsReadOnly(false, dateTime);
        } else {
            // 本日以外なら setIsReadOnly() の判断に任せる
            setIsReadOnly(isReadOnly(), dateTime);
            var bid = "pageReadOnlyStatus";
            var sp = newSPAN(elm, bid);
            if (isReadOnly())
                var bt = newOffButton(bid, "編集可/編集不可", "getOnOff");
            else
                var bt = newOnButton(bid, "編集可/編集不可", "getOnOff");
        }
    }
}

function showPageIcons(elm, isActive){
    // ページ・ヘッダーにアイコン・ギャラリーを表示・非表示
    if (isActive){
        //elm.innerHTML = "ICONS";
        var array = toolMenus();
        for (num in array){
            var cell = array[num];
            
            if (cell.menuType * 1 != _page) continue;
            if (cell.disabled * 1) continue;
            if (cell.subTitle * 1) continue;
            
            // メニュー項目を生成
            var sp = newSPAN(elm, cell.id);
            sp.style.marginLeft = "15px";
            sp.style.fontSize = "10pt";
            // cell.editor に infoTip に表示する内容が入っている
            setInfoTip(cell.id, cell.editor); // HELP
            
            if (cell.icon){
                // ICON があれば ICON を表示
                var img = newIMAGE(sp, "", cell.icon, "icon");
                img.style.height = "15px";
                var action = "kickMenuCell('"+cell.url+"','"+cell.window+"',this)";
                img.setAttribute("onclick", action);
                img.setAttribute("class", "expandIcon");
            } else {
                // アンカー表示
                var a = newA(sp, cell.label, "#", "");
                if (cell.url){
                    var action = "kickMenuCell('"+cell.url+"','"+cell.window+"',this)";
                    a.setAttribute("onclick", action);
                }
            }
        }
    } else {
        elm.innerHTML = "";
    }
}

/////////////////////////////////////////////////////////
///// CAUTION ///////////////////////////////////////////

var _caution;
function setCaution(st){
    _caution = st;
}
function caution(){
    // 注意事項を返す
    return _caution;
}

function allergyString(){
    // アレルギー欄の文字列を返す
    var obj = valueForTag("BasicSection.allergy", currentDate());
    if (!obj) return null;
    var val = obj.value;
    if (trim(val).length == 0) return null;
    if (val == "なし") return null;
    
    return val;
}
function cautionString(){
    // 注意事項の文字列を返す
    var obj = valueForTag("ProgressSection.note", currentDate());
    
    if (!obj) return null;
    var val = obj.value;
    if (trim(val).length == 0) return null;
    
    return val;
}

function showCaution(){
    // アレルギー・注意事項を表示
    var obj = postItForDate(currentDate());
    var hasPostIt = (obj && (obj.type < 2)) ? true : false;
    closePostIt(); // 以前の付箋を一旦消しておく
    if (hasPostIt){
        var div = elmFor(currentDate() + ".postItArea");
        div.innerHTML = "";
        var bt = newDIV(div, "");
        var sp = newSPAN(bt, "");
        
        // 付箋を表示
        sp.innerHTML = "付箋";
        var obj = postItForDate(currentDate());
        switch (obj.color * 1){ // 付箋色により表示
            case 1: sp.setAttribute("class", "postItTagBlue"); break;
            case 2: sp.setAttribute("class", "postItTagYellow"); break;
            case 3: sp.setAttribute("class", "postItTagRed"); break;
            default: sp.setAttribute("class", "postItTagGreen"); break;
        }
        
        // 付箋の位置を移動
        sp.style.position = "relative";
        sp.style.top = "-15px";
        sp.style.left = (noCalendar() > 0) ? "0" : "-30px";

        sp.setAttribute("onclick", "showPostItForce()");
    }
    
    var div = elmFor(currentDate() + ".cautionArea");
    div.innerHTML = "";
    var allergy = (showAllergy()) ? allergyString() : null;
    var caution = cautionString();
    setCaution(caution); // 注意事項を記憶しておく
    if (allergy || caution){
        // ラベル
        var dv = newDIV(div, "/clearfix");
        if (hasPostIt) dv.style.margin = "3px 0px";
        var bt = newDIV(dv, "");
        bt.style.display = "inline";
        bt.style.float = "left";
        bt.style.width = "60px";
        bt.style.fontSize = "10pt";
        bt.style.padding = "0 5px";
        bt.innerHTML = "注意";
        // 内容表示エリア
        var ldiv = newDIV(dv, "");
        ldiv.style.display = "inline";
        ldiv.style.float = "left";
        ldiv.style.fontSize = "11pt";
        // アレルギー
        if (allergy){
            var adiv = newDIV(ldiv, "");
            adiv.innerHTML = allergy;
            adiv.style.color = "#f00";
        }
        // 注意内容
        if (caution){
            var cdiv = newDIV(ldiv, "cautionF");
            cdiv.innerHTML = caution;
            cdiv.style.paddingLeft = "5px";
            cdiv.style.fontSize = "10pt";
            cdiv.contentEditable = true; // TEXT を編集可能状態にする
            //cdiv.setAttribute("onFocus", "alert('set editable')");
            cdiv.setAttribute("onBlur", "saveCaution()");
        }
    }
}

function savedCaution(answer){
    //alert("savedCaution->"+answer); //##
    var obj = JSON.parse(answer);
    var tag = 'ProgressSection.note';
    var note = obj[tag];
    
    // 記憶したデータも更新しておく
    setValueForTag(tag, currentDate(), note);
    
    showCaution();
}
function saveCaution(){
    // 重要事項をサーバへ保存
    var cautionSt = elmFor("cautionF").innerText;
    if (cautionSt == caution()) return;
    
    if (confirm("注意事項が修正されています。サーバへ保存しますか")){
        // 編集内容をサーバへ保存
        var pid = patientId();
        var date = currentDate();
        var tag = 'ProgressSection.note';
        var container = new Object();
        container[tag] = cautionSt;
        put_page(owner(), pid, date, timeLimit(), container, savedCaution);
    } else {
        // 編集前に戻す
        elmFor("cautionF").innerHTML = caution();
    }
}

function fixCaution(){
    // 注意事項をサーバへ保存
    var st = elmFor("inputF").value;
    if (st.length > 0){
        closeFloatPanel();
        
        // 編集内容をサーバへ保存
        var pid = patientId();
        var date = currentDate();
        var tag = 'ProgressSection.note';
        var container = new Object();
        container[tag] = st;
        put_page(owner(), pid, date, timeLimit(), container, savedCaution);
    }
}
function showCautionEditor(){
    // 注意事項入力パネルを開く：TOOL MENU などから開く
    var w = 350;
	var x = 150; // 表示するx座標
	var y = 150; // 表示するy座標
    var title = "注意事項入力パネル";
    var action = "openHelp('./cautionHelp.html')";
    var elm = openSeeThroughPanel("_floatPanel", x, y, w, title, action);
    if (!elm) return;
    elm.style.padding = "8px";
    
    // チェックボックス
    var div = newDIV(elm, "");
    div.style.marginBottom = "2px";
    div.style.fontSize = "10pt";
    var status = showAllergy(); // localStorage.js
    var cb = newCHECKBOX(div, "", "アレルギーをページ・ヘッダーに表示", status);
    cb.setAttribute("onchange", "setShowAllergy(this)");
    
    // 注意事項入力欄
    var div = newDIV(elm, "");
    var st = (cautionString()) ? cautionString() : "";
    var fd = newFIELD(div, "inputF", "", 50, st);
    fd.focus();
    fd.setAttribute("onchange", "fixCaution()");
    
    // 検索ボタン
    var bt = newSPAN(div, "/fixButton");
    bt.innerHTML = "確定";
    bt.setAttribute("onclick", "fixCaution()");
}

///// CAUTION ///////////////////////////////////////////
/////////////////////////////////////////////////////////


function openBasicPage(answer){
    // 基本情報ページを開く
    //alert("== openBasicPage->"+answer); //##
    
    var array = answer.split("<SEPARATOR>");
    if (array.length > 1){
        var obj = JSON.parse(array[1]);
        //alert("obj->"+encodeObject(obj)); //##
        
        setAddressObj(obj.addressSection);
        setBasicObj(obj.basicSection);
        setMaritalObj(obj.maritalSection);
        setHealthInsuranceObj(obj.healthInsurance);
        setPublicInsuranceObj(obj.publicInsurance);
        setUniversalObj(obj.universalSection);

        // 注意事項を表示
        showCaution();

        // 「...のカルテを開きつつあります」のメッセージを消去
        document.getElementById("alertArea").innerHTML = "";
        
        // 基本情報を tools の base 領域に表示
        var tools = window.top.tools;
        tools.closeToolArea();
    } else { // ERROR
        alert("== openBasicPage->"+answer); //##
    }
}

function openPage(dateTime, isActive){
    // dateTime のページを生成
    //_debug("== openPage == "+dateTime+"->"+isActive); //##
    
    var elm = document.getElementById(dateTime + ".page");
    elm.innerHTML = "";
    
    // 付箋添付エリア
    var div = newDIV(elm, dateTime + ".postItArea");

    if (isActive){
        elm.setAttribute("class","currentPage");
        
        // 他にアクティブなページがあればインアクティブにする
        if ((_activeDate) && (_activeDate != dateTime))
            openPage(_activeDate); // インアクティブにする
        _activeDate = dateTime;
        
        // Agent データ・オブジェクトを生成し記憶
        var agt = new Object();
        agt.patientId = patientId();
        agt.patientKanjiName = patientKanjiName();
        agt.entryDate = dateTime;
        agt.hospitalId = hospitalId();
        agt.owner = owner();
        setAgent(agt);
        
        // 祝日リストを読み込んでおく
        var year = dateTime.substr(0, 4);
        getHolidays(year);
    } else {
        elm.setAttribute("class","page");
    }
    
    // ページ・ヘッダーの受診日や氏名の表示行
    var div = newDIV(elm, "/clearfix");
    div.style.paddingBottom = "2px";
    // 受診日エリア
    var dv = newDIV(div, "/dateLabel");
    var num = weekOfDate(dateTime);
    dv.innerHTML = dateTime + " " + _weeks[num];
    dv.setAttribute("onclick", "openPage('" + dateTime + "','true')");
    // 氏名エリア
    var dv = newDIV(div, dateTime + ".name");
    // 漢字氏名 ---------------------
    var sp = newSPAN(dv, "/nameLabel");
    sp.innerHTML = patientKanjiName();
    // 仮名氏名 ---------------------
    var sp = newSPAN(dv, "/kanaLabel");
    var obj = valueForTag("NameSection.patientKanaName", dateTime);
    var kana = (obj && obj.value) ? obj.value : "";
    sp.innerHTML = kana;
    // 年齢 -------------------------
    var sp = newSPAN(dv, "/ageLabel");
    sp.innerHTML = ageAtDate(birthDate(), dateTime) + " 才"
    
    // 注意事項
    var div = newDIV(elm, dateTime + ".cautionArea");
    
    // ページ・ヘッダーのアイコン・ギャラリー表示行
    var div = newDIV(elm, "/clearfix");
    div.style.paddingBottom = "5px";
    var dv = newDIV(div, dateTime + "readWriteMarder/left-side");
    dv.style.width = "90px";
    dv.style.paddingLeft = "3px";
    dv.style.marginTop = "5px";
    showReadWriteMarker(dv, isActive, dateTime);
    var dv = newDIV(div, "/right-side");
    dv.style.paddingRight = "0";
    dv.style.marginTop = "5px";
    showPageIcons(dv, isActive);
    
    // 各フィールドを表示
    var array = layoutForMode(_progress_);
    //_initDebug("true"); //##
    _debug("=== openPage"); //##
    _debug("openPage array->"+encodeObject(array)); //##
    for (num in array){
        var cell = array[num];
        //_debug(cell.label+" cell->"+encodeObject(cell)); //##
        cell.editorIsOpen = false; // 中途でコケてゾンビ化した editorIsOpen を一掃
        if (cell.hitAndRun * 1) continue; // 非表示セルをスキップ

        openCell(elm, cell, dateTime, isActive);
    }

    if (isActive){
        // 本日以外のアクティブ・ページを開く場合に呼ばれる
        // 基本情報を読込中のメッセージ表示した後、基本情報を表示
        var elm = window.top.tools.base;
        elm.innerHTML = "";
        var sp = newSPAN(elm, "alert");
        sp.innerHTML = "読込中...";
        
        // 基本情報を表示
        setCurrentDate(dateTime);
        WKGetPage(owner(), patientId(), dateTime);
    }
}

function makeCalendar(answer){
    // calendar を生成
    var array = JSON.parse(answer);
    if (array)
        _debug("makeCalendar->"+encodeObject(array)); //##
    else 
        _debug("makeCalendar array->"+array); //##
    
    openCalendar(array); // calndar.js
}

var _activeDate;
function openPages(answer){
    // サーバから得られた ProgressSection データで各ページを生成
    var obj = JSON.parse(answer);
    //_initDebug(true); //##
    //_debug("== openPages ->"+encodeObject(obj)); return; //## return しないとコケる
    
    setPatientTable(obj.patientTable);
    setNameObj(obj.nameSection);
    setPatientName(obj.nameSection.patientKanjiName.val); // name を記憶
    setProgressObj(obj.progressSection);
    setFrontObj(obj.frontTable);
    setPostItObjects(obj.postIt);
    _activeDate = null; // 初期化して置かなければならない
    
    // ウインドー・タイトルに カルテID・名前 を表示
    window.top.document.title = patientName();
    
    // 全てのページを表示
    var div = document.getElementById("contents");
    div.innerHTML = "";
    var hasRecord = false; // obj にレコードが存在するか否か
    var hasTodayPage = false;
    
    var array = history();
    for (num in array){
        var dateTime = array[num];
        var dv = newDIV(div, dateTime + ".page");
        
        // ここで生成した dv にページを表示：最初のページのみアクティブで basicPage も表示
        var isActive = (num == 0) ? true : false;
        openPage(dateTime, isActive); 
        
        if (isSameDate(dateTime, today())) hasTodayPage = true;
        hasRecord = true;
    }
    
    // 最終受診日を currentDate() に設定
    if (array.length > 0) setCurrentDate(array[0]);
    
    // 基本情報を読込中のメッセージ表示
    var elm = window.top.tools.base;
    elm.innerHTML = "";
    var sp = newSPAN(elm, "alert");
    sp.innerHTML = "読込中...";
    
    if (!hasRecord){
        // カルテに１頁もない場合は自動的に頁追加
        addPage(todayAndTime());  // Ajax を起動するので openBasicPage() 実行しない
    } else if (addPageDateTime() && !hasTodayPage){
       // 待受リストや待受タグから黄色タグが開かれ、本日のページがない場合のみ
        if (isReserved())
            openAddReservedPagePanel(patientId(), addPageDateTime());
        else
            addPage(addPageDateTime()); 
    } else {
        if (noCalendar() == 0){ // localStorage.js
            var args = new Object();
            args["patientId"] = patientId();
            args["dateTime"] = currentDate();
            NRCall("GET_BOOKING", args, makeCalendar);
        }
        
        // currentDate の付箋があれば開く：currentDate() が設定されている必要あり
        //showPostIt(); // postIt.js
        
        // 基本情報を取得し表示：マルチ・スレッドを使う
        WKGetPage(owner(), patientId(), currentDate());
    }
}


//////////////////////////////////////////////////////////////////////////
///// SHELL から使えるメソッド //////////////////////////////////////////////

function openChart(patient_id, addPageDate){
    // patient_id のカルテを開く：addPageDate があればページ追加
    // addPageDate が日付形式ならその日付ページを追加、そうでなければ本日のページを追加
    //alert("== openChart == "+patient_id+"->"+addPageDate); //##

    if (!patient_id || (patient_id.length < 8)){
        if (patientId())
            patient_id = patientId();
        else
            return;
    }
    
    // 「検索」「ページ追加なしの予約タグ」がこの型式
    setAddPageDateTime(null);
    setIsReserved(false);

    if (addPageDate != null){
        // addPageDate が日時フォーマットなら、その日時のページを追加
        // 日時フォーマットでなければ現在日時のページを追加
        switch (isDate(addPageDate)){
            case 0: // addPageDate が日付形式でなかった：「履歴」「待受」がこの型式
            case 1: // addPageDate が年月日だけだった
                setAddPageDateTime(todayAndTime()); // 現在日時のページを追加
                break;
            default: // addPageDate が年月日時分秒だった
                // 「ページ追加ありの予約タグ」がこの型式
                setIsReserved(true);
                setAddPageDateTime(addPageDate); // 予約日のページを追加
                break;
        }
    }

    // workArea の検索リストから起動されることがあるので workArea をクリア
    var elm =document.getElementById("workArea");
    elm.innerHTML = "";
    var elm = document.getElementById("calendarArea");
    elm.innerHTML = "";
    
    setPatientId(patient_id); // patientId を記憶
    
    var elm = document.getElementById("patientIdArea");
    elm.innerHTML = patient_id;
    
    // 作業中であることを示すメッセージ
    var div = document.getElementById("contents");
    div.innerHTML = "";
    var elm = document.getElementById("alertArea");
    elm.innerHTML = patient_id + " のカルテを開きつつあります...";
    
    // Ajax がカブらないようシリアルに実行
    get_pages(owner(), patient_id, openPages);
}

function enableReadWriteMarker(dateTime){
    // 編集不可スライダーを編集可にする
    if (!dateTime) dateTime = currentDate();
    
    // ステータスを編集可に設定
    setIsReadOnly(false, dateTime);
    
    // スライダーを編集可の表示にする
    var dv = elmFor(dateTime + "readWriteMarder");
    dv.innerHTML = "";
    var bid = "pageReadOnlyStatus";
    var sp = newSPAN(dv, bid);
    var bt = newOnButton(bid, "編集可/編集不可", "getOnOff");
}



