
var _itemArray; // = new Array(); // Global 変数
var _groupCode; // = new Array(); // Global 変数

function initItemArray(){
	_itemArray = new Array();
}
function setItemArray(array){
    _itemArray = array;
}
function itemArray(){
    return _itemArray;
}
function addItemArray(item){
	_itemArray.push(item);
}
function removeItemArray(number){
	for (var i=_itemArray.length-1; i >= 0; i--){
		var _item = _itemArray[i];
		if (number == _item.number) _itemArray.splice(i, 1);
	}
}
function countOfItemArray(){
	return _itemArray.length;
}
function itemAtIndexOf(ix){
	// itemArray の ix 番目の item を返す
	return (ix < _itemArray.length) ? _itemArray[ix] : null;
}
function itemWithId(number){
	// number を ID とする item を返す
	var count = _itemArray.length;
	for (var i=0; i < count; i++){
		var item = _itemArray[i];
		if (item.number == number) return item;
	}
	return null;
}

var _originalVinLabel;
function setOriginalVinLabel(label){
    _originalVinLabel = label;
}
function originalVinLabel(){
    // 診療入力を開いた CELL の ラベル名
    return _originalVinLabel;
}

var _currentRecords; // = new Array(); // Global 変数
function setCurrentRecords(array){
	// 現在選択されているレコードの値を記憶
	_currentRecords = array;
}
function currentRecords(){
	return _currentRecords;
}

function groupCode(){
	// 診療行為のコード番号を返す
	return _groupCode;
}
function setGroupCode(code){
	// 診療行為の種類が選択された
	if (_groupCode){
		var elm = document.getElementById("item:"+_groupCode);
		elm.style.backgroundColor="#bfe";
		elm.style.color="#000";
	}
	
	_groupCode = code;
	var elm = document.getElementById("item:"+code);
	elm.style.backgroundColor="#00f";
	elm.style.color="#ffa";
    
    //console.log("setGroupCode", code); //##
	
	getItemList(code);
}

var _medicalActions;
function setMedicalActions(obj){
    //alert("setMedicalActions->"+encodeObject(obj)); //##
    
    _medicalActions = obj;
}
function medicalActions(){
    // 診療行為メニュー・オブジェクトを返す
    return _medicalActions;
}

//////////////////////////////////
///// HospitalTable からの継承値 ///

var _round; // Global 変数
var _ownRate; // Global 変数
function setHospitalInfo(obj){
	// obj = "round(5)ownRate(20)"
    _round = obj.round;
    _ownRate = obj.ownRage;
}

function ownRate(){
	// 自費料金を計算するための点数への掛け率
	return _ownRate;
}

///// HospitalTable からの継承値 ///
//////////////////////////////////



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

function parameters(){
	// patientId, ageOfTheMoon
	// を vinServer へ渡すための変数パッケージ
	var array = new Array();
	array['owner'] = parent().owner();
	array['hospitalId'] = parent().hospitalId();
	array['patientId'] = parent().patientId();
	array['entryDate'] = parent().currentDate();
	array['age'] = ageOfTheMoon();
	var elm = document.getElementById("timeZone");
	array['timeZone'] = (elm) ? elm.value : "";
    if (hasTax()) array['taxRate'] = taxRate() / 100; // 消費税
    var tzone = elmFor("timeZone").value; // タイムゾーン・ポップアップの値
	array['isInTime'] = (tzone == "時間内") ? 1 : 0;
	array['isHoliday'] = (parent().todayIsHoliday()) ? 1 : 0;
    //console.log("parameters", encodeObject(array)); //##
    
	return array;
	
	function ageOfTheMoon(){
		// patientId と本日の年月日から年齢を計算して返す
		var pid = parent().patientId();
		var yy = pid.substr(4,2) * 1;
		var yyyy = (yy > 25) ? 1900 + yy : 2000 + yy;
		var mm = pid.substr(0,2) * 1;
		var dd = pid.substr(2,2) * 1;
		var birthDate = yyyy + "-" + mm + "-" + dd;

		return ageAtDate(birthDate, parent().currentDate());
	}
}

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


///////////////////////////////////////
///// レコードの文字列化はここで管理     ///
///// vin.php 側では newItem() で管理 ///

function archives(){
	// itemArray を 診療行為の表示行 に変換して返す
    // 「テンプレート登録」に使う
    _debug("== archives =="); //##
    var results = new Array();
    var array = treatmentArray();
    if (array.length > 0){
        for (num in array){
            var rec = array[num];
            var ln = treatmentFormat(rec);
            results.push(ln);
        }
    }
    return results.join("\n");
}

function treatmentArray(){
	// itemArray を 診療行為オブジェクトの配列 に変換して返す
    // 「サーバへ計算依頼」に使う
	var array = new Array();
	var count = countOfItemArray();
	if (count > 0){
        var items = itemArray();
        for (num in items){
            var item = items[num];
            if (item.code % 10 == 9) continue; // 自動付加行はスキップ
            if (item.code * 1 == 13) continue; // 自動付加行はスキップ
            
            array.push(encodeItemObj(item));
        }
    }
    //console.log("treatmentArray", encodeObject(array)); //##
    
	return array;
    

    function encodeItemObj(item){
        // item を 診療行為オブジェクト に変換して返す
        //alert("encodeItem->"+encodeObject(item)); //##
        
        var rec = new Object();
        rec.number = item.number;
        rec.isOwn = (item.isOwn * 1 > 0) ? 1 : 0;
        rec.code = item.code;
        rec.alias = item.alias;
        rec.name = item.name;
        rec.dose = item.dose;
        rec.standard = item.dose;
        if ((rec.standard.length == 0) || (rec.standard * 1 == 0))
            rec.standard = 1;
        rec.unitName = item.unitName;
        rec.freq = item.freq;
        rec.point = item.point; // 空データの場合は calc() 時にサーバ側で PriceList から補完
        rec.isMix = item.isMix;
        rec.editable = 0;
        
        // 名前の頭に "+ " があれば混注
        if (item.name.indexOf("+ ") >= 0){
            rec.isMix = "1";
            rec.name = item.name.substr(2);
        }
        
        return rec;
    }
}

function codeArray(){
    // コード番号の配列を返す
    return [11,12,13,21,22,23,29,31,32,33,41,48,51,52,58,60,69,70,80,90,91];
}
function codeName(code){
    // ### vinServer.js の codeName() と同じであること ###
    switch (code * 1){
        case 11: return "初診";
        case 12: return "再診";
        case 13: return "診他";
        case 21: return "内服";
        case 22: return "屯服";
        case 23: return "外用";
        case 29: return "薬加";
        case 31: return "皮注";
        case 32: return "静注";
        case 33: return "点滴";
        case 41: return "処置";
        case 48: return "処薬";
        case 51: return "手術";
        case 52: return "麻酔";
        case 58: return "手薬";
        case 60: return "検査";
        case 69: return "判断";
        case 70: return "画像";
        case 80: return "其他";
        case 90: return "入院";
        case 91: return "入他";
        default: return "";
    }
}
function codeForName(name){
    // name に対応する code を返す
    var array = codeArray();
    for (num in array){
        var code = array[num];
        var nm = codeName(code);
        if (name == nm) return code;
    }
    return 0;
}

function newItem(rec){
    // rec = isOwnFee(0)code(11)alias()name(初診)dose()unitName()freq(1)point(270)isMix()
	// アイテム属性を記憶した Item Class を生成し itemArray に保存
    //_debug("== newItem->"+encodeObject(rec)); //##
    
	var item = new Object();
	var number = countOfItemArray();
    
	item.number = number; // item の ID (必ずしも itemArray 中の順番ではない)
	item.subItems = new Array();
	item.isOwn = rec.isOwn; // ####
	item.code = rec.code;
	item.alias = rec.alias;
	item.name = rec.name;
	item.dose = (rec.dose * 1 > 0) ? rec.dose : 1;;
	item.standard = (rec.standard * 1 > 0) ? rec.standard : 1;
	item.unitName = rec.unitName;
	item.freq = (rec.freq * 1 > 0) ? rec.freq : 1;;
	item.point = rec.point; // 空データの場合は calc() 時にサーバ側で PriceList から補完
	item.isMix = rec.isMix;
	item.editable = 0;

    // 名前の頭に "+ " があれば混注
    if (item.name.indexOf("+ ") >= 0){
        item.isMix = "1";
        item.name = item.name.substr(2);
    }
    
	addItemArray(item); // number を取り出した後で実行すること

	return item;
}

function doseChanged(row){
    // row 行目のレコードの単位数が変更された
    var item = itemAtIndexOf(row);
    item.dose = document.getElementById(row + ".dose").value;
}

function freqChanged(row){
    // row 行目のレコードの回数が変更された
    var item = itemAtIndexOf(row);
    item.freq = document.getElementById(row + ".freq").value;
}

///// レコードの文字列化はここで管理 ///
///////////////////////////////////

///////////////////////////////////
/// vinHistory に関する処理 /////////

function putHistory(records){
    // 過去履歴から選択された内容を診療行為へセット
    var array = new Array();
    var no = 0;
    for (num in records){
        var ln = records[num]; // 内服[アドナ錠１０ｍｇ(3 錠)] 2 x 5 自費
        //console.log(ln); //##
        if (ln.length == 0) continue;

        var ary = ln.split("[");
        var codest = trim(ary[0]); // 内服
        if (codest == "合計") continue;
        
        var rec = new Object();
        rec.code = codeForName(codest);
        if (rec.code % 10 == 9) continue; // code の下一桁が 9 は自動追加項目
        
        ln = ary[1]; // アドナ錠１０ｍｇ(3 錠)] 2 x 5 自費
        ary = ln.split("]");
        ln = ary[0]; // アドナ錠１０ｍｇ(3 錠)
        var right = ary[1]; //  2 x 5 自費
        ary = ln.split("(");
        var st = ary[0]; // アドナ３０ｍｇ
        ary = st.split("+ ");
        if (ary.length > 1){
            rec.name = ary[1];
            rec.isMix = "1";
        } else {
            rec.name = ary[0];
            rec.isMix = "";
        }
        rec.number = no++; // records からは検出できない
        rec.alias = ""; // records からは検出できない
        rec.dose = "";
        rec.unitName = "";
        if (ary.length > 1){
            var st = ary[1]; // 3 錠)
            ary = st.split(")");
            st = ary[0];
            ary = st.split(" ");
            if (ary.length > 1){
                rec.dose = ary[0];
                rec.unitName = ary[1];
            }
        }
        // "2 x 5 自費" の処理
        ary = right.split("自費");
        if (ary.length > 1)
            rec.isOwn = "1";
        else
            rec.isOwn = "";
        ln = ary[0];
        ary = ln.split("x");
        rec.point = trim(ary[0]) * 1;
        rec.freq = 1;
        if (ary.length > 1)
            rec.freq = trim(ary[1]) * 1;
       
        array.push(rec);
        //console.log(encodeObject(rec)); //##
    }
    
    // records を診療入力ツールに入力
    setItemArray(array);
    //console.log("itemArray", encodeObject(itemArray())); //##
    
    showItemList();
}

/// vinHistory に関する処理 /////////
///////////////////////////////////

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

function selectedGroupMenu(){
    // 一括が選択されているなら true を返す
    var gcode = groupCode() * 1; // 選択されているポップアップのコード：一括はコード0
    var itemName = (gcode == 0) ? selectedLimitedMenu() : ""; // 選択されたポップアップ名
    
    var elm = elmFor("setNameF");
    if (elm){
        var title = elm.value;
        
        return (itemName && isSame(itemName, title)) ? true : false;
    } else {
        return false;
    }
}

function savedTemplate(answer){
	// テンプレートが保存された後の処理
    // 更新された内容を再読込
    //console.log("savedTemplate", answer); //##
    
    elmFor("templateArea").innerHTML = "";
	getHeader();
}
function saveTemplate(){
    // 一括テンプレートをサーバへ保存
    // 一括メニュー・ポップアップが表示されていれば選択された一括メニュー項目を取得
    var title = elmFor("setNameF").value;
	if (title.length == 0){
		alert("セット名を入れてから登録してください");
		return;
    } else if (selectedGroupMenu()){
		if (!confirm("セット登録をこの内容で上書きしていいですか？")) return;
	}
    
	// 現在表示されているレコード・セットをテンプレートとして登録
    var args = new Object();
    args.owner = parent().owner();
    args.title = title;
    args.records = archives();
    //console.log("saveTemplate", encodeObject(args)); //##
    
    NRCallVin("PUT_TREATMENT_GROUP", args, savedTemplate);
}

function rmoveTemplate(){
    var title = elmFor("setNameF").value;
    if (!confirm(title + "　のセット登録を削除していいですか？")) return;
    
    // 現在表示されているレコード・セットをテンプレートとして登録
    var args = new Object();
    args.owner = parent().owner();
    args.title = title;
    //console.log("args", encodeObject(args)); //##
    
    NRCallVin("REMOVE_TREATMENT_GROUP", args, savedTemplate);
}

function getTimeZone(buff){
	// ",,0000,0600,深夜^,,2200,2400,深夜^,日,0000,2400" 形式を解析して時間区分を返す
	var year = parent().currentDate().substr(0, 4);
	var month = parent().currentDate().substr(5, 2);
	var day = parent().currentDate().substr(8, 2);
	var date = new Date(year, month - 1, day);
	var d = date.getDay();
	var week = _weeks[d];
	var weekNum = Math.ceil(day / 7);
	var hour = parent().currentDate().substr(11, 2);
	var min = parent().currentDate().substr(14, 2);
	var time = hour + min;
	
	// 指定した日時の時間区分をチェックする
	var array = decodeCSV(buff);
    for (row in array){
		var obj = array[row];
		var result = timeZone(obj,weekNum,week,time);
        
		if (result.length > 0){
			return result;
		}
	}
	return "時間外";
	
	function timeZone(obj, weekNum, week, time){
		// 時間区分を返す
		if (obj.num)
			if (obj.weekNum != weekNum) return "";
		if (obj.week)
			if (obj.week != week) return "";
		if (obj.from > time)
			return "";
		if (obj.to < time)
			return "";
		return obj.timeZone;
	}
	
	function decodeCSV(csv){
		// csv を conditions オブジェクトへ変換
		var results = new Array();
		var array = csv.split("^");
        for (row in array){
			var ln = trim(array[row]);
            
			var ary = ln.split(",");
			if (ary.length == 5){
				var obj = new Object();
				obj.weekNum = ary[0];
				obj.week = ary[1];
				obj.from = ary[2];
				obj.to = ary[3];
				obj.timeZone = ary[4];
				results.push(obj);
			}
		}
		
		if (results.length == 0){
			// csv に解析できるものがなければ default 条件を生成定
			var obj = new Array();
			obj.from = "0000";
			obj.to = "0600";
			obj.timeZone = "深夜";
			results.push(obj);
			
			var obj = new Array();
			obj.from = "2200";
			obj.to = "2400";
			obj.timeZone = "深夜";
			results.push(obj);
			
			var obj = new Array();
			obj.week = "日";
			obj.from = "0000";
			obj.to = "2400";
			obj.timeZone = "休日";
			results.push(obj);
			
			var obj = new Array();
			obj.from = "0900";
			obj.to = "1200";
			obj.timeZone = "時間内";
			results.push(obj);
		}
		
		return results;
	}
}

/////////////////////////////////////////////////////////////
///// Ajax: VIN は独立して動くので LOGIC:neuron.js の部分を内部に持つ

function setItemMatrix(elm, action){
    // 診療行為マトリックスを生成：vinCalcChecker.js からも利用される
    // obj = 一括(00) 初診(11) 再診(12) 診他(13) 内服(21) 屯服(22) 外用(23) 薬加(29) 皮注(31) 静注(32) 点滴(33) 処置(41) 処薬(48) 手術(51) 麻酔(52) 手薬(58) 検査(60) 判断(69) 画像(70) 其他(80) 入院(90) 入他(91)
    var obj = medicalActions().itemMatrix;
    var ul = newUL(elm, "");
    ul.setAttribute("class", "listMembers");
    for (key in obj){
        var code = obj[key];
        var li = newLI(ul, key);
        li.setAttribute("id", "item:"+code);
        li.setAttribute("class", "blueButton");
        li.setAttribute("onclick", action + "('" + code + "')");
    }
}

function gotCheckList(answer){
    var obj = JSON.parse(answer);
    setCheckList(obj); // vinCalcChecker.js
    
    // フィルターを読み込んでおく
    getFiter();
}
function putHeader(answer){
	// サーバから返されたヘッダー部分を表示
    initItemArray();
    var obj = JSON.parse(answer);
    setMedicalActions(obj);

    _log(["== vin: putHeader", encodeObject(obj)]); //##

    // alert("putHeader->"+encodeObject(obj)); //##
    
    // 「診療入力」ツールの「自費料金に外税を加算」チェック・ボックスを表示
    setHasTaxCheckbox();

    // 診療行為マトリックスを表示
    var elm = document.getElementById("matrixArea");
    elm.innerHTML = "";
    setItemMatrix(elm, "setGroupCode");

    // 診療時間帯ポップアップメニューを表示
    var timeZone = getTimeZone(obj.timeZone);
    
    setTimeZonePopup(timeZone); //## とりあえず
    
    // hospitalTable などから施設固有値を得る: まるめ係数・自費係数
    setHospitalInfo(obj.hospitalInfo);
    
    //console.log("itemList", encodeObject(obj.itemList)); //##
        
    // カルテが記憶していた診療行為セットを itemArray にセット
    var itemList = obj.itemList;
    if (itemList.length > 0){
        for (num in itemList){
            var rec = itemList[num];
            // この中の point はカルテの treatment フィールドから
            // 読み出されたものなので point * dose 処理がされている
            // ln:静注[ピドキサール注１０ｍｇ(1 管) 混注] 6
            newItem(rec);
        }
        showItemList();
    }

    // 病名チェッカーのチェックリストを読み込む
    NRCall("GET_DISEASE_FROM_PRICELIST", null, gotCheckList);

    function setHasTaxCheckbox(){
        //「診療入力」ツールの「自費料金に外税を加算」チェック・ボックスを表示
        var elm = elmFor("hasTaxArea");
        elm.innerHTML = "";
        var cb = newCHECKBOX(elm, "hasTaxBox", "自費料金に外税を加算", vin_hasTax());
    }
	
	function setTimeZonePopup(currentTimeZone){
		// 診療行為ポップアップメニューを生成
		var array = ["時間内","時間外","休日","深夜"];
		var elm = document.getElementById("timeZoneArea");
        elm.innerHTML = "";
		var pu = newPopupMenu(elm, "timeZone", array, currentTimeZone);
	}
}
function getHeader(){
	// onload で起動されるアクション：サーバにヘッダー部分の生成を依頼し表示
    var args = new Object();
    args['owner'] = parent().owner();
    args['hospitalId'] = parent().hospitalId();
    args['patientId'] = parent().patientId();
    args['entryDate'] = parent().currentDate();
    args['age'] = ageOfTheMoon();
    var elm = elmFor("timeZone");
    args['timeZone'] = (elm) ? elm.value : "";

	NRCallVin("GET_VIN_HEADER", args, putHeader);

    function ageOfTheMoon(){
        // patientId と本日の年月日から年齢を計算して返す
        var pid = parent().patientId();
        var yy = pid.substr(4,2) * 1;
        var yyyy = (yy > 25) ? 1900 + yy : 2000 + yy;
        var mm = pid.substr(0,2) * 1;
        var dd = pid.substr(2,2) * 1;
        var birthDate = yyyy + "-" + mm + "-" + dd;
        
        return ageAtDate(birthDate, parent().currentDate());
    }
}

///// Ajax: VIN は独立して動くので LOGIC:neuron.js の部分を内部に持つ
/////////////////////////////////////////////////////////////



var _items;
function setItems(array){
	_items = array;
}
function items(){
	return _items;
}

var _aliases;
function setAliases(array){
	_aliases = array;
}
function aliasForTitle(title){
	return _aliases[title];
}

//////////////////////////////////////////////////////////////
///// 添付書類表示 /////////////////////////////////////////////

var _manName;
function gotMan(answer){
	// 添付書類の URL あれば表示
    if (trim(answer).length > 0){
        var obj = JSON.parse(answer);
        //console.log("gotMan", encodeObject(obj)); //##
        
        var memo = obj.memo;
        var array = memo.split("URL:");
        if (array.length > 1){
            var st = array[1];
            var ary = st.split(" ");
            var url = ary[0];
            url = "../Medicine/medicine/" + url;
            window.open(url,"添付書類","width=1000,height=800,resizable=yes");
            return;
        }
    }
    
    // マニュアル取込ツールを開く
	window.open("../Prescription/manTool.php?name="+_manName,"_blank");
}
function man(){
    // 添付書類をサーバへ要求
    var code = groupCode(); // 診療行為のコード番号
    //console.log("code", code); //##
    
    // 内服や注射以外は無視
    var array = [21, 22, 23, 31, 32, 33];
    if (indexOfArray(array, code) < 0) return;

    var item = selectedLimitedMenu();
    //console.log("item", item); //##
    
    if (item.length > 0){
        _manName = item;
        var args = new Object();
        args["code"] = code;
        args["name"] = item;
        NRCall("GET_PRICE_LIST", args, gotMan);
    }
}
function showInfoIcon(elm){
    // 添付書類表示アイコンを表示
    var im = newIMAGE(elm, "", "./info.png", "?");
    im.setAttribute("onclick", "man()");
    im.style.height = "18px";
    im.style.position = "relative";
    im.style.top = "5px";
    im.setAttribute("class", "expandIcon");
}

///// 添付書類表示 /////////////////////////////////////////////
//////////////////////////////////////////////////////////////

function putItemList(answer){
    // アイテムリストを表示する
    var obj = JSON.parse(answer);
    //_debug("== putItemList == "+encodeObject(obj)); //##
    
    // "itemSelectorArea" の上にポップアップメニュー生成
    var elm = document.getElementById("itemSelectorArea");
    elm.innerHTML = "";
    var items = new Array();
    var aliases = new Array();
    var item = "";
    
    // obj は {"再診料":"saishin",,} のようなオブジェクトの配列
    for (title in obj){
        var value = obj[title];
        if (title.length == 0) continue;
        if (title == "_date_check_") continue;
        
        items.push(title);  // title:"再診料"
        aliases[title] = value; // value:"saishin"
        if (isSame(value, "shoshin")) 
            item = title;
        else if (isSame(value, "saishin")) 
            item = title;
    }
    items.splice(0, 0, "");
    items.push("...その他");
    setItems(items);
    setAliases(aliases);
    
    // item 選択ポップアップを表示
    makeLimitedMenu(elm, items, item, 20, "itemSelected()");
    
    itemSelected();
    
    // INFO アイコンを表示
    var sp = newSPAN(elm, "");
    sp.style.marginLeft = "5px";
    showInfoIcon(sp);
    
    // 絞り込みフィールドを生成
    makeForcusOnArea();
    
    document.getElementById("_message").innerHTML = "";
}
function getItemList(num){
	// 診療行為マトリックスの選択で起動され、該当アイテムリストをリクエスト
    // 「一括」の場合 num は "00"
    var args = new Object();
    args.code = num;
    NRCallVin("GET_CHILD_SELECTOR", args, putItemList);
}

function putItem(){
	// 選択されたアイテムの入力欄を再描画
	if ((xmlHttpObject.readyState == 4) && (xmlHttpObject.status == 200)){
		var value = xmlHttpObject.responseText;
        //alert("putItem->"+value); //##
		
		var array = value.split("<SEPARATOR>");
		if (array.length > 1){
			// array[1] = "_|_21_|_pill_|_低用量ピル_|_28_|_Tab_|_53_|_0"
			// 一括テンプレートの場合は複数レコード
			var records = JSON.parse(array[1]);
            //console.log("== putItem", encodeObject(records)); //##
            
			// ここでは選択されたアイテムに対するレコードをサーバの PriceList から得たもの
			// なので point * dose 処理がされていない。従って point は全て空にしておく。
			// 空 point だと calc() の時に PriceList の点数で補完される。
            records = pointToEmpty(records);
			
			// code に応じて「数量」「頻度」入力欄を表示
			// records[0] = "1_|_21_|_pill_|_低用量ピル_|_28_|_Tab_|_1060_|_0" 形式
			setCurrentRecords(records);
			showDoseAndFreqField(records[0]);
			
			document.getElementById("_message").innerHTML = "";
		} else
			document.getElementById("_message").innerHTML = value;
	} else 
		document.getElementById("_message").innerHTML = "Loading...";

    function pointToEmpty(records){
        // record 中の point を全て空にする。
        // 空 point だと calc() の時に PriceList の点数で補完される。
        for (num in records){
            // "0_|_21_|_adona30mg_|_アドナ30mg_|_3_|_Tab_|_1_|_12.9_|_0" 形式のレコード
            var rec = records[num];
            if (rec) rec.point = "";
        }
        return records;
    }
}
function getItem(){
	// itemSelector（薬剤名など）が選択された時に作動
    var args = new Object();
    args.isOwn = (document.getElementById("isOwn").checked) ? 1 : 0;
    args.code = groupCode();
    
    var item = selectedLimitedMenu();
//    var item = document.getElementById("itemSelector").value;
    args.alias = aliasForTitle(item);
    args.owner = parent().owner();
    
    NRCallVin("GET_ITEM", args, putItem);
}

function overlappedItem(){
    // 重複した診療行為があればそれを返し、なければ null を返す
    var obj = new Object();
    var array = itemArray();
    for (num in array){
        var rec = array[num];
        var item = rec.code + ":" + rec.name;

        // item の重複をチェックするため obj の引数にする
        if (obj[item]) return item;

        obj[item] = "dummy";
    }
    return false;
}

function treatmentFormat(obj){
    // NOA へ返送する 診療行為フォーマット に変換
    // "外用[ホーリンV錠 (2 錠)] 220 x 2 自費" のような形式の一行を生成
    var own = (obj.isOwn * 1) ? " 自費" : "";
    
    if (obj.code * 1 == 99){
        return obj.name;
    } else {
        var freq = (obj.freq * 1 > 1) ? " x " + obj.freq : "";
        var cd = codeName(obj.code);
        
        // 混注の子の場合は名称の先頭に "+ " をつける
        var name = (obj.isMix * 1 > 0) ? "+ " + obj.name : obj.name;
        
        // 単位がある場合は (単位数 単位) を表示
        var doseUnit = (obj.unitName.length > 0)
        ? "(" + obj.dose + " " + obj.unitName + ")" : "";
        
        if (obj.name.length == 0)
            return cd + "" + obj.point + freq + own;
        else
            return cd + "[" + name + doseUnit + "] " + obj.point + freq + own;
    }
}

function putResultOfCalc(answer){
    //alert("putResultOfCalc->"+answer); //##
    initItemArray();
    var parentRow = (-1);
    var parentPoint;
    var records = JSON.parse(answer);
    //alert("putResultOfCalc: records->"+encodeObject(records)); //##
    
    for (num in records){
        var rec = records[num];
        if (rec) {
            //_debug("rec->"+encodeObject(rec)); //##
            
            var obj = newItem(rec); // ここでレコードを itemArray() に追加
            // obj = "isOwn(0)code(11)alias()name(初診)standard(1)unitName()freq(1)point(270)isMix()"
            
            // 混注に関する処理を行う
            if (obj.isMix == "0"){ // 混注の親レコード
                parentRow = num;
                parentPoint = obj.point * 1;
            } else if (obj.isMix * 1 > 0){ // 混注の子レコード
                parentPoint += obj.point * 1; // 親の点数に子の点数を加算
                obj.point = ""; // 子の点数は空白にする
            } else { // 混注ではない
                if (parentRow >= 0){ // 過去に混注があった
                    var parentObj = itemArray()[parentRow];
                    parentObj.point = parentPoint;
                    parentRow = (-1);
                }
            }
        }
    }
    
    if (parentRow >= 0){ // 過去に混注があった
        var parentObj = itemArray()[parentRow];
        parentObj.point = parentPoint;
    }
    
    // 静注の親の点数は、その後の子供の点数が加算されてゆき書き換えられるので、その変化を
    // 記録した itemArray():オブジェクトの配列 から転送用 rows:文字列行 を生成する
    var rows = new Array(); // NOA へ返送する文字列レコードを格納
    for (num in itemArray()){
        var rec = itemArray()[num];
        rows.push(treatmentFormat(rec)); // NOA へ返送する文字列
    }
    
    // VIN の内容を再表示
    showItemList();
    
    // 「領収書」ボタンを表示
    showBillButton();
    
    document.getElementById("_message").innerHTML = ""; // Ajax に渡す前に実行
    
    // NOA へ結果を返送：Ajax
    var buff = rows.join("<br>");
    //console.log("putResultOfCalc:", rows.join("\n")); //##
    
    parent().gotValueFromTool(buff, vinTouchAndGo(), vinTouchAndPrint());
}

function timeStamped(answer){
    // 「計算せず」モードで受診レコードの endTime のみが更新された
    var rows = new Array(); // NOA へ返送する文字列レコードを格納
    var array = treatmentArray();
    for (num in array){
        var obj = array[num]; 
        if (obj)
            rows.push(treatmentFormat(obj)); // NOA へ返送する文字列
    }
    var buff = rows.join("<br>");

    // NOA へ結果を返送：Ajax
    parent().gotValueFromTool(buff, vinTouchAndGo(), vinTouchAndPrint());
}

function calc(){
	// アイテム・リストの計算を vinServer へリクエスト
	// サーバ側で計算結果を FRONT へ転送
    if (parent().currentLabel() != originalVinLabel()){
        alert("「 " + originalVinLabel() + " 」欄を開き「確定」しなおしてください");
        return;
    }
    
    var currentDate = parent().currentDate();
    if (isSameDate(todayAndTime(), currentDate) == 0){
        if (!confirm("本日のページではありません。書き換えていいですか？")) 
            return;
    }

    var array = treatmentArray();
    if (array.length == 0){
        if (!confirm("本日も前回と同じ診療行為ですか？"))
            return;
    }
    
    if (checkDiseases()){
        // 病名チェッカーが活きていれば診療行為・病名の対応チェックを行う
        doCheckDiseases()
    }
    
    if (hasFilter()){
        // もしフィルター拡張機能があればフィルタリングを行う
        var array = filter(itemArray());
        _debug("hasVinfilter->"+encodeObject(array)); //##
        
        setItemArray(array);
    }
    
    var item = overlappedItem();
    if (item){
        if (!confirm(item + " が重複しています。このまま計算していいですか？"))
            return;
    }
    
    // 妊娠関連は消費税対象外につきチェック
    checkPregnancy();
        
    if (omitCalculate()){
        // 「集計」ボタンで計算せず FRONT に診療終了の刻印のみ
		var patientId = parent().patientId();
		var entryDate = parent().currentDate();

        // FRONT の patientId,entryDate レコードの endTime を現時刻に更新
        var args = new Object();
        args["hospitalId"] = parent().hospitalId();
        args["patientId"] = patientId;
        args["entryDate"] = entryDate;
        args["endTime"] = "OMITCALC";
        
        NRCall("PUT_FRONT_END_TIME", args, timeStamped);
    } else {
        var args = new Object(); 
        args.records = array;
        args.arguments = parameters();
        
        //console.log("args.records", encodeObject(array)); //##
        
        NRCallVin("CALC", args, putResultOfCalc);
    }
    
    function checkPregnancy(){
        // 妊娠関連は消費税対象外につきチェック
        if (elmFor("hasTaxBox").checked == false) return;
        
        var array = treatmentArray();
        for (num in array){
            var rec = array[num];
            if ((rec.code * 1 == 12) && (rec.name.indexOf("産科") >= 0)){
                if (confirm(rec.name + " があります。消費税をはずしますか")){
                    var elm = elmFor("hasTaxArea");
                    elm.innerHTML = "";
                    var cb = newCHECKBOX(elm, "hasTaxBox", "自費料金に外税を加算", 0);
                    return;
                }
            }
        }
    }
}

function toggleTaxRate(has_tax){
    // チェックの更新で税率入力欄を表示/非表示
    var div = elmFor("taxRateArea");
    div.innerHTML = "";
    
    if (has_tax){
        div.style.fontSize = "10pt";
        
        var rate = (taxRate()) ? taxRate() : "";
        var fd = newFIELD(div, "taxRateF", "消費税率", 5, rate);
        fd.setAttribute("onchange", "saveTaxRate(this)");
        fd.style.textAlign = "right";
        var sp = newSPAN(div, "");
        sp.innerHTML = "%";
        sp.style.paddingLeft = "5px";
    }
}

function savedHasTax(answer){
    //alert("savedHasTax->"+answer); //##
}
function saveHasTax(elm){
    // 外税付加の status をサーバへ保存
    // 初期設定パネルのチェックの更新で税率入力欄を表示/非表示
    var status = (elm.checked) ? true : false;
    toggleTaxRate(status);

    var tag = "VIN_PREFERENCE";
    var item = "HAS_TAX";
    var val = (status) ? "1" : "0";

    setPrefForKey(item, val); // medicalActions() を更新
    
    put_menu(owner(), tag, item , "", val, savedHasTax);
}

function savedTaxRate(answer){
    //alert("savedTaxRate->"+answer); //##
}
function saveTaxRate(elm){
    // 消費税率をサーバへ保存
    var rate = elm.value;
    var tag = "VIN_PREFERENCE";
    var item = "TAX_RATE";
    
    setPrefForKey(item, rate); // medicalActions() を更新
                  
    put_menu(owner(), tag, item , "", rate, savedTaxRate);
}

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

function selectedChar(ch){
    // 文字選択パネルの文字が選択された
    var fd = elmFor("focusOnF");
    var val = fd.value + ch;
    fd.value = val;
    forcusOn();
}
function showCharPanel(elm){
    // 文字選択パネルを表示
    var pos = getPosition(elm);
    var w = 250;
	var x = pos.x; // 表示するx座標
	var y = pos.y + 25; // 表示するy座標
    var title = "";
    var elm = openSeeThroughPanel("_floatPanel", x, y, w, title);
    if (!elm){
        alert("_floatPanel がないのでパネルを表示できません"); return;
    }
    elm.style.padding = "5px";
    
    var ln = 'abcdefghijklmnopqrstuvwxyz';
    var len = ln.length;
    for (var p=0; p < len; p++){
        var ch = ln.charAt(p);
        if (p % 8 == 0)
            var div = newDIV(elm, "");
        var dv = newDIV(div, "/blueButton");
        dv.innerHTML = ch;
        dv.setAttribute("onclick", "selectedChar('" + ch + "')");
        dv.style.fontSize = "18pt";
        dv.style.fontFamily = "monospace";
    }
}

function forcusOn(){
	// key に一致するメニューだけを表示
	var key = document.getElementById("focusOnF").value;
	
	// key を含むメニューのみに絞り込む
	// ## items() はメニュー表示内容なので alias も保持しておき
	// ## alias も検索対象にできるようにする
	var menuItems = new Array();
	var array = items();
	for (num in array){
		var name = array[num]; // 診療行為の実名
        var alias = aliasForTitle(name); // 実名に対応する alias
        
        // 実名か alias に部分一致したものだけを menuItems に取り込む
		if (alias && (alias.indexOf(key) >= 0)){
			menuItems.push(name);
		} else if (name.indexOf(key) >= 0){
			menuItems.push(name);
        }
	}
	
	// ポップアップメニューを表示
	var elm = document.getElementById("itemSelectorArea");
	elm.innerHTML = "";
    makeLimitedMenu(elm, menuItems, "", 20, "itemSelected()");
	itemSelected();
    
    // INFO アイコンを表示
    var sp = newSPAN(elm, "");
    sp.style.marginLeft = "5px";
    showInfoIcon(sp);
}
function makeForcusOnArea(){
	// アイテムを絞り込みを行うフィールドを生成
	var elm = document.getElementById("focusOnArea");
    elm.innerHTML = "";
	var fd = newFIELD(elm, "focusOnF", "", 20, "");
	fd.focus();
	fd.setAttribute("onkeyup", "forcusOn()");
    fd.setAttribute("type", "search");
    fd.setAttribute("placeholder", "絞込みキー"); // 入力ヒントを表示
}

function putGlobal(answer){
	// globalList.js から返されるレスポンス
    alert("putGlobal は使われないので無処理"); //##
}
function itemSelected(){
	// itemSelector（薬剤名など）が選択された時に作動
	// ポップアップメニューに表示されたアイテムを default テンプレート名として表示
	var itemName = selectedLimitedMenu();
    
	if (itemName == ""){
		hideItemAddButton();
		return;
	} else if (itemName == "...その他"){
		// グローバル辞書からの選択パネルを表示
		// ### globalList からのメッセージは putGlobal() で受ける
		var url = "./globalList.php?code=" + groupCode();
        url += "&owner=" + parent().owner();
		window.open(url, "globalList"
					, "scrollbars=yes,width=900,height=500");
		return;
	}
	
	// itemSelector がアクティブの時のみ挿入ボタンを表示
	showItemAddButton();
    
	var fd = document.getElementById("setNameF");
	if (fd) fd.value = itemName; // 一括メニューの場合は fd 存在しない
    
	getItem();
}

function showDoseAndFreqField(rec){
	// 数量・頻度入力欄を表示
	// rec: "1_|_21_|_pill_|_低用量ピル_|_28_|_Tab_|_1_|_1060_|_0" 形式のレコード
	// から default 値を表示
	var elm = document.getElementById("doseAndFreqArea");
	elm.innerHTML = "";

	var code = groupCode() * 1;
    //alert("== showDoseAndFreqField == "+code+"->"+encodeObject(rec)); //##
    
	if (code == 0) return; // 一括メニュー
    
    // treatment 欄からデータ取得した場合 standard は無いので dose を流用
    if (! rec.standard) rec.standard = rec.dose;
	
	switch (code){
		case 21: case 22: case 23:
			showDose(elm, rec.standard, rec.unitName);
			showFeq(elm, code);
			break;
		case 31: case 32: case 33:
			showDose(elm, rec.standard, rec.unitName);
			var cb = newCHECKBOX(elm, "isMix", "を混注の追加薬剤として ", 0);
			break;
	}
	
	function showDose(elm, dose, unitName){
		var fd = newFIELD(elm, "dose", "", 3, dose);
		var tx = newTEXT(elm, unitName);
	}

	function showFeq(elm, code){
		var freq = 5; // ５日分に決め打ち
		var fd = newFIELD(elm, "freq", "", 2, freq);
		var tx = newTEXT(elm, freqName(code));
	}
}

function freqName(code){
    switch (code){
        case 21:
        case 22:
            return "日";
        default:
            return "回";
    }
}

function compareCode(a, b){
    // isOwn code isMix でソート： (a > b) のような比較では正しく動作しない
    return (sortString(a) * 1) - (sortString(b) * 1);

    function sortString(obj){
        // obj からソート用文字列を生成
        // 先頭が "0" だと正しくソートされない
        var isOwn = (obj.isOwn * 1 > 0) ? "2" : "1";
        var isMix = (obj.isMix && (obj.isMix * 1 > 0)) ? "1" : "0";
        
        return isOwn + obj.code + isMix + ""; // 数値として加算されないよう末尾に ""
    }
}
function showItemList(){
	// アイテム・リストを表示
	var elm = document.getElementById("result");
	elm.innerHTML = "";
	
	// タイトル
	var tbl = newTABLE(elm, "/base-table");
	var tr = newTR(tbl, "", "");
    tr.style.color = "#777";
    tr.style.fontSize = "10pt";
	var td = newTD(tr, "title_code", "");
    setInfoTip("title_code", "以下の行を一括消去"); // HELP
    var sp = newSPAN(td, "/codeCol");
    var img = newIMAGE(sp, "icon", "./remove-field.png", "remove");
	img.setAttribute("onclick", "clearItems()");
	img.style.height = "12px";
	img.style.position = "relative";
	img.style.bottom = "1px";
    img.setAttribute("class", "expandIcon");
	var td = newTD(tr, "", "診療行為");
	var td = newTD(tr, "", "数量");
    td.style.textAlign = "center";
	var td = newTD(tr, "", "点数");
    td.style.textAlign = "center";
	var td = newTD(tr, "", "頻度");
    td.style.textAlign = "center";

	// 診療行為コンテンツ
    var sumItem;
    var records = itemArray();
    
    // records を isOwn,code,isMix 順でソート
    records.sort(compareCode);
    
    //console.log("showItemList: records", encodeObject(records)); //##
    
    for (num in records){
        var item = records[num];
        //console.log("showItemList", encodeObject(item)); //##

        if (item.code == "0")
            continue;
        if (item.code == "99")
            sumItem = item;
        else {
            // 自費か健保かにより背景色を変える
            var trId = (item.isOwn > 0) ? "jihi" : "record";
            var tr = newTR(tbl, trId, "");
            
            // コード
            var td = newTD(tr, "/codeCol", "");
            var a = newA(td, item.code, "#", "");
            var action = "removeItem('" + item.number + "')";
            a.setAttribute("onclick", action);
            
            // 診療行為名（自動付加のものは背景色を変える）
            var tdId = ((item.code % 10 == 9) || (item.code * 1 == 13))
            ? "subRecord" : "";
            var td = newTD(tr, "/nameCol", "");
            var sp = newSPAN(td, tdId);
            sp.innerHTML = (item.isMix > 0) ? "+ " + item.name : item.name;
            // コード種別ごとに背景色を変える
            switch (String(item.code).substr(0, 1) * 1){
                case 4: sp.setAttribute("class", "shochi"); break;
                case 6: sp.setAttribute("class", "kensa"); break;
            }
            
            // 数量・単位
            var td = newTD(tr, "/doseCol", "");
            if ((item.code != 60) && (item.unitName.length)){
                var ary = item.unitName.split(" ");
                var fd = newFIELD(td, num + ".dose", "", 2, item.dose);
                fd.setAttribute("onchange", "doseChanged('" + num +"')");
                fd.style.textAlign = "right";
                var tx = newTEXT(td, item.unitName);
            }
            
            // 点数：ここに表示されるものは、薬価 * 数量なので注意
            // addItem() で PriceList を元に挿入されたものは空 point
            // calc() や getHeader() で取り込まれたものは point * dose 処理済み
            var td = newTD(tr, "", item.point + ""); // 数値のことがあるので文字列へ
            td.setAttribute("class", "pointCol");
            
            // 頻度
            var td = newTD(tr, "freqF/freqCol", "");
            td.style.paddingRight = "5px";
            var fname = freqName(item.code * 1);
            var freq = (item.isMix > 0) ? "" : item.freq;
            var fd = newFIELD(td, num + ".freq", "", 2, freq);
            fd.setAttribute("onchange", "freqChanged('" + num +"')");
            fd.style.textAlign = "right";
            var tx = newTEXT(td, fname);
        }
        //_debug("--- row end ---------------<br>"); //##
    }
	// 合計
	if (sumItem){
		// 合計についてはフォーマットが異なり item.name の中に入っている
		// "_|_99_|__|_合計[健保(686 x 3 = 2050)自費(5400)] 7450_|__|__|__|_"
		var tr = newTR(tbl, "sum", "");
		var td = newTD(tr, "", sumItem.name);
		td.setAttribute("colspan", "5");
	}
	
	// 絞込みフィールドをフォーカス
	var fd = document.getElementById("focusOnF");
	if (fd) fd.focus();
    
    // 診療行為に変更が加えられたので「集計」されるまで「領収書」ボタンを表示しない
    hideBillButton();
}

function clearItems(){
	// アイテム・リストをクリアする
	initItemArray();
	showItemList();
}

function removeItem(number){
    // number 番目の診療行為を削除
    //console.log("removeItem", number); //##

	removeItemArray(number);
	showItemList();
}

function hideItemAddButton(){
	document.getElementById("itemAddButtonArea").innerHTML = "";
}
function showItemAddButton(){
	var sp = document.getElementById("itemAddButtonArea");
	sp.innerHTML = "";
    sp.style.marginLeft = "5px";
	var bt = newDIV(sp, "/whiteButton");
    bt.innerHTML = "挿入";
	bt.setAttribute("onclick","addItem()");
}
function addItem(){
	// 選択・編集されたアイテムを診療行為リストに追加する
	// "1_|_21_|_pill_|_低用量ピル_|_28_|_Tab_|_1_|_1060_|_日分_|_" 形式のレコード
	// これを元に item オブジェクトを生成し currentItem に記憶
	var records = currentRecords();
    console.log("== addItem", encodeObject(records)); //##

	if (records.length == 1){
		// 一括メニューでない場合
        var rec = records[0];
        rec.isOwn = (document.getElementById("isOwn").checked) ? 1 : 0;
		var elm = document.getElementById("dose");
        rec.dose = (elm) ? elm.value : "1";
		var elm = document.getElementById("isMix");
        rec.isMix = (elm && elm.checked) ? 1 : 0;
		var elm = document.getElementById("freq");
        rec.freq = (elm) ? elm.value : "1";
        // まだ rec.point は計算処理されていないので見せない
	}
	
    for (num in records){
		// 一括メニュー(約束処方)の場合は、診療行為に複数を追加する
		var rec = records[num];
        rec.isOwn = (document.getElementById("isOwn").checked) ? 1 : 0;
		var item = newItem(rec);
	}
	
    closeFloatPanel(); // 文字パネルを閉じる
	
	showItemList();
}

/////////////////////////////////////////////////////////////
/////// テンプレート編集ペーン //////////////////////////////////

function closeTEmplateEditor(){
	document.getElementById("templateArea").innerHTML = "";
}

function _setnameSelected(){
    // 選択されたセット名を入力欄へ転記
    var setname = elmFor("setNamePop").value;
    elmFor("setNameF").value = setname;

    var div = elmFor("removeSetButtonArea");
    div.innerHTML = "";
    if (setname.length > 0){
        // 一括メニューが選択されている時だけ削除メニューを表示
        var im = newIMAGE(div, "","./remove-field.png","remove");
        im.setAttribute("onclick", "rmoveTemplate()");
        im.setAttribute("class", "expandIcon");
        im.style.marginLeft = "5px";
        im.style.position = "relative";
        im.style.top = "3px";
    }
}
function _gotSetnames(answer){
    // サーバから得た一括メニューを表示
    var obj = JSON.parse(answer);
    //console.log("_gotSetnames", encodeObject(obj)); //##
    
    var names = [""];
    for (label in obj){
        if (label.length == "") continue;
        if (label.charAt(0) == "_") continue;
        
        names.push(label);
    }
    
    // 一括メニューのポップアップを表示
    var elm = elmFor("setNameArea");
    elm.innerHTML = "";
    var pu = newPopupMenu(elm, "setNamePop", names, "");
    pu.setAttribute("onchange", "_setnameSelected()");
}
function _getSetnames(){
    // ラベル「セット名」の位置に、既存セットのポップアップメニューを表示
    var args = new Object();
    args.code = "00";
    
    NRCallVin("GET_CHILD_SELECTOR", args, _gotSetnames);
}

function openTemplateEditor(){
	// テンプレート編集ペーンを開く
	var elm = document.getElementById("templateArea");
	if (elm.innerHTML.length > 0){
		elm.innerHTML = "";
		return;
	}
    
    var frame = newDIV(elm, "templateFrame");

    // HEADER
    var div = newDIV(frame, "/clearfix");
    div.style.marginBottom = "8px";
    var dv = newDIV(div, "/left-side");
    // CLOSE ICON
    var sp = newSPAN(dv, "");
    sp.style.paddingRight = "5px";
    var im = newIMAGE(sp,"icon","./close.png","close");
    im.setAttribute("onclick", "closeTEmplateEditor()");
    im.setAttribute("class", "expandIcon");
    // タイトル
    var sp = newSPAN(dv, "");
	sp.innerHTML = "セット登録パネル";
    // HELP
    dv.style.width = "200px";
    var dv = newDIV(div, "/right-side");
	var im = newIMAGE(dv,"icon","./help.png","close");
    im.setAttribute("onclick", "openHelp('./vinTemplateHelp.html')");
    im.style.height = "16px";
    im.setAttribute("class", "expandIcon");

    // 一括名
    var div = newDIV(frame, "");
    div.style.paddingBottom = "10px";
	// 約束処方名入力（一括メニューが開いていればそのメニュー・アイテムを default 表示）
    var gcode = groupCode() * 1; // 選択されているポップアップのコード：一括はコード0
    var menuItem = (gcode == 0) ? selectedLimitedMenu() : ""; // 選択されたポップアップ名
    var dv = newDIV(div, "");
    dv.style.paddingLeft = "10px";
    // 一括名ポップアップ
    var sp = newSPAN(dv, "setNameArea");
    _getSetnames();
    // セット名入力欄
    var sp = newSPAN(dv, "");
	var fd = newFIELD(sp, "setNameF", "", 20, menuItem);
    fd.setAttribute("placeholder", "セット名");
    fd.focus();
    fd.style.marginLeft = "5px";
    // 削除ボタン
    var sp = newSPAN(dv, "removeSetButtonArea");
/*    
    if (selectedGroupMenu()){
        // 一括メニューが選択されている時だけ削除メニューを表示
        var bt = newDIV(div, "/fixButton");
        bt.innerHTML = "削除";
        bt.setAttribute("onclick", "rmoveTemplate()");
    }*/
    
    // CONTENTS
    var div = newDIV(frame, "templateChildren");
    div.style.paddingLeft = "10px";
    var buff = convertSTRING(archives(), "\n", "<br>");
    div.innerHTML = buff;
    
    // 登録ボタン
    var div = newDIV(frame, "/right-side");
    div.style.paddingBottom = "10px";
    var bt = newDIV(div, "/fixButton");
    bt.innerHTML = "登録";
    bt.setAttribute("onclick", "saveTemplate()");
}

/////// テンプレート編集ペーン //////////////////////////////////
/////////////////////////////////////////////////////////////

function showBillButton(){
    // 「領収書」ボタンを表示
	var elm = document.getElementById("billButtonArea");
    elm.innerHTML = "";
	var bt = newDIV(elm, "/whiteButton");
    bt.innerHTML = "領収書";
	bt.setAttribute("onclick","printBill()");
}
function hideBillButton(){
    // 「領収書」ボタンを削除
	var elm = document.getElementById("billButtonArea");
    elm.innerHTML = "";
}

function printBill(){
    // 領収明細書を発行
    //_initDebug(true); //##
    _debug("printBill"); //##
    
	var obj = new Object();
    obj.currentDate = parent().currentDate();
    obj.publishedDate = today();
    obj.patientId = parent().patientId();
    obj.patientName = parent().patientKanjiName();
    obj.insuranceClass = _valueForTag("HealthInsurance.shubetsu");
    obj.paymentRatio = _valueForTag("HealthInsurance.paymentRatio");
    var st = _valueForTag("PatientTable.unpaid"); // "timeStamp,unpaid" 形式
    
    var array = st.split(",");
    obj.unpaidFee = (array.length > 1) ? array[1] : "0";
    obj.discountRatio = _valueForTag("HealthInsurance.discountRatio");

    // VIN の医事計算レコードをスキャン
    var point = 0;
    var ownFee = 0;
    var count = countOfItemArray();
	if (count > 0){
        obj.ins = new Object();
        obj.own = new Object();
        for (var i=0; i < count; i++){
            var item = itemAtIndexOf(i);
            var code = Math.floor(item.code / 10) * 10; // "12" を "10" にする
            var freq = (item.freq) ? item.freq : 1;
            if (item.isOwn > 0){
                if (!obj.own[code]) obj.own[code] = 0;
                // code 毎の自費点数を加算
                obj.own[code] += item.point * freq;
                ownFee += item.point * freq;
            } else {
                if (!obj.ins[code]) obj.ins[code] = 0;
                // code 毎の健保点数を加算
                obj.ins[code] += item.point * freq;
                point += item.point * freq;
            }
        }
    }
    var hospitalInfo = parent().hospitalInfo();
    obj.round = hospitalInfo.round;
    obj.ownRate = hospitalInfo.ownRate;
    obj.hospitalAddress = hospitalInfo.hospitalAddress;
    obj.hospitalName = hospitalInfo.hospitalName;
    obj.hospitalPhone = hospitalInfo.hospitalPhone;
    obj.point = point;
    obj.insFee = point * obj.paymentRatio + obj.round;
    obj.insFee = Math.floor(obj.insFee / 10) * 10;
    obj.ownFee = ownFee;

    if (hasTax() && (taxRate() * 1 > 0)){ 
        // 消費税額を HospitalInfo の設定により丸め処理
        //console.log("taxRate", taxRate(), "round", obj.round); //##
        obj.tax = Math.floor(((ownFee * (taxRate()/100)) + obj.round) / 10) * 10;
    }
    //console.log("== obj->"+encodeObject(obj)); //##

	var url = "./printBill.php?value=" + JSON.stringify(obj);    
	window.open(url, "BILL", "width=650,height=800,dependent=yes");
    
    function _valueForTag(tag){
        var obj = parent().valueForTag(tag);
        
        // obj.value は null のことあり
        return (obj && obj.value) ? obj.value : "";
    }
}

/////////////////////////////////////////////////////
///// 初期設定 ///////////////////////////////////////

function setPrefForKey(key, value){
    // key に対応する value で medicalActions() を更新
    var array = medicalActions().preferences;
    for (num in array){
        var rec = array[num];
        if (rec.menu == key) {
            rec.value = value;
            return;
        }
    }
}
function prefForKey(key){
    // key に対応する初期設定値を返す
    var array = medicalActions().preferences;
    for (num in array){
        var rec = array[num];
        if (rec.menu == key) return rec.value;
    }
    return null;
}

function hasTax(){
    // 診療入力ツール上のチェックボックスの消費税加算の有無を返す
    var cbox = elmFor("hasTaxBox");
    
    return (cbox.checked) ? 1 : 0;
} 
function vin_hasTax(){
    // DB に記憶した消費税加算の有無を返す
    var val = prefForKey("HAS_TAX");
    
    return (val && (val * 1 > 0)) ? 1 : 0;
}
function taxRate(){
    // 外税なら消費税率を返す、そうでなければ null を返す
    var val = prefForKey("TAX_RATE");
    
    return (val) ? val : "";
}

function openVinPreference(elm){
    // 初期設定パネルを開く
    var pos = getPosition(elm);
    var w = 310;
	var x = 10; // 表示するx座標
	var y = pos.y + 50; // 表示するy座標
    var title = "初期設定パネル";
    var help = "openHelp('vinPrefHelp.html')";
    var elm = openSeeThroughPanel("_floatPanel", x, y, w, title, help);
    if (!elm){
        alert("_floatPanel がないのでパネルを表示できません"); return;
    }
    elm.style.padding = "5px";
    elm.style.fontSize = "10pt";    
    
    // 消費税
    var div = newDIV(elm, "");
	var cb = newCHECKBOX(div, "", "自費料金に外税を加算", vin_hasTax());
    cb.setAttribute("onchange", "saveHasTax(this)");
    // 税率
    var div = newDIV(elm, "taxRateArea");
    div.style.marginLeft = "20px";
    toggleTaxRate(vin_hasTax()); // 税率入力欄をチェックボックスの状態により表示・非表示
    // 確定保存
    var div = newDIV(elm, "");
    var st = "集計とともに「診療欄」へ結果転記・保存";
    var cb = newCHECKBOX(div, "vinTouchAndGoCB", st, vinTouchAndGo());
    cb.setAttribute("onchange", "setVinTouchAndGo(this)");
    setInfoTip("vinTouchAndGoCB", "集計とともに「診療」欄を保存"); // HELP
    // 確定印刷
    var div = newDIV(elm, "");
    var st = "集計とともにカルテ・ページを印刷";
    var cb = newCHECKBOX(div, "vinTouchANdPrintCB", st, vinTouchAndPrint());
    cb.setAttribute("onchange", "setVinTouchAndPrint(this)");
    setInfoTip("vinTouchANdPrintCB", "集計とともにページ印刷"); // HELP
    // 計算せず
    var div = newDIV(elm, "");
    var sp = newSPAN(div, "");
    var st = "集計で計算せず「診療」欄へ転記のみ";
    var cb = newCHECKBOX(sp, "omitCalculate", st, omitCalculate());
    cb.setAttribute("onchange", "setOmitCalculate(this)");
    setInfoTip("omitCalculate", "計算せず診療行為の転記のみ"); // HELP
}

///// 初期設定 ///////////////////////////////////////
/////////////////////////////////////////////////////


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

function calcChecker(){
    // 診療行為と病名との突合チェッカーを開く
    openCalcChecker();
}

function openVinHistory(){
    // 過去履歴ツールを開く
    var url = "vinHistory.php?patientId=" + parent().patientId();
    window.open(url, "vinHistory", "width=600,height=1000,scrollbars=yes");
}

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

function initVin(){
    var base = document.getElementById("vinArea"); // basicPage.js
    
    // ===== 伝票表示エリア =======================================
    var elm = elmFor("vinBase"); 
    if (elm) 
        elm.innerHTML = ""; // 既存のものがあれば空にし以下で再構成
    else
        elm = newDIV(base, "vinBase"); // 隠れたものがなければ新規作成
    
    // === HEADER ============================
    var div = newDIV(elm, "/tool-handle");
    var dv = newDIV(div, "/left-side");
    // CLOSE ICON
    var im = newIMAGE(dv,"icon","./close.png","close");
    im.style.position = "relative";
    im.style.top = "2px";
    im.style.height = "11px";
    im.setAttribute("onclick", "closeVin()");
    im.setAttribute("class", "expandIcon");
    // HANDLE BUTTON
    var bt = newDIV(dv, "/handleButton");
    bt.innerHTML = "診療入力";
    bt.setAttribute("onclick", "toggleNode('vinContentArea')");
    bt.style.width = "100px";
    bt.style.marginLeft = "2px";
    bt.style.fontSize = "10pt";
    // tools にツール・ネームを登録
    tools().addToolName('vinContentArea');

    var dv = newDIV(div, "/right-side");
	var im = newIMAGE(dv, "", "./help.png", "?");
	im.setAttribute("onclick", "openHelp('vinHelp.html')");
	im.setAttribute("verticalAlign", "middle");
	im.style.height = "16px";
	im.style.position = "relative";
	im.style.top = "3px";
    im.setAttribute("class", "expandIcon");

    // CONTENTS =====================================
    var cont = newDIV(elm, "vinContentArea");
    
	// --- 診療マトリックス表示・エリア ---------------
    var div = newDIV(cont, "matrixArea");

	// --- 時間帯・自費チェックボックス ---------------
    var div = newDIV(cont, "controlBox");
    var tbl = newTABLE(div, "base-table");
	tbl.style.fontSize = "8pt";
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "", "");
	var cb = newCHECKBOX(td, "isOwn", "自費 ", 0);
	var js = newSPAN(td, "timeZoneArea");
	// 絞り込みボタン・エリア
	var sp = newSPAN(td, "focusOnArea");
    // VERSION
    var sp = newSPAN(sp, "");
    sp.innerHTML = vin_version();
    sp.style.paddingLeft = "20px";
    sp.style.color = "#aaa";
    sp.style.fontSize = "9pt";
    sp.style.position = "relative";
    sp.style.top = "3px";
    
	// 処置内容選択エリア
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "itemSelectorArea", "");
	td.style.padding = "0px 5px";
	// 診療行為名・挿入ボタン
	var tr = newTR(tbl, "", "");
	var td = newTD(tr, "", "");
	td.style.padding = "0px 5px";
	var sp = newSPAN(td, "doseAndFreqArea");
	var sp = newSPAN(td, "itemAddButtonArea");
    
	// --- 診療行為表示・エリア：診療行為行を列記するエリア
    var div = newDIV(cont, "result");
	
    // === FOOTER =====================
    var div = newDIV(cont, "/tool-footer");
    div.style.height = "25px";
    var dv = newDIV(div, "/left-side");
    dv.style.width = "80%";
    dv.style.marginTop = "3px";
    dv.style.paddingLeft = "10px";
    dv.style.fontSize = "9pt";
	var bt = newDIV(dv, "/fixButton");
    bt.innerHTML = "集計";
	bt.setAttribute("onclick","calc()");
    var sp = newSPAN(dv, "billButtonArea");
    
    var sp = newSPAN(dv, "hasTaxArea");

    var dv = newDIV(div, "/right-side");
    var img = newIMAGE(dv, "icon", "./hammer.png", "remove");
	img.setAttribute("onclick", "openVinPreference(this)");
	img.style.height = "12px";
	img.style.position = "relative";
	img.style.top = "5px";
    img.setAttribute("class", "expandIcon");

	// アンカー・エリア
    var div = newDIV(cont, "");
    div.style.padding = "5px 0";
    var sp = newSPAN(div, "/listMember");
    sp.innerHTML = "PriceList";
    sp.setAttribute("onclick", "openPliceList()");
    var sp = newSPAN(div, "/listMember");
    sp.innerHTML = "セット登録";
    sp.setAttribute("onclick", "openTemplateEditor()");
    var sp = newSPAN(div, "/listMember");
    sp.innerHTML = "フィルター";
    sp.setAttribute("onclick", "openFilter()");
    var sp = newSPAN(div, "/listMember");
    sp.innerHTML = "病名チェッカー";
    sp.setAttribute("onclick", "calcChecker()");
    var sp = newSPAN(div, "/listMember");
    sp.innerHTML = "過去履歴";
    sp.setAttribute("onclick", "openVinHistory()");
    
	// --- テンプレート登録時にテンプレート名入力欄を表示するためのエリア
    var div = newDIV(cont, "templateArea");
    
    // 診療入力を開いた CELL の ラベル名 を記憶
    var label = parent().currentLabel();
    setOriginalVinLabel(label); 

    // iFrame なら toggleButton にツール名を表示
    var bt = tools().elmFor("toggleButton");
    if (bt) bt.innerHTML = "診療入力ツール";

    getHeader();
}

function vin_version(){
	return "Ver.150308";
}


