
//////////////////////////
/// Grobal 変数
//////////////////////////

function priceListServer(){
    return "../Prescription/PriceListServer.php";
}

var _tableArray = null;
var _youhouType = 0;
var _cellId = 100;
var _cursorPosition = (-1);
var _changed = 0;

function setChanged(val){
    _changed = val;
}
function changed(){
    return _changed;
}

function cursorPosition(){
    return _cursorPosition;
}
function setCursorPosition(pos){
    _cursorPosition = pos * 1;
}

function setSelectedType(type){
    // 用法 radio button の選択により popupMenu を作成表示
    _youhouType = type;
    loadData(_youhouType); // type に該当するレコードを DB から読み込む
    makeNarrowButtons();
    
    // タブの行列を表示
    setTabs(type);
}
function selectedType(){
    return _youhouType; // function名と定数名は異なること
}

function setTableArray(ln){
    // 文字列形式でもらった ln を基に薬剤テーブルを生成
    _tableArray = new Array();
    var records = eval('(' + ln + ')');
    
    _debug("== setTableArray"); //##
    
    for (i in records){
        var obj = records[i];
        _debug(obj.code+"->"+obj.name); //##
        
        var recObj = new RecordObj(obj);
        
        if (recObj) _tableArray.push(recObj);
    }
    //alert("setTableArray->"+encodeObject(_tableArray)); //##
    
    // "...その他" を追加
    var obj = new Object();
    obj.name = "...その他";
    _tableArray.push(obj);
}
function tableArray(){
    return _tableArray;
}
function tableNameArray(){
    var array = new Array();
    for (num in _tableArray){
        var obj = _tableArray[num];
        array[num] = obj.name;
    }
/*    var i, count = _tableArray.length;
    for (i=0; i < count; i++){
        var obj = _tableArray[i];
        array[i] = obj.name;
    }*/
    return array;
}
function genericForName(name){
    // 商品名に対応する一般名を返す
    for (num in _tableArray){
        var obj = _tableArray[num];
        if ((name == obj.name) && obj.generic)
            return obj.generic;
    }
    // 対応する generic がなければ name を返す
    return name;
}
function tableNameArrayForKey(type, key){
    // key に一致する薬剤テーブルを返す
    var array = new Array();
    var items = tableArray();
    var i, num, count = items.length;
    for (i=num=0; i < count; i++){
        var obj = items[i];
        switch (type){
            case 2: // 薬効がマッチすればリストに加える 
                if (obj.effect && (obj.effect.indexOf(key) >= 0))
                    array[num++] = obj.name;
                break;
            default: // 別名でも実名でも薬効でもマッチすればリストに加える 
                if (obj.name.indexOf(key) >= 0)
                    array[num++] = obj.name;
                if (obj.effect && (obj.effect.indexOf(key) >= 0))
                    array[num++] = obj.name;
                if (obj.alias && (obj.alias.indexOf(key) >= 0))
                    array[num++] = obj.name;
                break;
        }
    }
    return array;
}
function effectArray(){
    // type(約束、内用、屯用、外用) に応じた効能リストを返す
    var items = tableArray(); // 効能に応じたものがすでに入っていはず
    var effectObj = new Object();
    for (i=0,ct=items.length; i < ct; i++){
        var obj = items[i];
        var effects = obj.effect; // "鎮痛 解熱" 形式
        if (!effects || (effects.length == 0)) continue;
        
        var ary = effects.split(" ");
        for (j=0,ctj=ary.length; j < ctj; j++){
            var effect = ary[j]; // "鎮痛" 形式
            // 効能をユニークにするため object の添字として保存
            if (effect.length) effectObj[effect] = obj.name;
        }
    }
    
    // ユニークな効能を array に入れて返す
    var array = new Array();
    for (key in effectObj)
        array.push(key);
    array.sort();
    return array;
}

function showTableNameArray(){
    // ### 検証用に tableNameArray を message エリアに表示
    var key = document.getElementById("searchKey").value;
    var elm = document.getElementById("message");
    elm.innerHTML = "";
    var tbl = newTABLE(elm, "");
    tbl.style.border = "thin solid #000";
    tbl.style.width = "100%";
    tbl.style.fontSize = "8 pt";
    
    var tr = newTR(tbl, "header", "");
    var td = newTD(tr, "", "name");
    var td = newTD(tr, "", "alias");
    var td = newTD(tr, "", key);
    
    var items = tableArray();
    for (i=0,ct=items.length; i < ct; i++){
        var obj = items[i];
        if (key.length && (obj.effect.indexOf(key) < 0)) continue;
        var tr = newTR(tbl, "", "");
        var td = newTD(tr, "", obj.name);
        var td = newTD(tr, "", obj.alias);
        var td = newTD(tr, "", obj.effect);
    }
}

///////////////////////////////////
/// localStorage による処理 /////////

function setTouchAndGo(elm){
    // ピンを立てる：「確定」しても FORM は消えず NOA も編集モードから抜けない
    window.localStorage["prescriptionTouchAndGo"] = (elm.checked) ? "1" : "0";
}
function isTouchAndGo(){
    var status = window.localStorage["prescriptionTouchAndGo"];
    
    return (status && status * 1) ? true : false;
}
/// localStorage による処理 /////////
///////////////////////////////////


//////////////////////////////////////
// 用法のリストの作成管理 ///////////////

_naiyouItems = null;
_tonyouItems = null;
_gaiyouItems = null;

function naiyouItems(){
    return _naiyouItems;
}
function gaiyouItems(){
    return _gaiyouItems;
}
function tonyouItems(){
    return _tonyouItems;
}

function setYouhouItems(buff){
    _debug("=== setYouhouItems ==="); //##
    
    _naiyouItems = new Array();
    _tonyouItems = new Array();
    _gaiyouItems = new Array();
    // 最初に空白アイテムを追加：「カルテ側から送られた処方の用法」にマッチする用法
    // がなかった場合、ポップアップメニューに空白アイテムが表示されたままになる。
    // default の用法が最初から表示されていると、修正忘れの起こる可能性あるため。
    _naiyouItems.push(""); 
    _tonyouItems.push("");
    _gaiyouItems.push("");
    
    var array = JSON.parse(buff);
    
    _debug("set NAIYO TONYO GAIYO->"+encodeObject(array)); //##
    
    for (i in array){
        var obj = array[i];
        switch (obj.type * 1){
            case 21 : _naiyouItems.push(trim(obj.value)); break;
            case 22 : _tonyouItems.push(trim(obj.value)); break;
            case 23 : _gaiyouItems.push(trim(obj.value)); break;
        }
    }
}

// 用法のリストの作成管理 ///////////////
//////////////////////////////////////


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

function patientId(){
    return parent().patientId();
}

function currentDate(){
    return parent().currentDate();
}

function valueInNoa(tag){
    // NOA における tag 相当の値を返す
    var obj = parent().valueForTag(tag, parent().currentDate());
    return (obj && obj.value) ? obj.value : "";
}

var _receivedObj;
function initReceivedObj(){
    // NOA から継承する情報を記憶
    _debug("== initReceivedObj =="); //##
    
    var date = parent().currentDate();
    _receivedObj = new Object();
    _receivedObj.currentDate = date;
    _receivedObj.patientId = patientId();
    _receivedObj.loginName = parent().userName();
    var hospInfo = parent().hospitalInfo();
    _receivedObj.hospitalName = hospInfo.hospitalName;
    _receivedObj.hospitalAddress = hospInfo.hospitalAddress;
    _receivedObj.hospitalPhone = hospInfo.hospitalPhone;
    _receivedObj.todoufukenBangou = hospInfo.divisionNumber;
    _receivedObj.tensuuhyouBangou = hospInfo.tableNumber;
    _receivedObj.iryoukikanCode = hospInfo.hospitalCode;
    
    // 基本情報などに HTML 属性があるとエラーになるのでプレーン・テキストに変換しておくこと
    var st = htmlToPlain(valueInNoa("NameSection.patientKanjiName"));
    _receivedObj.kanjiName = st;
    var st = htmlToPlain(valueInNoa("NameSection.patientKanjiName"));
    _receivedObj.name = st;
    var st = htmlToPlain(valueInNoa("NameSection.patientKanaName"));
    _receivedObj.furigana = st;
    
    _receivedObj.sex = valueInNoa("PatientTable.sex");
    _receivedObj.birthDay = valueInNoa("PatientTable.birthDate");
    _receivedObj.shubetsu = valueInNoa("HealthInsurance.shubetsu");
    _receivedObj.family = valueInNoa("HealthInsurance.kubun");
    _receivedObj.paymentRatio = valueInNoa("HealthInsurance.paymentRatio");
    _receivedObj.hokenshaBangou = valueInNoa("HealthInsurance.ownerNumber");
    _receivedObj.kigou = valueInNoa("HealthInsurance.kigou");
    _receivedObj.bangou = valueInNoa("HealthInsurance.bangou");
    _receivedObj.kouhiFutanBangou = valueInNoa("PublicInsurance.ownerNumber");
    _receivedObj.jyukyuuBangou = valueInNoa("PublicInsurance.recipientNumber");
    _receivedObj.kouhiMeishou = valueInNoa("PublicInsurance.ownerName");
    _receivedObj.kouhiKoufubi = valueInNoa("PublicInsurance.startDate");
    _receivedObj.kouhiYuukouKigen = valueInNoa("PublicInsurance.expiredDate");
    _receivedObj.kouhiFutanRatio = valueInNoa("PublicInsurance.paymentRatio");
    
    _debug(" _receivedObj->"+encodeObject(_receivedObj)); //##
    // 処方オブジェクト
    var buff = valueInNoa("ProgressSection.prescription");
    _debug("buff->"+buff); //##
    
    // buff に "=== 自費処方 ===" 行があれば別途処理
    if (buff.length > 0){
        var array = buff.split("\n");
        var firstRow = array[0];
        if (firstRow.indexOf("自費") >= 0){
            array.shift(); // ”自費" の文言の入った最初の行を削除
            buff = array.join("\n");
            _receivedObj.isOwn = "1";
        }
    }
    
    // 自費チェックボックスのステータスを表示
    var sp = elmFor("isOwnArea");
    sp.innerHTML = "";
    var status = (_receivedObj.isOwn) ? 1 : 0; // NOA データの自費フラッグを反映
    var cb = newCHECKBOX(sp, "isOwn", "自費 ", status);
    
    // NOA の処方欄の内容を取り込む
    var obj = prescription(buff);
    
    _receivedObj.prescription = obj;
    
    setPrescriptionObject(obj);
}    

function prescription(buff){
    if (buff.length == 0) return "";
    
    //   _initDebug(true); //##
    _debug("-- prescription buff("+buff+")"); //##
    
    // ## 平文形式の処方を以下のような object に encode して返す
    // 　頭につく "0.0": などは、それぞれのオブジェクトを識別するための
    // 　階層化された ID で、これを元に挿入・削除などの操作を行える。
    // "prescription":{
    //	"0":{
    //		"0.0":{"code":"0","name":"アドナ 10mg","dose":"6","unit":"Cap"},
    //		"0.1":{"code":"121","name":"分3内服食後","dose":"5","unit":"日分"}},
    //	"1":{
    //		"1.0":{"code":"0","name":"アデスタン","dose":"1","unit":"回分"},
    //		"1.1":{"code":"123","name":"外用","dose":"1","unit":"回分"}},
    //	"2":{
    //		"2.0":{"code":"0","name":"ニューロタン錠","dose":"1","unit":"Tab"},
    //		"2.1":{"code":"122","name":"屯用 就寝前","dose":"5","unit":"日分"}}
    // }
    var prscObj = new Object();
    var groupObj = new Object();
    
    // '\n' または '<br>' や '<div>' で改行されていることがあるので全てに対応
    buff = transferToCR(buff);
    //alert("buff("+buff+")"); //##
    var records = buff.split('\n');
    
    var gId = 0;
    var num = 0;
    var code = "0"; // 用法種別を示すコード
    for (i in records){
        var ln = records[i];
        if (trim(ln).length == 0) continue;
        
        if (ln.indexOf("-") == 0){ // 行頭が - で始まれば用法行
            // ln: "----- 分3内服 ８時間毎(5 日分)" のような形式
            code = codeWithString(ln); // "121","122","123" いずれかを返す
            // ln: "分3内服 ８時間毎(5 日分)" だけを後の処理へ渡す
            //   - の数が違っていても、その後に空白区切りがあれば用法行として認める
            var pos = ln.indexOf(" ");
            ln = trim(ln.substr(pos + 1));
        } else {
            // ln: "トランサミンカプセル 250mg(6 Cap)" のような形式 あるいは
            code = "" + num++; // (code < 100) で用法行ではない
        }
        _debug("<p>-- ln("+ln+") code->"+code+"</p>"); //##
        
        // ln を解析して、名前、投与量、単位、を記憶したオブジェクト:obj を生成
        var array1 = ln.split("(");
        if (array1.length > 1){
            var obj = new Object();
            var name = array1[0]; // "(" 以前は名称
            if (name.charAt(0) == "*"){ // generic へ変更禁止
                obj.name = trim(name.substr(1));
                obj.notGeneric = true;
            } else if (name.charAt(0) == " "){ // generic へ変換可
                obj.name = trim(name.substr(1));
            } else                    // 商品名
                obj.name = array1[0]; // "(" 以前は名称
            var ln2 = array1[1];
            var array2 = ln2.split(")");
            var ln3 = array2[0]; // ln3: "(...)"
            var array3 = ln3.split(" ");
            obj.dose = array3[0]; // (...) 中の空白区切り前が用量
            obj.unit = (array3.length > 1) ? array3[1] : ""; // 単位
            groupObj[code] = obj;
            _debug(code+"->"+encodeObject(obj)); //##
            
            if (code * 1 > 100){
                // 用法行に至ったので それを prscObj に記憶
                var _gid = ""+gId++;
                prscObj[_gid] = groupObj;
                // 次の用法のため環境を初期化
                num = 0; // group 内のレコード id を初期化
                groupObj = new Object(); // 新しい groupObj を生成
            }
        }
    }
    _debug("prscObj->"+encodeObject(prscObj)); //##
    
    return prscObj;
    
    
    function codeWithString(ln){
        // ln: "----- 分3内服 ８時間毎(5 日分)" のような形式からコードを判別して返す
        // "----" を削除し "分3内服 ８時間毎(5 日分)" にする
        var ary = ln.split(' ');
        ary.splice(0, 1); 
        ln = ary.join(' ');
        // "(5 日分)" を削除し "分3内服 ８時間毎" にする
        ary = ln.split('(');
        ln = trim(ary[0]);
        
        if (ln.indexOf("内服", 0) >= 0)
            return "121";
        else if (ln.indexOf("内用", 0) >= 0)
            return "121";
        else if (hasMember(naiyouItems(), ln) > 0)
            return "121";
        else if (ln.indexOf("屯", 0) >= 0)
            return "122";
        else if (ln.indexOf("頓", 0) >= 0)
            return "122";
        else if (hasMember(tonyouItems(), ln) > 0)
            return "122";
        else if (ln.indexOf("外用", 0) >= 0)
            return "123";
        else if (ln.indexOf("塗布", 0) >= 0)
            return "123";
        else if (hasMember(gaiyouItems(), ln) > 0)
            return "123";
        else
            return "0";
    }
}

function receivedObj(){
    // NOA のデータを元にした処方に必要な情報オブジェクト
    return _receivedObj;
}

var _prescriptionObject;
function setPrescriptionObject(obj){
    // 処方内容の構造を記憶: 処方が編集された時に呼ばれる
    //console.log("setPrescriptionObject", encodeObject(obj)); //##
    _prescriptionObject = obj;
}
function prescriptionObject(){
    // 編集中の処方オブジェクト
    // NOA の処方欄を元にした処方オブジェクトは _receivedObj.prescription に記憶
    return _prescriptionObject;
}
function maxGroupId(){
    // グループID　の最大値を返す
    var maxId = 0;
    
    // レコード削除などにより key が 1 から始まるとは限らないので
    // _prescriptionObject の数ではなく最大の key を検出
    for (key in _prescriptionObject){
        if (key * 1 > maxId) maxId = key * 1;
    }
    
    return maxId + 1;
}

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


///////////////////////////
/// Class のコンストラクタ ///

function RecordObj(obj){ // Record Object のコンストラクタ
    var newObj = new Object();
    newObj.code = obj.code; // 21,22,23
    newObj.alias = obj.alias;
    newObj.name = obj.name;
    newObj.generic = obj.generic;
    newObj.dose = obj.dose; // "6"
    if (obj.standard) newObj.dose = obj.standard;
    newObj.unit = unit(obj.unit); // obj.unit = "Tab 日分"
    newObj.freq = freq(obj.code, obj.unit); // obj.unit = "Tab 日分"
    newObj.handan = obj.handan;
    newObj.min = obj.min;
    newObj.standard = obj.standard;
    newObj.max = obj.max;
    newObj.width = obj.width;
    newObj.effect = obj.effect;
    newObj.memo = obj.memo;
    return newObj;
    
    function unit(val){
        if (!val) return val;
        
        var array = val.split(" ");
        return array[0];
    }
    
    function freq(code, val){
        if (!val) return val;
        
        var array = val.split(" ");
        if (array.length > 1)
            return array[1];
        else {
            switch (code * 1){
                case 21: 
                    return "日分";
                default:
                    return "回分";
            }
        }
    }
}	

/// Class のコンストラクタ ///
///////////////////////////


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

function getRecords(answer){
    //alert("getRecords->"+answer);
    
    if (answer && (answer.length > 0))
        setTableArray(answer);
    makePopupItems(tableNameArray());
}
function loadData(type){
    // PHPサーバへリクエストを送り、データが返送されたら func() で受ける
    var args = new Object();
    args['code'] = type;
    
    _callServer("GET_LIST", priceListServer(), args, getRecords);
}

function setUsageList(answer){
    // PriceList から用法リストを load
    //alert("=== setUsageList->"+answer); //##
    
    setYouhouItems(answer); // 用法リストを作成
    initReceivedObj(); // NOA から継承する情報を記憶
    showShohou(); // カルテ内の処方を表示：Ajax を呼んだ後のここで起動すること
}
function getUsageList(){
    // 用法リストをサーバへリクエスト
    _callServer("GET_USAGE_LIST", priceListServer(), null, setUsageList);
}

function gotGeneric(answer){
    // 対応する generic のテーブルがサーバから返ってきた
    //alert("gotGeneric->"+answer); //##
    
    // genObj = ["商品名":"一般名",,,]
    // 対応する一般名がない場合、一般名は ""
    var genObj = JSON.parse(answer);
    //_initDebug(true); //##
    _debug("== gotGeneric->"+encodeObject(genObj)+"\n"); //##
    
    var obj = prescriptionObject();
    for (num in obj){
        var group = obj[num];
        for (n in group){
            if (n > 100) continue;
            var rec = group[n];
            var generic = genObj[rec.name];
            _debug(rec.name+" genObj->"+encodeObject(genObj)+"\n"); //##
            
            // rec に generic 属性を追加
            // これを基に NOA で generic の有無を判断
            rec.generic = (generic && (generic.length > 0)) ? generic : "";
            
            _debug(rec.name+" generic->"+rec.generic+"\n"); //##
        }
    }
    //alert("gotGeneric obj:"+encodeObject(obj)); //##
    
    doSendPrescription(obj);
}
function getGeneric(obj){
    // generic のテーブルをサーバへ要求した後に処方箋を印刷
    var args = new Array();
    for (num in obj){
        var group = obj[num];
        for (n in group){
            var rec = group[n];
            if (rec.code > 100) continue;
            args.push(rec.name);
        }
    }
    
    _callServer("GET_GENERIC", priceListServer(), args, gotGeneric);
}


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

function isOwn(){
    return (document.getElementById("isOwn").checked) ? 1 : 0;
}


function firstCodeOf(ln){
    // "21,22" のような形式から最初のコードだけを取り出し数値として返す
    var array = ln.split(",");
    return trim(array[0]) * 1;
}

function numberOfRows(){
    // 処方の行数を返す（用法行も含む）
    return document.getElementById("contentsTable").childNodes.length;
}

function numberOfChildren(obj){
    // 処方グループに属する子供レコード数を返す
    var num = 0;
    for (groupId in obj) num++;
    
    return num;
}

function narrowsItems(type, key){
    // 絞り込みキーを基に popupMenu のコンテンツを作成
    if (key.length == 0) return;
    
    // 薬剤選択 popupMenu のコンテンツを作成
    var array = tableNameArrayForKey(type, key);
    makePopupItems(array);
}
function autoNarrowsItems(){
    // searchKey フィールドに文字が入力されるごとに作動
    var key = document.getElementById("searchKey").value;
    narrowsItems(0, key);
}

function recWithName(popupName, isGroup){
    // 薬剤名 popupName に相当する recObj を返す
    // (isGroup > 0) なら約束処方
    var records = tableArray();
    for (i in records){
        var recObj = records[i];
        var name = recObj.name;
        // code:"22,21"の場合の対応
        var code = firstCodeOf(recObj.code);
        if ((isGroup > 0) && (code < 100)) continue;
        if ((isGroup == 0) && (code > 100)) continue;
        if (isGroup > 0){
            if (name == popupName) return recObj;
        } else {
            if (name.indexOf(popupName) == 0) return recObj;
        }
    }
    return null;
}

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

function openManTool(name){
    // ガイド・パネルを開く
    window.open("./manTool.php?name="+name,"_blank");
}

function closeMan(){
    var elm = document.getElementById("message");
    elm.innerHTML = "";
}
function man(){
    // 薬剤添付書類を開く
    var name = selectedLimitedMenu();
    if (name == null) return;
    
    var rec = recWithName(name, 0);
    if (rec == null) return;
    
    // 添付書類の URL あれば表示
    var memo = rec.memo;
    var array = memo.split(" ");
    for (i=0,ct=array.length; i < ct; i++){
        var st = array[i];
        if (st.indexOf("URL:") >= 0){
            var ary = st.split(":");
            if (ary.length > 1){
                var url = ary[1];
                // url = "../../Medicine/medicine/" + url; // /X/NOA
                url = "../Medicine/medicine/" + url;
                window.open(url,"添付書類","width=1000,height=800,resizable=yes");
                return;
            }
        }
    }
    openManTool(name); // マニュアル取込ツールを開く
}

function clearHelp(){
    // HELP を消去
    document.getElementById("message").innerHTML = "";
}

function makePopupItems(menus){
    // 薬剤選択 popupMenu のコンテンツを作成
    var elm = document.getElementById("popupMenuArea");
    elm.innerHTML = "";
    
    var div = newDIV(elm, "popupMenuBar");
    
    // 薬剤名ポップアップ・メニュー
    makeLimitedMenu(div, menus, "", 15, "checkIfNew()");
    
    // 挿入ボタン
    var bt = newDIV(div, "/whiteButton");
    bt.innerHTML = "挿入";
    bt.setAttribute("onclick", "insertRecord()");
    bt.style.position = "relative";
    bt.style.top = "2px";
    
    // INFO ICON
    var im = newIMAGE(div, "icon", "./info.png", "?");
    im.setAttribute("onclick", "man()");
    im.style.width = "20px";
    im.setAttribute("class", "expandIcon");
    im.style.position = "relative";
    im.style.top = "8px";
    
    clearHelp(); // HELP を消去
}

function prescriptionToString(obj){
    // prescription オブジェクトを処方箋記述様式のテキストへ変換
    _debug("== prescriptionToString =="); //##
    _debug("obj->"+encodeObject(obj)); //##
    
    var buff = "";
    for (key in obj){
        var val = obj[key];
        if (typeof(val) == "object"){
            // グループの中を処理
            buff +=  prescriptionToString(val);
        }
        else if (obj.code == 999)
            continue; // コメントは無視
        else {
            // レコードの処理
            if (obj.code > 100) buff += "----- "; // 用法行の場合
            var mark = "";
            if (obj.code * 1 > 99){ // 用法行
                var name = obj.name;
            } else { // 薬剤行
                var isGeneric = (obj.generic && (obj.generic.length > 0));
                var name = (isGeneric) ? obj.generic : obj.name;
                
                // generic にチェック入らないものは行頭に '*' 印をつける：セパレータは除く
                if (obj.notGeneric) mark = "*";
                
                _debug("obj.name->"+obj.name); //##
                _debug("obj.generic->"+obj.generic); //##
                _debug("-- name ->"+name); //##
            }
            buff += mark + name + " ( " + obj.dose + " " + obj.unit + " )<BR/>";
            return buff;
        }
    }
    return buff;
}

function printPrescription(){
    // 処方箋の印刷パネルを生成して開く
    var robj = receivedObj();
    var obj = prescriptionObject();
    
    //    console.log("printPrescription", encodeObject(robj)); //##
    
    // 自費の場合 obj 中の保険情報を自費情報に置換
    if (isOwn()) robj = nullInrance(robj);
    
    // info は JSON 形式
    var ln = prescriptionToString(obj);
    
    ln += "- - - - - - - - - - 以 下 余 白 - - - - - - - - - -";
    var st = "./printPDF.php?"
    + "&info=" + JSON.stringify(robj)
    + "&doctorName=" + robj.doctorName
    + "&value=" + ln;
    
    window.open(st, "PDF", "dependent=yes");
    
    function nullInrance(obj){
        // obj 中の保険情報を自費情報に置換して返す
        obj.shubetsu = "";
        obj.family = "";
        obj.paymentRatio = "10";
        obj.hokenshaBangou = "";
        obj.kigou = "";
        obj.bangou = "";
        obj.kouhiFutanBangou = "";
        obj.jyukyuuBangou = "";
        return obj;
    }
}

function printShohou(){
    // 作成した処方箋を 印刷
    var preObj = prescriptionObject();
    // 処方に genric が含まれることを意味するフラッグ
    var hasGeneric = (isIncludeOfGeneric(preObj));
    // 薬局での generic へ交換禁止のフラッグ
    var noGeneric = (isNotGeneric(preObj));
    var doctorName = (noGeneric) ? receivedObj().loginName : "";
    
    // 処方情報の確認パネルを生成
    var elm = document.getElementById("_confirm");
    elm.innerHTML = "";
    
    var tbl = newTABLE(elm, "");
    tbl.style.width = "100%";
    
    var obj = receivedObj();
    obj.doctorName = doctorName;
    makeLine(tbl, "処方日", obj.currentDate.substr(0, 10));
    makeLine(tbl, "医療機関", obj.hospitalName);
    makeLine(tbl, "", obj.hospitalAddress);
    makeLine(tbl, "", obj.hospitalPhone);
    makeLine(tbl, "", obj.loginName);
    
    makeLine(tbl, "受診者", obj.kanjiName);
    makeLine(tbl, "", obj.sex);
    makeLine(tbl, "保険", obj.hokenshaBangou);
    makeLine(tbl, "", obj.shubetsu);
    makeLine(tbl, "", obj.family);
    makeLine(tbl, "", obj.paymentRatio);
    makeLine(tbl, "記号", obj.kigou);
    makeLine(tbl, "番号", obj.bangou);
    makeLine(tbl, "公費負担番号", obj.kouhiFutanBangou);
    makeLine(tbl, "受給番号", obj.jyukyuuBangou);
    var status = (noGeneric) ? "==== 後発品へ変更不可 ====" : "可";
    makeLine(tbl, "後発品へ変更", status);
    makeLine(tbl, "処方医", obj.doctorName);
    
    // 処方内容
    var obj = prescriptionObject();
    var buff = prescriptionToString(obj);
    var array = buff.split("<BR/>");
    for (i in array){
        var ln = trim(array[i]);
        if (ln.length == 0) continue;
        if (i == 0)
            makeLine(tbl, "処方", ln);
        else
            makeLine(tbl, "", ln);
    }
    
    if (hasGeneric)
        makeLine(tbl, "一般名処方", "generic");
    else 
        makeLine(tbl, "一般名処方", "なし");
    
    // FOOTER
    var tr = newTR(tbl, "", "");
    var td = newTD(tr, "float-footer", "");
    td.style.textAlign = "right";
    td.setAttribute("colspan", "2");
    var bt = newDIV(td, "/whiteButton");
    bt.innerHTML = "処方箋を印刷";
    bt.setAttribute("onclick", "printPrescription()");
    
    var x = 5; y = 0;
    openFloatPanel(tbl, x, y, "処方内容 確認パネル");
    
    function makeLine(tbl, key, val){
        var tr = newTR(tbl, "", "");
        var td = newTD(tr, "", key);
        td.style.fontSize = "8pt";
        td.style.color = "#333";
        td.style.width = "70px";
        td.style.backgroundColor = "ec9"; //＃light brown
        val = "" + val;  // paymentRatio などは数値の可能性あり文字列へ変換
        val = trim(val);
        if (val == "generic"){
            var td = newTD(tr, "", "＊＊ 一般名処方せん加算 ＊＊");
            td.style.fontSize = "10pt";
            td.style.padding = "0px 5px";
            td.style.fontWeight = "bold";
            td.style.color = "#00f"; //red
            // 一般名が処方内にあれば再計算を促す
        } else if (val && val.length){
            var td = newTD(tr, "", val);
            td.style.fontSize = "12pt";
            td.style.padding = "0px 5px";
            td.style.fontWeight = "bold";
            td.style.color = "#333";
        } else {
            var td = newTD(tr, "", "* データがありません *");
            td.style.fontSize = "10pt";
            td.style.padding = "0px 5px";
            td.style.fontWeight = "bold";
            td.style.color = "#f03"; //red
        }
    }
    
    function isIncludeOfGeneric(obj){
        // obj の中に genric が含まれるかどうかをチェック
        for (key in obj){
            var val = obj[key];
            if (typeof(val) == "object"){
                // グループの中を処理
                if (isIncludeOfGeneric(val)) return true;
            } else if (obj.code > 100)
                continue; // コメントは無視
            else {
                // レコードの処理
                if (obj.generic && (obj.generic.length > 0)){
                    //                if (obj.name != obj.generic){
                    return true;
                }
            }
        }
        return false;
    }
    
    function isNotGeneric(obj){
        // obj の中に generic に変換拒否の薬剤が有るかどうかをチェック
        for (key in obj){
            var val = obj[key];
            if (typeof(val) == "object"){
                // グループの中を処理
                if (isNotGeneric(val)) return true;
            } else if (obj.code > 100)
                continue; // コメントは無視
            else {
                // レコードの処理
                if (obj.notGeneric){
                    return true;
                }
            }
        }
        return false;
    }
}

function insertCellAtTerminator(newObj){
    // 終端行へ用法行もあわせて挿入
    //console.log("insertCellAtTerminator", encodeObject(newObj)); //##
    
    // 新しいグループを生成
    var newGroupObj = new Object();
    
    // 新しいグループへ newObj を挿入
    var newRecId = 0;
    newGroupObj[newRecId] = newObj;
    
    // 新しいグループへ default の用法行を生成して挿入
    var newRecId = 100 + selectedType() * 1;
    newGroupObj[newRecId] = youhouObject();
    
    // 新しいグループを処方オブジェクトに追加
    var obj = prescriptionObject();
    //console.log("prescriptionObject", encodeObject(obj)); //### TEST
    
    if (!obj) obj = new Object();
    var newGroupId = maxGroupId();
    
    obj[newGroupId] = newGroupObj;
    //console.log("obj", newGroupId, encodeObject(obj)); //### TEST
    
    setPrescriptionObject(obj);
    
    setCursorPosition(numberOfRows()); // カーソルをレコード挿入後の位置へ
    
    function youhouObject(){
        // 選択されている投与区分に応じた default の用法オブジェクトを生成して返す
        var youhouObj = new Object();
        var cd = selectedType() * 1;
        switch (cd){
            case 21: {
                var array = naiyouItems();
                youhouObj.code = "121";
                youhouObj.name = array[0]; // とりあえず最初のアイテム
                youhouObj.dose = 5;
                youhouObj.unit = "日分"; // default 値
            } break;
            case 22: {
                var array = tonyouItems();
                youhouObj.code = "122";
                youhouObj.name = array[0]; // とりあえず最初のアイテム
                youhouObj.dose = 5;
                youhouObj.unit = "回分"; // default 値
            } break;
            case 23: {
                var array = gaiyouItems();
                youhouObj.code = "123"
                youhouObj.name = array[0]; // とりあえず最初のアイテム
                youhouObj.dose = 1;
                youhouObj.unit = "回分"; // default 値
            } break;
        }
        return youhouObj;
    }
}

function insertCellAtCursorPosition(newObj){
    // radio-button:カーソル位置に rec を挿入
    //console.log("insertCellAtCursorPosition", encodeObject(newObj)); //##
    
    var obj = prescriptionObject();
    var resultObj = new Object();
    var row = 0;
    
    for (groupId in obj){
        var groupObj = obj[groupId];
        var newGroupObj = new Object();
        
        for (recId in groupObj){
            var recObj = groupObj[recId];
            //_debug("--- recObj: "+row+"<br>"+encodeObject(recObj)+"<br>"); //##
            
            // "21,22" などのコードの場合があるので、コードは内用・頓用などのタブから判定
            //    recObj.code = selectedType();
            
            if (row == cursorPosition()){
                // cursorPosition へ newObj を挿入
                //_debug("= newRecId: "+row+"->"+newObj.name); //##
                newGroupObj[row++] = newObj;
            }
            if (recObj.code < 100){
                //_debug("--- recId: "+row+"->"+recObj.name); //##
                newGroupObj[row] = recObj;
            } else {
                //_debug("separetor: "+recObj.code+"->"+recObj.dose); //##
                newGroupObj[recObj.code] = recObj;
            }
            row++;
        }
        resultObj[groupId] = newGroupObj;
        //_debug(groupId+"==>"+encodeObject(resultObj)+"<br>"); //##
    }
    setPrescriptionObject(resultObj);
    setCursorPosition(cursorPosition() + 1); // カーソル位置をひとつ下へ
}

function putGlobal(answer){
    // ### globalList から answer を受け取るため用意したメソッド
    //alert(answer);
    var rec = decodeObject(answer);
    rec.freq = 0;
    
    //alert(encodeObject(rec));
    
    // radio-button:カーソル位置に rec を挿入
    if ((numberOfRows() - 1) == cursorPosition()){
        // 終端行の場合は用法行もあわせて追加挿入
        insertCellAtTerminator(rec);
    } else {
        insertCellAtCursorPosition(rec);
    }
    showShohou();
}

function checkIfNew(){
    // "...その他"が選択されたらグローバル辞書登録パネルを開く
    var name = selectedLimitedMenu();
    if (name == "...その他"){
        // PriceListGlobal から薬剤を探す
        if (selectedType() == "23")
            var code = "23"; // 外用薬
        else
            var code = "21"; // 内服薬
        
        // ### globalList からのメッセージは putGlobal() で受ける
        var url = "../NOA/globalList.php?code=" + code + "&owner=" + parent().owner();
        
        window.open(url, "globalList"
                    , "scrollbars=yes,width=800,height=700");
    }
    clearHelp();
}
function insertRecord(){
    // popupMenu から選択された処方を挿入
    var name = selectedLimitedMenu();
    checkIfNew();  // "...その他"が選択されたらグローバル辞書登録パネルを開く
    
    //console.log("insertRecord", name, selectedType()); //##
    
    if (selectedType() > 100){ // 約束処方名 name に一致する処方データを検出
        var rec = recWithName(name, 1);
        if (rec == null) return;
        // memo の " が '&quot;' に encode されているので decode する
        var ary = rec.memo.split("&quot;");
        rec.memo = ary.join("\"");
        
        addYakusokuShohou(rec);
    } else { // 薬剤名 name に一致するレコードを検出
        var rec = recWithName(name, 0);
        if (rec == null) return;
        
        // "21,22" などのコードの場合があるので、コードは内用・頓用などのタブから判定
        rec.code = selectedType();
        
        // radio-button:カーソル位置に rec を挿入
        if ((numberOfRows() - 1) == cursorPosition()){
            // 終端行の場合は用法行もあわせて追加挿入
            insertCellAtTerminator(rec);
        } else {
            insertCellAtCursorPosition(rec);
        }
    }
    showShohou();
    
    function addYakusokuShohou(yakusokuObj){
        // 約束処方オブジェクトを処方末尾に追加
        var resultObj = new Object();
        var obj = prescriptionObject();
        var gid = 0; // obj が空の場合に使われる
        for (groupId in obj){
            var groupObj = obj[groupId];
            resultObj[groupId] = groupObj;
            //console.log(groupId, encodeObject(groupObj)); //##
            
            gid++; // 既存の処方オブジェクトの最後の groupId を記憶
        }
        
        // 既存の処方に約束処方を追加
        var yakuObj = eval('(' + yakusokuObj.memo + ')');
        for (_groupId in yakuObj){
            var groupObj = yakuObj[_groupId];
            resultObj[gid++] = groupObj;
        }
        
        setPrescriptionObject(resultObj);
        setCursorPosition(-1); // カーソル位置を末尾へ
    }
}

function removeRecord(){
    // 表示された処方箋を削除（DB 内容は変更しない）
    //console.log("removeRecord", numberOfRows(), cursorPosition()); //##
    if ((numberOfRows() - 1) == cursorPosition()){ // 削除行が tarminator なら 
        setPrescriptionObject(new Object());
        setCursorPosition(0);
    } else { // 削除行が tarminator 以外なら 
        // cursorPosition() のオブジェクトを削除
        var obj = prescriptionObject();
        var resultObj = new Object();
        var row = 0;
        for (groupId in obj){
            var groupObj = obj[groupId];
            for (recId in groupObj){
                var recObj = groupObj[recId];
                if (cursorPosition() == row++){
                    if (recObj.code > 100){ // 削除対象が用法行
                        // 用法グループをまとめて削除
            //            obj = deleteElement(obj, groupId);
                        delete obj[groupId];
                    } else { // 削除対象が薬剤行
                        if (children(groupObj) <= 2){
                            // 削除対象のグループが 対象行と用法行だけ ならグループごと削除
             //               obj = deleteElement(obj, groupId);
                            delete obj[groupId];
                        } else {
                            // 削除対象の薬剤行のみ削除
             //               obj[groupId] = deleteElement(groupObj, recId);
                            delete groupObj[recId];
                        }
                    }
                }
            }
        }
//        setPrescriptionObject(obj);
    }
    showShohou();
    
    function children(obj){
        // obj に属する子供の数を返す
        var num = 0;
        for (key in obj) num++;
        return num;
    }
    
/*    function deleteElement(obj, targetKey){
        // obj[targetKey] の要素を削除
        var newObj = new Object();
        for (key in obj){
            if (key == targetKey) continue;
            newObj[key] = obj[key];
        }
        return newObj;
    }*/
}

function radioClicked(no){
    setCursorPosition(no);
}


function markeToNameIfNotGeneric(obj){
    // generic 変換不可の薬剤名行頭に * をつける
    var newObj = new Object();
    for (key in obj){
        var val = obj[key];
        if (typeof(val) == "object"){
            // グループの中を処理
            newObj[key] =  markeToNameIfNotGeneric(val);
        } else if (obj.code == 999){
            // コメントはそのまま
            newObj[key] =  val;
        } else {
            // レコードの処理
            if (key == "name"){
                if (obj.notGeneric)
                    newObj[key] = "*" + obj.name; // generic へ変更禁止
                else if (obj.name != obj.generic)
                    newObj[key] = " " + obj.name; // generic
                else 
                    newObj[key] = obj.name;       // 商品名
            } else
                newObj[key] =  val;
        }
    }
    return newObj;
}
function doSendPrescription(obj){
    // 処方箋データを電子カルテ・クライアントへ送る
    // alert("sendPrescription === \n"+encodeObject(obj)); //##
    
    var robj = receivedObj(); // NOA 側から送られた情報
    robj.isOwn = (isOwn()) ? "1" : ""; // 自費フラッグをつける
    robj.prescription = prescriptionObject(); // こちら側で作成した処方を挿入
    //alert("doSendPrescription->"+encodeObject(robj)); //##
    
    // 処方内容を確認・印刷
    printShohou();
    
    // 処方箋を電子カルテ・クライアントへ返送
    var preObj = markeToNameIfNotGeneric(robj.prescription);
    robj.prescription = preObj;
    var value = encodeObject(robj); // NOA 形式の方が簡潔・確実な処理
    _debug("doSendPrescription: value->"+value); //##
    
    // NOA へ結果を返送
    var status = document.getElementById("touchAndGoCheck").checked;
    parent().getPrescription(value, status);
}
function sendPrescription(){
    // 「確定」ボタン：処方箋データを電子カルテ・クライアントへ送る
    var obj = prescriptionObject();
    
    // obj に generic を加えるようサーバへ依頼
    // サーバからの返答により doSendPrescription(obj) を起動
    getGeneric(obj);
}

function youhouChanged(cellId){
    // 用法行が変更された時に呼ばれ、変更結果を prescriptionObject に反映
    var obj = prescriptionObject();
    var array = cellId.split(".");
    var gid = array[0]; // group ID
    var rid = array[1]; // row ID
    var groupObj = obj[gid];
    var rowObj = groupObj[rid];
    
    // prescriptionObject の値を更新
    var item = document.getElementById("usage"+cellId).value;
    rowObj.name = item; // 変更された用法を更新
    
    setPrescriptionObject(obj);
}

function doseChanged(cellId, code, name){
    // 投与量が変更された時に呼ばれ、変更結果を prescriptionObject に反映
    // 用法行が変更された時に呼ばれ、変更結果を prescriptionObject に反映
    var obj = prescriptionObject();
    var array = cellId.split(".");
    var gid = array[0]; // group ID
    var rid = array[1]; // row ID
    var groupObj = obj[gid];
    var rowObj = groupObj[rid];
    
    // prescriptionObject の値を更新
    var item = document.getElementById("dose"+cellId).value;
    rowObj.dose = item; // 変更された用法を更新
    
    //alert("doseChanged:"+code+"^"+name+"^"+item); //##
    
    setPrescriptionObject(obj);
}

function unitChanged(cellId){
    // 投与量が変更された時に呼ばれ、変更結果を prescriptionObject に反映
    var obj = prescriptionObject();
    var array = cellId.split(".");
    var gid = array[0]; // group ID
    var rid = array[1]; // row ID
    var groupObj = obj[gid];
    var rowObj = groupObj[rid];
    
    // prescriptionObject の値を更新
    var item = document.getElementById("unit"+cellId).value;
    rowObj.unit = item; // 変更された単位を更新
    
    //alert("unitChanged:"+rowObj.name+"^"+rowObj.dose+"^"+item); //##
    
    setPrescriptionObject(obj);
}

function changeGeneric(groupId, recId){
    // recId のチェックボックスが変更された
    var obj = prescriptionObject();
    var groupObj = obj[groupId];
    var recObj = groupObj[recId];
    var cb = document.getElementById("generic"+recId);
    recObj.notGeneric = (cb.checked) ? 1 : 0;
}

function showShohou(){
    // obj:処方オブジェクトを HTML として展開表示
    var obj = prescriptionObject();
    //console.log("showShohou", encodeObject(obj)); //##
    
    var elm = document.getElementById("contentsArea");
    elm.innerHTML = "";
    var tbl = newTABLE(elm,"contentsTable");
    tbl.style.fontSize = "9pt";
    var no=0;
    for (groupId in obj){
        var freq = ""; // 日分、回分などの表示
        var groupObj = obj[groupId];
        for (recId in groupObj){
            var recObj = groupObj[recId];
            recObj.code = recId; // recId をコードとして recObj に記憶
            
            _debug("-- "+encodeObject(recObj)); //##
            
            // カーソル用ラジオボタン生成
            var tr = newTR(tbl,"","");
            var td = newTD(tr,"","");
            td.style.paddingLeft = "5px";
            var pu = newPopupItem(td, "cursorRadio", ""+no, "");
            
            if (no == cursorPosition())
                pu.setAttribute("checked", true);
            var action = "radioClicked('" + no + "')";
            td.setAttribute("onclick", action);
            no++;
            
            // code:"22,21"の場合の対応
            var code = firstCodeOf(recObj.code);
            var cid = groupId+"."+recId;
            
            if (code < 100){ // 薬剤行
                var td = newTD(tr,"","");
                var status = (recObj.notGeneric) ? 1 : 0;
                var cb = newCHECKBOX(td, "generic"+recId, "", status);
                
                // /NOA/dom.js 参照でないと以下は機能しない
                setInfoTip("generic"+recId, "後発品へ変更不可"); // HELP
                
                var action = "changeGeneric('"+groupId+"','"+recId+"')";
                cb.setAttribute("onchange", action);
                newTEXT(td, recObj.name);
                var td = newTD(tr,"","");
                var fd = newFIELD(td, "dose"+cid, "", 3, recObj.dose);
                var args = cid + "','" + recObj.code + "','"+ recObj.name;
                var action = "doseChanged('" + args + "')";
                fd.setAttribute("onchange", action);
                var td = newTD(tr,"",recObj.unit);
                freq = recObj.freq;
            } else { // isSeparator：用法行
                tr.setAttribute("class", "separator");
                var td = newTD(tr,"","");
                var youhouArray = setYouhouArray(code * 1); // 用法行を見て用法を判定
                _debug("youhouArray-> "+youhouArray); //##
                
                var pu = newPopupMenu(td, "usage"+cid, youhouArray, recObj.name);
                var action = "youhouChanged('"+ cid + "')";
                pu.setAttribute("onchange", action);
                
                var td = newTD(tr,"","");
                var fd = newFIELD(td, "dose"+cid, "", 3, recObj.dose);
                // recObj.name は doseChanged()中でポップアップ値から取得しなおすこと
                var args = cid + "','" + recObj.code + "','"+ recObj.name;
                var action = "doseChanged('" + args + "')";
                fd.setAttribute("onchange", action);
                
                var td = newTD(tr,"","");
                // 用法行の前の薬剤に freq(回数、個など) が設定されていればそれを使う
                if (freq && (freq.length > 0)) recObj.unit = freq;
                var fd = newFIELD(td, "unit"+cid, "", 3, recObj.unit);
                var action = "unitChanged('" + cid + "')";
                fd.setAttribute("onchange", action);
            }
        }
    }
    
    // terminator：最終行
    // 選択されたラジオボタン位置に薬剤が挿入されるので、これがないと最終行に追加できない
    // 最終行の削除で、すべてを一括削除できる
    var tr = newTR(tbl,"record","");
    
    var td = newTD(tr,"","");
    td.style.paddingLeft = "5px";
    var action = "radioClicked('" + no + "')";
    td.setAttribute("onclick", action);
    var pu = newPopupItem(td, "cursorRadio", ""+no, "");
    _debug("-- terminator -- "+pu); //##
    
    if (cursorPosition() < 0) setCursorPosition(numberOfRows() - 1);
    if (cursorPosition() == no)
        pu.setAttribute("checked", true);
    else if (cursorPosition() >= numberOfRows()){
        // 選択されたラジオボタンがない場合は最終ラジオボタンを操作対象とする
        setCursorPosition(numberOfRows() - 1);
        pu.setAttribute("checked", true);
    }
    
    var td = newTD(tr,"","");
    td.setAttribute("align", "right");
    td.setAttribute("colspan", "3");
    td.style.paddingRight = "10px";
    var bt = newDIV(td, "/grayButton");
    bt.innerHTML = "選択行削除";
    bt.setAttribute("onclick", "removeRecord()");
    
    
    function setYouhouArray(cd){
        switch (cd){
            case 121: return naiyouItems();
            case 122: return tonyouItems();
            case 123: return gaiyouItems();
        }
    }
}

function yakkouClicked(elm){
    // 薬効が選択されたら、それに一致した薬剤ポップアップを生成表示
    
    // 薬効リストを閉じる
    elmFor("yakkouListArea").innerHTML = "";
    
    // 絞込欄に選択された薬効を入れる
    var yakkou = elm.innerHTML;
    document.getElementById("searchKey").value = yakkou;

    // 絞込ボタン・欄を生成
    makeNarrowButtons();

    // 選択された薬効で絞込み
    narrowsItems(2, yakkou);
}
function showYakkouList(key){
    // 薬効リストを表示
    var div = elmFor("yakkouListArea");
    div.innerHTML = "";
    var array = effectArray();
    for (num in array){
        var item = array[num];
        if (key && key.length){
            if (item.indexOf(key) < 0) continue;
        }
        
        var sp = newDIV(div, "");
        sp.setAttribute("class", "blueButton");
        sp.innerHTML = item;
        var action = "yakkouClicked(this)";
        sp.setAttribute("onclick", action);
    }
}
function autoNarrowsYakkou(){
    // key で絞込み
    var key = elmFor("searchYakkouKey").value;
    showYakkouList(key);
}

function makeNarrowButtons(){
    // "薬効で絞込" ボタンを生成
    var elm = document.getElementById("narrowArea");
    elm.innerHTML = "";
    
    // 薬効で絞込みボタン
    var div = newDIV(elm, "narrowFrame"); // rarrowArea で設定するとうまくない
    var bt = newDIV(div, "/grayButton");
    bt.innerHTML = "薬効で絞込";
    bt.style.marginRight = "10px";
    bt.setAttribute("onclick", "showYakkouList()");
//    bt.setAttribute("onclick", "effectSelected()");
    
    // 検索フィールド
    var fd = newFIELD(div, "searchKey", "", 20, "");
    fd.setAttribute("placeholder", "文字で絞込み");
    fd.setAttribute("onkeyup","autoNarrowsItems()");
    fd.setAttribute("autocomplete","on");
    fd.focus();
    
    // サブメニューを消去して初期状態にする
    var smenu = document.getElementById("_submenu");
    smenu.style.visibility = "hidden";
}

///////////////////////////
/// Dtag and Drop /////////

function f_dragstart(event){
    // ドラッグ開始時の処理
    // ドラッグするデータのid名をDataTransferオブジェクトにセット
    event.dataTransfer.setData("text", prescriptionText());
    
    function prescriptionText(){
        var obj = prescriptionObject(); // 処方オブジェクト
        return "Rp)\n" + objectToShohouText(obj);
        
        function objectToShohouText(obj){
            // object をこの電子カルテの処方表示フォーマットへ変換
            // ## この関数は NOA の parts.js でも同じものが解凍用に使われている ##
            var buff = "";
            for (key in obj){
                var val = obj[key];
                if (typeof(val) == "object"){
                    // グループの中を処理
                    buff +=  objectToShohouText(val);
                }
                else {
                    // レコードの処理
                    if (obj.code > 100) buff += "----- "; // 用法行の場合
                    buff += obj.name + "(" + obj.dose + " " + obj.unit + ")\n";
                    return buff;
                }
            }
            return buff;
        }
    }
}

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

/// Dtag and Drop /////////
///////////////////////////

function openPliceList(){
    // PriceList を開く
    window.open("../NOAManager/priceList.php?mode=NOA","PriceList");
}

function showHistory(){
    // 処方箋の過去履歴を表示
    window.open("../Prescription/history.php?patientId=" + patientId()
                ,"History"
                ,"width=600,height=1000,scrollbars=yes,resizable=yes");
}

function setTabs(aType){
    // タブの行列を生成
    var _tabObjects = {"120":"約束","21":"内用","22":"屯用","23":"外用"};
    var _tabArray = ["120","21","22","23"];
    
    var div = document.getElementById("tabBase");
    div.innerHTML = "";
    var ul = newUL(div, "/listMembers");
    
    // _tabObjects をスキャンしたのでは順序が狂うので _tabArray を使う
    for (num in _tabArray){
        var type = _tabArray[num];
        var label = _tabObjects[type];
        var action = "setSelectedType('" + type + "')"
        var className = (aType*1 == type*1) ? "white-tab" : "gray-tab";
        
        // className は float:left なので逆順に並ぶことになる
        var li = newLI(ul, label);
        li.setAttribute("class", className);
        li.setAttribute("onclick",action);
    }
}

function closePrescription(){
    // 処方ツールを画面から削除
    if (window.name == "tools")
        document.getElementById("prescArea").innerHTML = "";
    else
        window.close();
}

function initPrescription(){
    // 処方パネルを初期化
    var elm = document.getElementById("partsArea"); // basicPage.js

    // ===== 処方ツール表示エリア =====================================
    var base = elmFor("prescArea"); 
    if (base) 
        base.innerHTML = ""; // 存のものがあれば空にし以下で再構成
    else
        base = newDIV(elm, "prescArea"); // 隠れたものがなければ新規作成
    
    // === HEADER =====
    var div = newDIV(base, "/tool-header");
    // --- LEFT SIDE ------------------------
    var dv = newDIV(div, "/left-side");
    // CLOSE ICON
    var im = newIMAGE(dv,"icon","./close.png","close");
    im.style.position = "relative";
    im.style.top = "3px";
    im.style.height = "11px";
    im.setAttribute("onclick", "closePrescription()");
    im.setAttribute("class", "expandIcon");
    // ラベル
    var bt = newDIV(dv, "/greenButton");
    bt.innerHTML = "処方箋";
    bt.setAttribute("onclick", "toggleNode('prescContents')");
    bt.style.marginLeft = "10px";
    // --- RIGHT SIDE -----------------------
    var dv = newDIV(div, "/right-side");
    var im = newIMAGE(dv, "", "./help.png", "?");
    im.setAttribute("onclick", "help()");
    im.style.height = "17px";
    im.setAttribute("class", "expandIcon");

    var cont = newDIV(base, "prescContents");
    cont.style.border = "thin solid #aaa";
    cont.style.borderRadius = "0 0 10px 10px";
    var dv = newDIV(cont, "message");

    // 約束、内用、頓用、外用、効能の選択エリア
    var div = newDIV(cont, "tabBase");
    div.style.marginBottom = "5px";
    div.style.backgroundColor = "#ffe";
    setTabs("");
    
    var div = newDIV(cont, "");
    div.style.borderTop = "thin solid #ddd";
    div.style.paddingLeft = "5px";
    div.style.backgroundColor = "#ffe";

    // 絞込みエリア ----------------------------------
    var dv = newDIV(div, "narrowArea");

    //  薬効リスト表示エリア  -------------------------    
    var dv = newDIV(div, "yakkouListArea");

    // 薬剤選択ポップアップ、挿入ボタンのエリア -----------
    var dv = newDIV(div, "popupMenuArea");
    
    // 処方内容の表示・編集エリア ======================
    var div = newDIV(cont, "contentsArea/tool-body");
    div.style.padding = "5px";
    div.setAttribute("draggable", "true"); // Drag out できるように設定
    div.setAttribute("ondragstart", "f_dragstart(event)");
    div.setAttribute("ondragover", "f_dragover(event)");
    
    // 注意事項行 ------------------------------------
    var div = newDIV(cont, "cautionArea");
    var obj = parent().valueForTag("BasicSection.allergy", currentDate());
    if (obj && obj.value){
        var sp = newSPAN(div, "");
        sp.style.paddingLeft = "10px";
        sp.style.color = "#aaa";
        sp.style.fontSize = "9pt";
        sp.innerHTML = "注意" ;
        var sp = newSPAN(div, "");
        sp.style.fontSize = "11pt";
        sp.style.color = "#f00";
        sp.innerHTML = obj.value ;
    }
    
    // === FOOTER ====================================
    var footer = newDIV(cont, "");
    
    var div = newDIV(footer, "/clearfix");
    div.style.fontSize = "9pt";
    var dv = newDIV(div, "/left-side");
    dv.innerHTML = version();
    dv.style.color = "#aaa";
    dv.style.width = "90px";
    var dv = newDIV(div, "/right-side");
    var sp = newSPAN(dv, "isOwnArea");
    var status = 0; // (receivedObj().isOwn) ? 1 : 0; // NOA データの自費フラッグを反映
    var cb = newCHECKBOX(sp, "isOwn", "自費 ", status);
    var status = isTouchAndGo();
    var cb = newCHECKBOX(dv, "touchAndGoCheck", " 確定保存", status);
    cb.setAttribute("onchange", "setTouchAndGo(this)");
    var bt = newDIV(dv, "/fixButton");
    bt.innerHTML = "確定";
    bt.setAttribute("onclick", "sendPrescription()");
    bt.style.position = "relative";
    bt.style.bottom = "3px"; // ボタン位置調整
    bt.style.marginLeft = "5px";
    bt.style.marginRight = "0";
    bt.style.position = "relative";
    bt.style.top = "0px";
    
    var div = newDIV(footer, "");
    div.style.clear = "both";
    
    // === メンテナンス用アンカーを置くエリア ================
    var ul = newUL(footer, "");
    ul.setAttribute("class", "listMembers");
    ul.style.padding= "0 0 8px 5px";
    var li = newLI(ul, "PriceList 編集");
    li.setAttribute("class", "listMember");
    li.setAttribute("onclick", "openPliceList()"); // source: usgeEditor.js
    var li = newLI(ul, "用法編集");
    li.setAttribute("class", "listMember");
    li.setAttribute("onclick", "showUsageEditor()"); // source: usgeEditor.js
    var li = newLI(ul, "約束処方");
    li.setAttribute("class", "listMember");
    li.setAttribute("onclick", "showGroupEditor()"); // source: groupEditor.js
    var li = newLI(ul, "過去履歴");
    li.setAttribute("class", "listMember");
    li.setAttribute("onclick", "showHistory()");
    
    // 約束処方登録エリア：usageEditor.js groupEditor.js で使う
    var dv = newDIV(cont, "pr_editorArea");

    var dv = newDIV(cont, "_submenu");

    // 処方内容を表示
    getUsageList();
}

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

