

////////////////////////////////////////////
/// localStorage ///////////////////////////

function getWindowSize(){
	// Booking のウインドー位置とサイズをサーバへリクエスト
    var size = window.localStorage["waitingListWindowSize"];
    
	// サーバから得られたサイズにウインドーを調整する
	if (size){
		var args = size.split(",");
		var x = args[0] * 1;
		var y = args[1];
		var w = args[2];
		var h = args[3];
		// resize を先にしておかないと元が大きいサイズだった場合 moveTo しよう
		// としてもウインドー境界の制限で移動できない場合がある
		window.resizeTo(w, h);
		window.moveTo(x, y);
	}
}
function putWindowSize(){
	// Booking のウインドー位置とサイズをサーバへ記憶
    if (_isOutPanel == false) return;

    var x = window.screenLeft;
	var y = window.screenTop;
	var w = window.outerWidth;
	var h = window.outerHeight;
    var array = [x, y, w, h];
    window.localStorage["waitingListWindowSize"] = array.join(",");
    
    showFadeoutInfo("messageArea", "window のサイズと位置を記憶しました", 800);
}

/// localStorage ///////////////////////////
////////////////////////////////////////////


///////////////////////////////////////////////////////
///// Preferences /////////////////////////////////////

function sortBookingList(){
    // 受付日時で逆ソートする
    var status = (bookingReverse()) ? "" : "1";
    setBookingReverse(status);
    
    // その条件で受診者リストを再表示
    showWaitingList();
}

function showControls(){
    // フッター上のコントロール類を表示
    var elm = document.getElementById("controlBar");
    if (elm.innerHTML.length > 0){
        // その条件で受診者リストを再表示
        showWaitingList();
        return;
    }
    elm.innerHTML = "";
    
    // 表示の設定
    var base = newDIV(elm, "/controlBarArea");
    var div = newDIV(base, "");
    var cb = newCHECKBOX(div, "", "付箋カラーを表示", postItColorCheck());
    cb.setAttribute("onchange", "setPostItColorCheck(this)");
    var sp = newSPAN(div, "");
    sp.style.marginLeft = "8px";
    var cb = newCHECKBOX(div, "", "本日の受診者のみ表示", bookingTodayCheck());
    cb.setAttribute("onchange", "setBookingTodayCheck(this)");
    var sp = newSPAN(div, "");
    sp.style.marginLeft = "8px";
    var cb = newCHECKBOX(div, "", "パネル枠サイズ固定せず", flexibleWaitingList());
    cb.setAttribute("onchange", "setFlexibleWaitingList(this)");
    
    // 非表示の設定
    var div = newDIV(base, "");
    // 診療済を非表示
    var sp = newSPAN(div, "");
    sp.style.marginRight = "5px";
    var cb = newCHECKBOX(sp, "", "診療済を非表示", finishCheck());
    cb.setAttribute("onchange", "setFinishCheck(this)");
    // 診療済チェックボックスを表示
    var cb = newCHECKBOX(sp, "", "診療済チェックボックスを表示", showBookingCheck());
    cb.setAttribute("onchange", "setShowBookingCheck(this)");
    
    var div = newDIV(base, "");
    // -- 予約覧を表示しておきたいという要望強ければ復活 --
    var sp = newSPAN(div, "");
    sp.style.marginRight = "5px";
    var cb = newCHECKBOX(sp, "", "予約欄を表示", yoyakuCheck());
    cb.setAttribute("onchange", "setYoyakuCheck(this)");
    // 実施計画欄を表示
    var sp = newSPAN(div, "");
    sp.style.marginRight = "5px";
    var cb = newCHECKBOX(sp, "", "実施計欄を表示", planColumnCheck());
    cb.setAttribute("onchange", "setPlanColumnCheck(this)");
    // 金額欄を表示
    var sp = newSPAN(div, "");
    sp.style.marginRight = "5px";
    var cb = newCHECKBOX(sp, "", "金額欄を表示", costColumnCheck());
    cb.setAttribute("onchange", "setCostColumnCheck(this)");
    // 保険証確認を表示
    var cb = newCHECKBOX(div, "", "保険証確認を表示", insColumnCheck());
    cb.setAttribute("onchange", "setInsColumnCheck(this)");
}

///// Preferences /////////////////////////////////////
///////////////////////////////////////////////////////

function openWaitEditor(st){
    // 予約情報の変更パネルを開く
    var obj = decodeObject(st);
    var patientId = obj.patientId;
    var entryDate = obj.entryDate;
    var reservedDate = obj.reservedDate;
    var accepted = (entryDate != reservedDate) ? true : false;
    
    if (! isSameDate(reservedDate, today())){
        alert(reservedDate + " は本日の予約ではないので変更できません");
        return;
    }
    if (accepted){
        if (confirm(entryDate+" の「受付」を " + reservedDate + "の「予約」に戻します")){
            var args = new Object();
            args["patientId"] = patientId;
            args["entryDate"] = reservedDate;
            args["reservedDate"] = reservedDate;
            
            NRCall("PUT_FRONT_BOOKING", args);
        }
    } else {
        if (confirm(reservedDate+" の「予約」を、現在時刻で「受診」に変更します")){
            var args = new Object();
            args["patientId"] = patientId;
            args["entryDate"] = "";
            args["reservedDate"] = reservedDate;
            
            NRCall("PUT_FRONT_BOOKING", args);
        }
    }
}
        
function changeEndTime(elm, st){
    // チェックボックスの診療済 / 診療未済 が変更された
    var isFinished = (elm.checked) ? true : false;
    var rec = decodeObject(st);
    var pid = rec.patientId;
    var dateTime = rec.entryDate;
    
    if (rec.reservedDate == rec.entryDate){ // 診療待ち予約患者
        alert("受付が済んでいないので変更できません");
    } else {
        if (isFinished){ // 診療済みとする
            var args = new Object();
            args["patientId"] = pid;
            args["entryDate"] = dateTime;
            args["endTime"] = todayAndTime();
                        
            NRCall("PUT_FRONT_END_TIME", args);
        } else { // 診療未済とする
            var args = new Object();
            args["patientId"] = pid;
            args["entryDate"] = dateTime;
            args["endTime"] = "";
                        
            NRCall("PUT_FRONT_END_TIME", args);
        }
    }
}


//////////////////////////////////////////////////////////
///// 実施計画を黄色いタグで表示 /////////////////////////////

function closeYellowTip(elm){
    elm.display = "none";
    elm.innerHTML = "";
}
function kickYellowTip(targetId, comment){
    // comment を全面表示するインフォティップを開く
    // ### kickInfoTip() では Y 座標が下過ぎることがあるので、その場に表示する
    if (comment.length == 0) return;
    
    // 不可視設定の DIV: _infoTip を用意する必要あり
    var elm = document.getElementById("_infoTip");
    if (!elm){
        alert("_infoTip がありません"); return;
    }
    elm.innerHTML = "";
    
    var targetElement = elmFor(targetId); // infoTip を起動する element
    var pos = getPosition(targetElement);
    elm.style.left = pos.x; // 表示するx座標
    elm.style.top = pos.y; // 表示するy座標
    elm.style.visibility = "visible";
    
    // 万一 inofoTIp が画面に残ってしまった場合に対応
    elm.setAttribute("onmouseover", "closeYellowTip(this)");
    
    // infoTip を表示
    var p = newSPAN(elm, "/infoTIp"); // ## これにより残像発生を防ぐ
    p.innerHTML = comment;
}

///// 実施計画を黄色いタグで表示 /////////////////////////////
//////////////////////////////////////////////////////////

function _opneLogChart(date, patientId, addPage){
    // カルテを開く
    putWindowSize();
    
    if (window.event.shiftKey){
        // 患者会計レコードの編集パネルを開く
        var url = "../FRONT/patientEditor.php?dateAndId=" + date + "^" + patientId;
        
        window.open(encodeURI(url),
                    "patientEditor",
                    "width=260,height=550,resizable=yes");
    } else {
        // カルテを開く
        var url = "top.php?patientId=" + patientId
        + "&addPageFlag=" + addPage;
        
        window.open(encodeURI(url),patientId,"width=1100,height=800,resizable=yes");
    }
}

function refleshWaitingList(obj){
    // 待受リストの内容を更新
    var elm = document.getElementById("waitingTableArea");
    if (!elm) return; // polling から呼ばれ待受リスト・パネル表示されていない場合
    
    if (! flexibleWaitingList()){
        elm.style.height = "200px"; // パネルの高さ
        elm.style.overflow = "auto"; // 内部がスクロールするよう設定
    }
    
    elm.innerHTML = "";
    var tbl = newTABLE(elm, "/bookingTable");
    elm.style.paddingRight = "10px";
    
    if (!obj || (obj.length == 0)) return;
    
    // === HEADER ========================================
    showHeader();
    
    // === CONTENTS ======================================
    // bookingReverse() が指定されているなら obj を逆順ソート
    if (bookingReverse()) obj = obj.reverse();
    
    var ignoreFinished = finishCheck(); // 診療済を非表示
    var total = 0;
    var sum = 0;
    
    for (num in obj){
        var rec = obj[num];     
        
        //console.log("postItColor", rec.patientId, rec.postItColor); //##
        
        // 終了時刻が NULL なら「診療待ち」時刻があれば「診療済み」と判定
        var isFinished = (rec.endTime && rec.endTime.toString().length) ? true : false;
        var isToday = isSameDate(rec.entryDate, today());
        
        if (ignoreFinished && isFinished) continue; // 診療済をスキップ
        if (bookingTodayCheck() && !isToday) continue; // 本日以外をスキップ
        
        var reserved = false;
        if (rec.reservedDate && (rec.reservedDate != "0000-00-00 00:00:00"))
            reserved = true; // 予約患者
                
        var tr = newTR(tbl, "", "");
        // 付箋カラー ---------------------------
        if (postItColorCheck()){
            var td = newTD(tr, "postItColorArea", "");
            td.style.width = "10px";
            var colorNumber = rec.postItColor;

            // postIt を持たないレコードの場合 colorNum は -2
            if (colorNumber >= 0){
                var dot = newDIV(td, "");
                dot.innerHTML = colorNumber;
                dot.style.padding = "0 4px";
                switch (colorNumber * 1){
                    case 1: dot.setAttribute("class", "postItDotBlue"); break;
                    case 2: dot.setAttribute("class", "postItDotYellow"); break;
                    case 3: dot.setAttribute("class", "postItDotRed"); break;
                    default: dot.setAttribute("class", "postItDotGreen"); break;
                }
                
            }
        }
        // 診療済みチェックボックス ---------------
        if (showBookingCheck()){ // 診療済チェックボックスを表示
            var td = newTD(tr, "bookingCheckBox", "");
            td.style.width = "10px";
            var cb = newCHECKBOX(td, "", "", (isFinished) ? 1 : 0);
            var st = encodeObject(rec); // rec をアーカイブする
            cb.setAttribute("onchange", "changeEndTime(this,'" + st +"')");
        }
        // 予約時刻 ----------------------------
        if (yoyakuCheck()){
            var reservedDate = (rec.reservedDate)
            ? rec.reservedDate.substr(11,5) : "";
            if (reservedDate == "00:00") reservedDate = "";
            var td = newTD(tr, "/bookingColumn", reservedDate);
            td.style.width = "30px";
        }
        // 受付日時 ----------------------------
        var td = newTD(tr, "/bookingColumn", "");
        td.style.width = "90px";
        var sp = newSPAN(td, "");
        sp.innerHTML = shortDate(rec.entryDate, 'hasTime');
        sp.style.paddingLeft = "0"; // 何故か padding がついてしまうので
        if (reserved){ // 予約患者
            if (rec.reservedDate == rec.entryDate){ // 受付未済の予約患者
                sp.setAttribute("class", "reserved");
            } else { // 受付済みの予約患者
                sp.setAttribute("class", "reservedTime");
            }
            var st = encodeObject(rec); // rec をアーカイブする
            sp.setAttribute("onclick", "openWaitEditor('"+st+"')");
        } else { // 受付済みのもの
            sp.setAttribute("class", "nonReservedTime");
        }
        // patientId --------------------------
        var st = rec.patientId + " " + rec.kanjiName;
        var td = newTD(tr, "", st);
        td.style.width = "180px";
        if (rec.reservedDate == rec.entryDate){ // 診療待ち予約患者
            td.setAttribute("class", "accepted"); // 診療待ち：黄色のタグ
            // ### encodeObject(rec) 渡しだと内容によってはエラー発生 ###
            var action = "_opneLogChart('" + rec.entryDate +"','" + rec.patientId + "')" // カルテを開く：ページ追加せず
        } else if (isFinished){ // 診療済み
            td.setAttribute("class", "finished"); // 診療済み：白文字
            var action = "_opneLogChart('" + rec.entryDate +"','" + rec.patientId + "')" // カルテを開く：ページ追加せず
        } else { // 診療待ち
            td.setAttribute("class", "accepted"); // 診療待ち：黄色のタグ
            var action = "_opneLogChart('" + rec.entryDate +"','" + rec.patientId + "','addPage')" // カルテを開き新規ページ追加
        }
        td.setAttribute("onclick", action);
        // 合計欄 --------------------------------
        if (costColumnCheck()){
            var cost = rec.insFee * 1 + rec.ownFee  * 1 + "";
            sum += rec.insFee * 1 + rec.ownFee  * 1;
            total++;
            var td = newTD(tr, "/bookingColumn", cost); // 合計
            td.style.textAlign = "right";
            td.style.width = "50px";
        }
        // 実施計画欄 --------------------------------
        if (planColumnCheck()){
            var plan = rec.plan;
            if (plan.length > 2) plan = plan.substr(0, 2) + "...";
            var eid = rec.entryDate;
            var td = newTD(tr, eid + "/bookingColumn", plan); // 実施計画
            td.style.textAlign = "right";
            td.style.width = "50px";
            
            // plan 欄にマウスが載ると plan がフルテキストで表示される
            td.setAttribute("onmouseover", "kickYellowTip('"+eid+"','"+rec.plan+"')");
            td.setAttribute("onmouseout", "closeInfoTip()");
            
        }
        // 保険証欄 -------------------------------
        if (insColumnCheck()){
            var td = newTD(tr, "/bookingActor", ""); // 保険証
            setScanDateWith(td, rec.scanDateTime);
            var action = "openInsViewer('"+rec.patientId+"','"+rec.entryDate+"')"; // neuron.js
            td.setAttribute("onclick", action);
            td.style.width = "70px";
        }
    }
    
    // 本日のみの表示であれば合計を表示
    if (costColumnCheck() && bookingTodayCheck()){
        var tr = newTR(tbl, "", "");
        if (postItColorCheck()){ // 付箋カラー
            var td = newTD(tr, "", "");
        }
        if (showBookingCheck()){ // 診療済チェックボックス
            var td = newTD(tr, "", "");
        }
        if (yoyakuCheck()){ // 予約覧
            var td = newTD(tr, "", "");
        }
        var td = newTD(tr, "/bookingColumn", "Total ( " + total + " )");
        var td = newTD(tr, "", "");
        td.style.textAlign = "right";
        var td = newTD(tr, "/bookingColumn", sum + "");
        td.style.textAlign = "right";
    }
    
    function showHeader(){
        // ヘッダーを表示
        var elm = document.getElementById("headerArea");
        elm.innerHTML = "";
        var tbl = newTABLE(elm, "/bookingTable");
        var tr = newTR(tbl, "", "");
        tr.style.fontSize = "9pt";
        
        // TITLE を掴んでドラッグできるようにする
        tr.setAttribute("onmousedown", "cursorLock(this)"); // マウスで掴み可動にする
        tr.setAttribute("onmouseup", "cursorUnlock()"); // マウスで掴み可動にする
        window.onmousemove = getMouseXY;
        
        // 付箋カラー -----------------------------
        if (postItColorCheck()){
            var td = newTD(tr, "/bookingTitle", "");
            td.style.width = "15px";
        }
        // 診療済みチェック ------------------------
        if (showBookingCheck()){
            var td = newTD(tr, "/bookingTitle", "済");
            td.style.width = "10px";
        }
        // 予約時刻 -------------------------------
        if (yoyakuCheck()){
            var td = newTD(tr, "/bookingTitle", "予約");
            td.style.width = "30px";
        }
        // 受付日時 -------------------------------
        var td = newTD(tr, "bookingSortTab/bookingTitle", "受付日時");
        td.style.width = "90px";
        td.setAttribute("onclick", "sortBookingList()");
        // カルテ ID と氏名 ------------------------
        var td = newTD(tr, "/bookingTitle", "カルテ");
        td.style.width = "180px";
        // 金額合計 -------------------------------
        if (costColumnCheck()){
            var td = newTD(tr, "/bookingTitle", "計");
            td.style.width = "50px";
        }
        // 実施計画 -------------------------------
        if (planColumnCheck()){
            var td = newTD(tr, "/bookingTitle", "実施計画");
            td.style.width = "50px";
        }
        // 保険証画像確認 --------------------------
        if (insColumnCheck()){
            var td = newTD(tr, "/bookingTitle", "保険証");
            td.style.width = "70px";
        }
    }
    
    function setScanDateWith(elm, filename){
        // filename から 日付を抽出して返す
        // filename = "03234202_20120113165123.JPG" 形式
        if (filename){
            elm.style.textAlign = "right";
            var array = filename.split("_");
            if (array.length > 1){
                var st = array[1];
                var yyyy = st.substr(0, 4);
                var mm = st.substr(4, 2);
                var dd = st.substr(6, 2);
                var hour = st.substr(8, 2);
                var min = st.substr(10, 2);
                var sec = st.substr(12, 2);
                var dateTime = yyyy+"-"+mm+"-"+dd+" "+hour+":"+min;
                
                var today = (currentDate()) ? currentDate() : todayAndTime();
                var pastDays = daysBetween(dateTime, today);
                if (pastDays > 30){
                    // 一定日数を越えたものは「経過日数」表示
                    elm.innerHTML = pastDays + " 日経過";
                } else {
                    elm.innerHTML = yyyy+"-"+mm+"-"+dd;
                }
            } else {
                elm.innerHTML = filename; // 本来このようなことは無いはず
            }
        } else {
            elm.innerHTML = "画像なし";
            elm.setAttribute("class", "bookingYellowActor"); // 黄色表示
        }
    }
}

function showWaitingListPanel(){
    // 別ウインドーに表示する
    window.open("./waitingPanel.php","waitingPanel"
                ,"width=500,height=270,scrollbars=yes,dependent=yes");
}

function showBookingList(){
    // 外部から呼ばれる関数名
    initWaitingList("_confirm");
}
function showWaitingList(){
    // 受診者リストを表示
    initWaitingList();
}

var _isOutPanel;

var _waitingListArea;
function initWaitingList(id){
    // 受診者リストを表示
    //window.name = "waitingList";
    _waitingListArea = (id) ? id : "_floatPanel";
    
    if (_waitingListArea == "_floatPanel"){
        // NOA 画面に表示される通常の waitingList
        _isOutPanel = false;
        
        var x = 10;
        var y = 80;
        var w = 500;
        var title = "待受パネル";
        var help = "openHelp('waitingListHelp.html')";
        var elm = openSeeThroughPanel("_floatPanel", x, y, w, title, help);
        if (!elm) return;
   } else {
        // 別ウインドーとして表示される waitingList
        _isOutPanel = true;

        var elm = document.getElementById(_waitingListArea);
        elm.innerHTML = "";
    }
    
    var div = newDIV(elm, "waitingListArea");
    
    // === ヘッダー表示エリア ===
    var dv = newDIV(div, "headerArea");
    
    // === コンテンツ表示エリア ===
    var dv = newDIV(div, "waitingTableArea");
    
    if (_isOutPanel){ // 外部パネルとして表示される waitingList
        getWindowSize();
    } else { // NOA 画面に表示される waitingList
        // === FOOOTER ===
        var dv = newDIV(div, "");
        dv.style.background = "#55f";
        dv.style.fontSize = "9pt";
        dv.style.paddingTop = "5px";
        // 外部ウインドー・アイコン -------
        var sp = newSPAN(dv, "outWindow/outArrowArea");
        sp.setAttribute("onclick", "showWaitingListPanel()");
        setInfoTip("outWindow", "独立したウインドーとして開く"); // HELP
        var img = newIMAGE(sp, "", "./outArrow.png", "?");
        img.style.height = "10px";
        // 初期化アイコン ----------------
        var sp = newSPAN(dv, "bookingOpen");
        sp.setAttribute("onclick", "showControls()");
        sp.style.marginLeft = "5px";
        setInfoTip("bookingOpen", "摘要や初期設定を表示"); // HELP
        var img = newIMAGE(sp, "", "./hammer.png", "?");
        img.style.height = "14px";
        img.setAttribute("class", "expandIcon");
        // === 設定コントロール・エリア ===
        var ctrl = newDIV(div, "controlBar");
    }
    polling();
        
    
    function polling(){
        // ### WaitingList が別ウインドーで開く場合にのみ動作 ###
        // 受付の患者登録を Worker を使い裏プロセスの polling でチェック
        // DB とのやりとりや polling は polling.js で設定
        var obj = new Object();
        obj["dateTime"] = today();
        var noaString = encodeObject(obj);
        
        // today() と異なるタイムスタンプがあれば返事を返すようリクエスト
        var worker = new Worker('./polling.js');
        worker.postMessage(noaString); // ### worker に命令書 noaString を送る ###

        console.log("kick polling"); //##

        
        worker.onmessage = function (event) {
            // 新たに受け付けられた受診者データを受け取る
            var answer = event.data;
            
            console.log("polling", todayAndTime()); //##
            
            var array = answer.split("<SEPARATOR>");
            if (array.length > 1){
                var obj = JSON.parse(array[1]);
                var records = obj.records; // 本日の日計表レコード
                
                // 待受リストを更新
                refleshWaitingList(records);
            }
        }
    }
}


