/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * PharmaceuticalsTablePanel.java
 *
 * Created on 2009/09/01, 12:45:47
 */
package open.dolphin.order;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.InputEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import open.dolphin.table.ObjectReflectTableModel;

import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.TransferHandler;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableColumn;
import open.dolphin.client.AutoKanjiListener;
import open.dolphin.client.AutoRomanListener;
import open.dolphin.client.GUIConst;
import open.dolphin.client.SelectListener;
import open.dolphin.client.SymptomsDialog;
import open.dolphin.client.editor.stamp.StampModelEditor;
import open.dolphin.project.GlobalSettings;
import open.dolphin.container.Pair;
import open.dolphin.dao.SqlDaoFactory;
import open.dolphin.dao.SqlMasterDao;
import open.dolphin.helper.IntegerDocument;
import open.dolphin.helper.NumericDocument;
import open.dolphin.infomodel.BundleMed;
import open.dolphin.infomodel.ClaimItem;
import open.dolphin.infomodel.IInfoModel;
import open.dolphin.infomodel.IStampInfo;
import open.dolphin.infomodel.InteractEntry;
import open.dolphin.infomodel.MasterItem;
import open.dolphin.infomodel.MedicineEntry;
import open.dolphin.infomodel.ModuleModel;
import open.dolphin.infomodel.SinryoCode;
import open.dolphin.infomodel.SsKijyoEntry;
import open.dolphin.project.GlobalVariables;
import open.dolphin.table.OddEvenRowRendererWithExpire;


/**
 *
 * @author oda
 */
public class PharmaceuticalsTablePanel extends javax.swing.JPanel implements PropertyChangeListener {

    private static final long serialVersionUID = 8361225970230987080L;
    protected static final String DEFAULT_STAMP_NAME = "新規スタンプ";
    private static final String FROM_EDITOR_STAMP_NAME = "エディタから";
    private static final String[] COLUMN_NAMES = {"コード", "診療内容", "数量", "単位", " ", "回数"};
    private static final String[] METHOD_NAMES = {"getCode", "getName", "getNumber", "getUnit", "getDummy", "getBundleNumber"};
    private static final int[] COLUMN_WIDTH = {50, 210, 20, 20, 10, 20};
    private static final String IN_MEDICINE = "院内処方";
    private static final String EXT_MEDICINE = "院外処方";
    private static final String ADMIN_MARK = "[用法] ";
    private static final String REG_ADMIN_MARK = "\\[用法\\] ";
    private static final int ROWS = 0;    // Table の行数
    private static final int ONEDAY_COLUMN = 2;    // 数量カラム番号
    private static final int BUNDLE_COLUMN = 5;   // 回数絡む
    private ObjectReflectTableModel<MasterItem> PharmaceuticalsTableModel;  // セットテーブルの TableModel
    private StampModelEditor parent; // StampModelEditorOriginal
    private boolean validModel; // 有効モデルフラグ
    private MedTableStateMgr stateMgr; // State Manager
    private String entity;  // このエディタの Entity
    private String saveReceiptCode;  // 再編集の場合に保存しておくレセ電算コード
    private String defaultNumber = "1";  // デフォルト数

    /** Creates new form PharmaceuticalsTablePanel */
    public PharmaceuticalsTablePanel() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        volumeEditor = new javax.swing.JTextField();
        countEditor = new javax.swing.JTextField();
        stateLabel = new javax.swing.JLabel();
        buttonGroup = new javax.swing.ButtonGroup();
        scroller = new javax.swing.JScrollPane();
        medTable = new javax.swing.JTable();
        controlPanel = new javax.swing.JPanel();
        infoPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        stampNameField = new javax.swing.JTextField();
        inMed = new javax.swing.JRadioButton();
        extMed = new javax.swing.JRadioButton();
        forceInExtFlag = new javax.swing.JCheckBox();
        buttonPanel = new javax.swing.JPanel();
        editButton = new javax.swing.JButton();
        removeButton = new javax.swing.JButton();
        clearButton = new javax.swing.JButton();

        volumeEditor.setName("volumeEditor"); // NOI18N

        countEditor.setName("countEditor"); // NOI18N

        stateLabel.setText("jLabel1");
        stateLabel.setName("stateLabel"); // NOI18N

        setLayout(new java.awt.BorderLayout());

        scroller.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scroller.setName("scroller"); // NOI18N

        medTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        medTable.setToolTipText("ドラッグ & ドロップで順番を入れ替えることができます。");
        medTable.setName("medTable"); // NOI18N
        medTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        medTable.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                medTableMouseDragged(evt);
            }
        });
        scroller.setViewportView(medTable);

        add(scroller, java.awt.BorderLayout.CENTER);

        controlPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        controlPanel.setName("controlPanel"); // NOI18N
        controlPanel.setLayout(new javax.swing.BoxLayout(controlPanel, javax.swing.BoxLayout.X_AXIS));

        infoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        infoPanel.setName("infoPanel"); // NOI18N
        infoPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        jLabel1.setText("スタンプ名");
        jLabel1.setName("jLabel1"); // NOI18N
        infoPanel.add(jLabel1);

        stampNameField.setBackground(new java.awt.Color(251, 239, 128));
        stampNameField.setName("stampNameField"); // NOI18N
        infoPanel.add(stampNameField);

        inMed.setText("院内");
        inMed.setName("inMed"); // NOI18N
        inMed.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                inMedActionPerformed(evt);
            }
        });
        infoPanel.add(inMed);

        extMed.setText("院外");
        extMed.setName("extMed"); // NOI18N
        extMed.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                extMedActionPerformed(evt);
            }
        });
        infoPanel.add(extMed);

        forceInExtFlag.setText("緊急時");
        forceInExtFlag.setName("forceInExtFlag"); // NOI18N
        infoPanel.add(forceInExtFlag);

        controlPanel.add(infoPanel);

        buttonPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        buttonPanel.setName("buttonPanel"); // NOI18N
        buttonPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));

        editButton.setText("編集");
        editButton.setToolTipText("コメントコードの場合編集できます");
        editButton.setEnabled(false);
        editButton.setName("editButton"); // NOI18N
        editButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editButtonActionPerformed(evt);
            }
        });
        buttonPanel.add(editButton);

        removeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/open/dolphin/resources/images/del_16.gif"))); // NOI18N
        removeButton.setToolTipText("選択したアイテムを削除します。");
        removeButton.setEnabled(false);
        removeButton.setName("removeButton"); // NOI18N
        removeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeButtonActionPerformed(evt);
            }
        });
        buttonPanel.add(removeButton);

        clearButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/open/dolphin/resources/images/remov_16.gif"))); // NOI18N
        clearButton.setToolTipText("セット内容をクリアします。");
        clearButton.setEnabled(false);
        clearButton.setName("clearButton"); // NOI18N
        clearButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearButtonActionPerformed(evt);
            }
        });
        buttonPanel.add(clearButton);

        controlPanel.add(buttonPanel);

        add(controlPanel, java.awt.BorderLayout.SOUTH);
    }// </editor-fold>//GEN-END:initComponents

    private void medTableMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_medTableMouseDragged
        int ctrlMask = InputEvent.CTRL_DOWN_MASK;
        int action = ((evt.getModifiersEx() & ctrlMask) == ctrlMask) ? TransferHandler.COPY : TransferHandler.MOVE;
        JComponent c = (JComponent) evt.getSource();
        TransferHandler handler = c.getTransferHandler();
        handler.exportAsDrag(c, evt, action);
    }//GEN-LAST:event_medTableMouseDragged

    private void editButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editButtonActionPerformed
        editSelectedItem();
    }//GEN-LAST:event_editButtonActionPerformed

    private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed
        removeSelectedItem();
    }//GEN-LAST:event_removeButtonActionPerformed

    private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
        clear();
    }//GEN-LAST:event_clearButtonActionPerformed

    private void inMedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_inMedActionPerformed
        boolean b = extMed.isSelected();
        GlobalVariables.getPreferences().putBoolean(GlobalVariables.RP_OUT, b);
    }//GEN-LAST:event_inMedActionPerformed

    private void extMedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_extMedActionPerformed
        boolean b = extMed.isSelected();
        GlobalVariables.getPreferences().putBoolean(GlobalVariables.RP_OUT, b);
    }//GEN-LAST:event_extMedActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.ButtonGroup buttonGroup;
    private javax.swing.JPanel buttonPanel;
    private javax.swing.JButton clearButton;
    private javax.swing.JPanel controlPanel;
    private javax.swing.JTextField countEditor;
    private javax.swing.JButton editButton;
    private javax.swing.JRadioButton extMed;
    private javax.swing.JCheckBox forceInExtFlag;
    private javax.swing.JRadioButton inMed;
    private javax.swing.JPanel infoPanel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JTable medTable;
    private javax.swing.JButton removeButton;
    private javax.swing.JScrollPane scroller;
    private javax.swing.JTextField stampNameField;
    private javax.swing.JLabel stateLabel;
    private javax.swing.JTextField volumeEditor;
    // End of variables declaration//GEN-END:variables

    /**
     * Creates new MedicineTable
     * @param parent
     */
    public PharmaceuticalsTablePanel(StampModelEditor parent) {
        setParent(parent);
        initComponents();
        InitCustomComponents();
    }

    private void InitCustomComponents() {
        // 薬剤セットテーブルを生成する
        PharmaceuticalsTableModel = new ObjectReflectTableModel<MasterItem>(COLUMN_NAMES, ROWS, METHOD_NAMES, null) {

            // 数量と回数のみ編集可能
            @Override
            public boolean isCellEditable(int row, int col) {
                return (col == ONEDAY_COLUMN || col == BUNDLE_COLUMN) ? true : false;
            }

            @Override
            public void setValueAt(Object o, int row, int col) {

                if (o == null || ((String) o).trim().equals("")) {
                    o = new String("0");
                }

                MasterItem mItem = (MasterItem) getObject(row);

                if (col == ONEDAY_COLUMN && mItem != null) {
                    mItem.setNumber((String) o);
                    stateMgr.checkState();
                } else if (col == BUNDLE_COLUMN && mItem != null) {
                    mItem.setBundleNumber((String) o);
                    stateMgr.checkState();
                }
            }
        };

        // Tableを生成する
        medTable.setModel(PharmaceuticalsTableModel);
        medTable.setTransferHandler(new MasterItemTransferHandler());

        ListSelectionModel m = medTable.getSelectionModel();
        m.addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (e.getValueIsAdjusting() == false) {
                    notifySelectedRow();
                }
            }
        });
        medTable.setDefaultRenderer(Object.class, new OddEvenRowRendererWithExpire());

        int ccts = GlobalVariables.getPreferences().getInt("order.table.clickCountToStart", 2);

        // 数量カラム

    //    volumeEditor.addFocusListener(AutoRomanListener.getInstance());
        volumeEditor.addFocusListener(SelectListener.getInstance());

        volumeEditor.setDocument(new NumericDocument());
        TableColumn column = medTable.getColumnModel().getColumn(ONEDAY_COLUMN);
        DefaultCellEditor volumeCellEditor = new DefaultCellEditor(volumeEditor);
        volumeCellEditor.setClickCountToStart(ccts);
        column.setCellEditor(volumeCellEditor);

        // 回数カラム

    //    countEditor.addFocusListener(AutoRomanListener.getInstance());
        countEditor.addFocusListener(SelectListener.getInstance());


        countEditor.setDocument(new IntegerDocument());
        TableColumn column2 = medTable.getColumnModel().getColumn(BUNDLE_COLUMN);
        DefaultCellEditor countCellEditor = new DefaultCellEditor(countEditor);
        countCellEditor.setClickCountToStart(ccts);
        column2.setCellEditor(countCellEditor);

        // 列幅を設定する
        for (int i = 0; i < COLUMN_NAMES.length; i++) {
            column = medTable.getColumnModel().getColumn(i);
            column.setPreferredWidth(COLUMN_WIDTH[i]);
        }

        stampNameField.addFocusListener(AutoKanjiListener.getInstance());

        buttonGroup.add(inMed);
        buttonGroup.add(extMed);

        if (GlobalVariables.getPreferences().getBoolean(GlobalVariables.RP_OUT, true)) {
            extMed.setSelected(true);
        } else {
            inMed.setSelected(true);
        }

        if (parent.getContext().getOkButton() != null) {
            buttonPanel.add(parent.getContext().getOkButton());
        }

        scroller.setViewportView(medTable);
        scroller.getViewport().setBackground(GlobalSettings.getColors(GlobalSettings.Parts.TABLE_BACKGROUND));

        setPreferredSize(new Dimension(GUIConst.DEFAULT_EDITOR_WIDTH, GUIConst.DEFAULT_EDITOR_HEIGHT + 50));

        // StateMgrを生成する
        stateMgr = new MedTableStateMgr(this, medTable, removeButton, clearButton, stampNameField, stateLabel);
    }

    /**
     *
     * @return
     */
    public StampModelEditor getMyParent() {
        return this.parent;
    }

    /**
     *
     * @param parent
     */
    public void setParent(StampModelEditor parent) {
        this.parent = parent;
    }

    /**
     *
     * @return
     */
    public String getEntity() {
        return entity;
    }

    /**
     *
     * @param val
     */
    public void setEntity(String val) {
        entity = val;
    }

    /**
     *
     * @return
     */
    public boolean isValidModel() {
        return validModel;
    }

    /**
     *
     * @param valid
     */
    public void setValidModel(boolean valid) {
        validModel = valid;
        getMyParent().setValidModel(validModel);
    }

    private List<Pair<InteractEntry, SsKijyoEntry>> checkSymptom(SqlMasterDao dao, String importCode) {
        List<Pair<InteractEntry, SsKijyoEntry>> result = new ArrayList<Pair<InteractEntry, SsKijyoEntry>>();
        List<String> onStampCode = new ArrayList<String>();
        for (Object item : PharmaceuticalsTableModel.getObjectList()) {
            onStampCode.add(((MasterItem) item).getCode());
        }

        dao.getSsKijyoEntry(importCode, onStampCode, result);
        return result;
    }

    /**
     * 医薬品及び用法の通知を受け、データをセットする。
     * @param e PropertyChangeEvent
     */
    @Override
    public void propertyChange(PropertyChangeEvent e) {

        Object newValue = e.getNewValue();

        if (newValue != null && (newValue instanceof MasterItem)) {
            MasterItem item = (MasterItem) newValue;
            if (SinryoCode.isComment(item.getCode())) {
                CommentHelper ch = new CommentHelper();
                if (ch.confirm(item)) {
                    PharmaceuticalsTableModel.addRow(item);
                    scrollToBottom(scroller);
                }
            } else if (item.getClassCode() == ClaimConst.YAKUZAI) {
                SqlMasterDao dao = (SqlMasterDao) SqlDaoFactory.create("dao.master");
                boolean isCancel = false;
                List<Pair<InteractEntry, SsKijyoEntry>> symptoms = checkSymptom(dao, item.getCode());
                if (!symptoms.isEmpty()) {
                    SymptomsDialog symptomDialog = new SymptomsDialog(null, true, dao, symptoms); //(JFrame) this.getRootPane().getParent()
                    symptomDialog.setVisible(true);
                    isCancel = symptomDialog.IsCancel();
                }
                if (!isCancel) {
                    String inputNum = defaultNumber;
                    if (item.getUnit() != null) {
                        String unit = item.getUnit();
                        if (unit.equals("錠")) {
                            inputNum = GlobalVariables.getPreferences().get("defaultZyozaiNum", "3");
                        } else if (unit.equals("ｇ")) {
                            inputNum = GlobalVariables.getPreferences().get("defaultSanyakuNum", "1.0");
                        } else if (unit.equals("ｍＬ")) {
                            inputNum = GlobalVariables.getPreferences().get("defaultMizuyakuNum", "1");
                        }
                    }

                    item.setNumber(inputNum);
                    PharmaceuticalsTableModel.addRow(item);
                    scrollToBottom(scroller);
                    String name = stampNameField.getText().trim();
                    if (name.equals("") || name.equals(DEFAULT_STAMP_NAME)) {
                        stampNameField.setText(item.getName());
                    }
                }
            } else if (item.getClassCode() == ClaimConst.ZAIRYO) {
                item.setNumber(defaultNumber);
                PharmaceuticalsTableModel.addRow(item);
                scrollToBottom(scroller);
                String name = stampNameField.getText().trim();
                if (name.equals("") || name.equals(DEFAULT_STAMP_NAME)) {
                    stampNameField.setText(item.getName());
                }

            } else if (item.getClassCode() == ClaimConst.SYUGI) {
                PharmaceuticalsTableModel.addRow(item);
                scrollToBottom(scroller);
                String name = stampNameField.getText().trim();
                if (name.equals("") || name.equals(DEFAULT_STAMP_NAME)) {
                    stampNameField.setText(item.getName());
                }

            } else if (item.getClassCode() == ClaimConst.ADMIN) {
                item.setName(ADMIN_MARK + item.getName());
                item.setDummy("X");
                item.setBundleNumber(GlobalVariables.getPreferences().get("defaultRpNum", defaultNumber));
                PharmaceuticalsTableModel.addRow(item);
                scrollToBottom(scroller);
            }
            stateMgr.checkState();
        }
    }

    private void scrollToBottom(final JScrollPane pane) {

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                pane.getVerticalScrollBar().setValue(pane.getVerticalScrollBar().getMaximum());
            }
        });
    }

    private void notifySelectedRow() {
        int index = medTable.getSelectedRow();
        MasterItem item = PharmaceuticalsTableModel.getObject(index);
        removeButton.setEnabled(item != null);
        if (item != null) {
            editButton.setEnabled(SinryoCode.isComment(item.getCode()));
        } else {
            editButton.setEnabled(false);
        }
    }

    /**
     *
     */
    public void clear() {
        PharmaceuticalsTableModel.clear();
        forceInExtFlag.setSelected(false);
        stateMgr.checkState();
    }

    private void setStampName() {
        if (PharmaceuticalsTableModel.getRowCount() > 0) {
            stampNameField.setText(PharmaceuticalsTableModel.getObject(0).getName());
        }
    }

    private void removeSelectedItem() {

        int index = medTable.getSelectedRow();
        if (index < 0) {
            notifySelectedRow();
            return;
        }
        MasterItem o = PharmaceuticalsTableModel.getObject(index);
        if (o == null) {
            notifySelectedRow();
            return;
        }

        PharmaceuticalsTableModel.deleteRow(index);
        setStampName();
        stateMgr.checkState();
    }

    private ModuleModel createModuleModel() {

        ModuleModel retModel = new ModuleModel();
        BundleMed med = new BundleMed();
        retModel.setModel(med);

        // StampInfoを設定する
        IStampInfo moduleInfo = retModel.getModuleInfo();
        moduleInfo.setEntity(getEntity());
        moduleInfo.setStampRole(IInfoModel.ROLE_P);

        //　スタンプ名を設定する
        String stampName = stampNameField.getText().trim();
        if (!stampName.equals("")) {
            moduleInfo.setStampName(stampName);
        } else {
            moduleInfo.setStampName(DEFAULT_STAMP_NAME);
        }

        return retModel;
    }

    private ClaimItem createClaimItem(MasterItem mItem) {
        ClaimItem item = new ClaimItem(mItem);
        item.setClassCode(String.valueOf(mItem.getClassCode()));
        item.setClassCodeSystem(ClaimConst.SUBCLASS_CODE_ID);
        return item;
    }

    private List<ModuleModel> getBundles() {

        List<ModuleModel> retList = new ArrayList<ModuleModel>();

        List items = PharmaceuticalsTableModel.getObjectList();
        ModuleModel module = createModuleModel();
        BundleMed bundle = (BundleMed) module.getModel();

        boolean isTonyo = false;
        for (MasterItem item : (List<MasterItem>) items) {
            if (item.getClassCode() == ClaimConst.ADMIN) {
                if (open.dolphin.infomodel.SinryoCode.isTonyo(item.getCode())) {
                    isTonyo = true;
                }
            }
        }

        for (Iterator iter = items.iterator(); iter.hasNext();) {
            MasterItem mItem = (MasterItem) iter.next();
            if (mItem != null) {
                String number = mItem.getNumber();
                if (number != null && (!number.trim().equals(""))) {
                    mItem.setNumber(number);
                } else {
                    number = null;
                }
                if (SinryoCode.isComment(mItem.getCode())) {
                    bundle.addClaimItem(createClaimItem(mItem));
                    continue;
                }

                setItem(bundle, mItem, number, isTonyo, retList, module);

            } else {
                break;
            }
        }
        retList.add(module);
        module = createModuleModel();
        bundle = (BundleMed) module.getModel();
        return retList;
    }

    private void setItem(BundleMed bundle, MasterItem mItem, String number, boolean isTonyo, List<ModuleModel> retList, ModuleModel module) {

        switch (mItem.getClassCode()) {
            case ClaimConst.SYUGI:
                ClaimItem sItem = createClaimItem(mItem);
                bundle.addClaimItem(sItem);
                break;
            case ClaimConst.YAKUZAI:
                ClaimItem yItem = createClaimItem(mItem);
                bundle.addClaimItem(yItem);
                yItem.setYkzKbn(mItem.getYkzKbn());
                if (number != null) {
                    yItem.setNumber(number);
                    yItem.setUnit(mItem.getUnit());
                    yItem.setNumberCode(ClaimConst.YAKUZAI_TOYORYO);
                    yItem.setNumberCodeSystem(ClaimConst.NUMBER_CODE_ID);
                }
                if (bundle.getClassCode() == null) {
                    String rCode = null;
                    rCode = selectClassCodeForYakuzai(mItem.getYkzKbn(), isTonyo, forceInExtFlag.isSelected());
                    if (rCode == null && saveReceiptCode != null) {
                        rCode = saveReceiptCode;
                    }
                    bundle.setClassCode(rCode);
                    bundle.setClassCodeSystem(ClaimConst.CLASS_CODE_ID);
                    bundle.setClassName(MMLTable.getClaimClassCodeName(rCode));
                }
                break;
            case ClaimConst.ZAIRYO:
                ClaimItem zItem = createClaimItem(mItem);
                bundle.addClaimItem(zItem);
                if (number != null) {
                    zItem.setNumber(number);
                    zItem.setUnit(mItem.getUnit());
                    zItem.setNumberCode(ClaimConst.ZAIRYO_KOSU);
                    zItem.setNumberCodeSystem(ClaimConst.NUMBER_CODE_ID);
                }
                break;
            case ClaimConst.ADMIN:
                String ommit = mItem.getName().replaceAll(REG_ADMIN_MARK, "");
                bundle.setAdmin(ommit);
                bundle.setAdminCode(mItem.getCode());
                String bNum = mItem.getBundleNumber();
                if (bNum != null && (!bNum.trim().equals(""))) {
                    bundle.setBundleNumber(mItem.getBundleNumber());
                }
                String memo = inMed.isSelected() ? IN_MEDICINE : EXT_MEDICINE;
                bundle.setMemo(memo);
                break;
        }
    }

    private String selectClassCodeForYakuzai(String ykzKbn, boolean isTonyo, boolean isForce) {
        // 基本的な内用外用頓用を決定
        String rCode = null;
        if (ykzKbn != null) {
            if (ykzKbn.equals(ClaimConst.YKZ_KBN_GAIYO)) {
                rCode = ClaimConst.RECEIPT_CODE_GAIYO;
            } else {
                rCode = ClaimConst.RECEIPT_CODE_NAIYO;
            }
        }
        if (rCode == null) {
            return null;
        }
        if (rCode.equals(ClaimConst.RECEIPT_CODE_NAIYO) && isTonyo) {
            rCode = ClaimConst.RECEIPT_CODE_TONYO;
        }
        // 強制（緊急）院内院外を決定
        if (isForce) {
            if (rCode.equals(ClaimConst.RECEIPT_CODE_GAIYO)) {
                if (inMed.isSelected()) {
                    rCode = ClaimConst.RECEIPT_CODE_GAIYO_INNAI;
                } else {
                    rCode = ClaimConst.RECEIPT_CODE_GAIYO_INGAI;
                }
            } else if (rCode.equals(ClaimConst.RECEIPT_CODE_NAIYO)) {
                if (inMed.isSelected()) {
                    rCode = ClaimConst.RECEIPT_CODE_NAIYO_INNAI;
                } else {
                    rCode = ClaimConst.RECEIPT_CODE_NAIYO_INGAI;
                }
            } else if (rCode.equals(ClaimConst.RECEIPT_CODE_TONYO)) {
                if (inMed.isSelected()) {
                    rCode = ClaimConst.RECEIPT_CODE_TONYO_INNAI;
                } else {
                    rCode = ClaimConst.RECEIPT_CODE_TONYO_INGAI;
                }
            }
        }
        return rCode;
    }

    /**
     * エディタで編集したスタンプを返す。
     * @return エディタで編集したスタンプ
     */
    public Object getValue() {
        List<ModuleModel> list = getBundles();
        return (Object) list.get(0);
    }

    /**
     * 編集するスタンプを表示する。
     * @param theStamp
     */
    public void setValue(Object theStamp) {
        Date now = new Date();
        clear();
        if (theStamp == null) {
            // Stateを変更する
            stateMgr.checkState();
            return;
        }
        // 引数で渡された Stamp をキャストする
        ModuleModel target = (ModuleModel) theStamp;

        // Entityを保存する
        setEntity(target.getModuleInfo().getEntity());

        // スタンプ名を表示する
        String stampName = target.getModuleInfo().getStampName();
        boolean serialized = target.getModuleInfo().isSerialized();

        if (!serialized && stampName.startsWith(FROM_EDITOR_STAMP_NAME)) {
            stampName = DEFAULT_STAMP_NAME;
        } else if (stampName.equals("")) {
            stampName = DEFAULT_STAMP_NAME;
        }
        stampNameField.setText(stampName);

        BundleMed med = (BundleMed) target.getModel();
        if (med == null) {
            return;
        }

        String classCode = med.getClassCode();
        if (classCode != null) {
            forceInExtFlag.setSelected(classCode.matches("^..[12]$"));
        }

        // レセ電算コードを保存する
        if (med.getClassCode() != null) {
            saveReceiptCode = med.getClassCode();
        }

        ClaimItem[] items = med.getClaimItem();
        if (items != null) {
            for (ClaimItem item : items) {
                MasterItem mItem = new MasterItem(Integer.parseInt(item.getClassCode()), item);
                mItem.setYkzKbn(item.getYkzKbn());
                String number = item.getNumber();
                if (number != null && (!number.equals(""))) {
                    mItem.setNumber(number);
                    mItem.setUnit(item.getUnit());
                }

                SqlMasterDao dao = (SqlMasterDao) SqlDaoFactory.create("dao.master");
                List<MedicineEntry> collection = new ArrayList<MedicineEntry>();
                dao.getAlternateEntry(item.getCode(), collection);
                for (MedicineEntry updateEntry : collection) {
                    if (!mItem.getCode().equals(updateEntry.getCode())) {
                        MasterItem updatedMasterItem = new MasterItem(Integer.parseInt(item.getClassCode()), updateEntry);
                        updatedMasterItem.setUnit(updateEntry.getUnit());
                        updatedMasterItem.setNumber("0");
                        updatedMasterItem.setYkzKbn(item.getYkzKbn());
                        PharmaceuticalsTableModel.addRow(updatedMasterItem);
                    }
                }
                PharmaceuticalsTableModel.addRow(mItem);
                scrollToBottom(scroller);
            }
        }

        // Save Administration
        if (med.getAdmin() != null) {
            MasterItem item = new MasterItem(3, med);
            item.setCode(med.getAdminCode());
            item.setName(ADMIN_MARK + med.getAdmin());
            item.setDummy("X");
            String bNumber = med.getBundleNumber();
            item.setBundleNumber(bNumber);
            PharmaceuticalsTableModel.addRow(item);
            scrollToBottom(scroller);
        }

        // Memo
        String memo = med.getMemo();
        if (memo != null && memo.equals(IN_MEDICINE)) {
            inMed.setSelected(true);
        } else {
            extMed.setSelected(true);
        }

        // Notify
        stateMgr.checkState();
    }

    private void editSelectedItem() {
        int idx = medTable.getSelectedRow();
        MasterItem item = (MasterItem) PharmaceuticalsTableModel.getObject(idx);
        if (item != null) {
            if (SinryoCode.isComment(item.getCode())) {
                CommentHelper ch = new CommentHelper();
                ch.confirm(item);
            }
            PharmaceuticalsTableModel.fireTableDataChanged();
            stateMgr.checkState();
            //先頭のアイテム名がデフォルトのセット名になるので先頭のアイテムが削除された場合、セット名を変える
            if (PharmaceuticalsTableModel.getObject(0) != null) {
                stampNameField.setText(((MasterItem) PharmaceuticalsTableModel.getObject(0)).getName());
            } else {
                stampNameField.setText(DEFAULT_STAMP_NAME);
            }
        }
    }
}
