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

/*
 * AppointTablePanel.java
 *
 * Created on 2010/03/10, 15:29:33
 */
package open.dolphin.client.caremapdocument;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

import open.dolphin.client.IChartDocument;
import open.dolphin.project.GlobalSettings;
import open.dolphin.table.IMECellEditor;
import open.dolphin.table.ObjectTableModel;
import open.dolphin.table.OddEvenRowRenderer;
import open.dolphin.utils.MMLDate;
import open.dolphin.infomodel.AppointmentModel;
import open.dolphin.infomodel.ModelUtils;

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

    private static final long serialVersionUID = 1013931150179503017L;
    private final String[] COLUMN_NAMES = {"予約日", "内  容", "メ   モ"}; //GlobalVariables.getStringArray("appoint.table.columnNames");
    private final int[] COLUMN_WIDTH = {90, 90, 300};
    private final int NUM_ROWS = 9;
    private final int MEMO_COLUMN = 2;
    private CareTableModel tableModel;
    private JTable careTable;
    private TodayRowRenderer todayRenderer;
    private String today;   // = "2003-02-21";
    private IChartDocument parent;
    private boolean dirty;

    /** Creates new form AppointTablePanel */
    public AppointTablePanel(JButton updateBtn) {
        super();
        initComponents();

        setLayout(new BorderLayout(0, 5));

        todayRenderer = new TodayRowRenderer();
        tableModel = new CareTableModel(COLUMN_NAMES, NUM_ROWS);
        careTable = new JTable(tableModel) {

            private static final long serialVersionUID = -3446348785385967929L;

            @Override
            public TableCellRenderer getCellRenderer(int row, int col) {

                AppointmentModel e = (AppointmentModel) tableModel.getObject(row);

                if (e != null && e.getDate().equals(today)) {
                    //TODO 
                    Color c = AppointColors.getAppointColor(e.getName());
                    todayRenderer.setBackground(c);
                    return todayRenderer;

                } else {
                    return super.getCellRenderer(row, col);
                }
            }
        };
        careTable.setSurrendersFocusOnKeystroke(true);
        careTable.setRowSelectionAllowed(true);
        careTable.setDefaultRenderer(Object.class, new OddEvenRowRenderer());

        // CellEditor を設定する
        // NAME_COL clickCountToStart=1, IME=ON
        TableColumn column = careTable.getColumnModel().getColumn(MEMO_COLUMN);
        column.setCellEditor(new IMECellEditor(new JTextField(), 1, true));

        // Set the column width
        if (COLUMN_WIDTH != null) {
            int len = COLUMN_WIDTH.length;
            for (int i = 0; i < len; i++) {
                column = careTable.getColumnModel().getColumn(i);
                column.setPreferredWidth(COLUMN_WIDTH[i]);
            }
        }
        //careTable.setPreferredSize(new Dimension(500, 200));

        JScrollPane scroller = new JScrollPane(careTable,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scroller.getViewport().setBackground(GlobalSettings.getColors(GlobalSettings.Parts.TABLE_BACKGROUND));
        JPanel cmd = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
        cmd.add(updateBtn);
        updateBtn.setMargin(new Insets(2, 2, 2, 2));
        this.add(cmd, BorderLayout.NORTH);
        this.add(scroller, BorderLayout.CENTER);

        today = MMLDate.getDate();
    }

    /** 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() {

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
    public void setParent(IChartDocument doc) {
        parent = doc;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void propertyChange(PropertyChangeEvent e) {

        String prop = e.getPropertyName();

        if (prop.equals(CareMapDocumentPanel.CALENDAR_PROP)) {

            SimpleCalendarPanel[] calendars = (SimpleCalendarPanel[]) e.getNewValue();

            int len = calendars.length;
            List list = new ArrayList();

            for (int i = 0; i < len; i++) {

                List results = calendars[i].getAppointDays();
                int size = results.size();
                for (int k = 0; k < size; k++) {
                    list.add(results.get(k));
                }
            }
            tableModel.setObjectList(list);
        } else if (prop.equals(CareMapDocumentPanel.APPOINT_PROP)) {
            AppointmentModel appoint = (AppointmentModel) e.getNewValue();
            tableModel.updateAppoint(appoint);
        } else if (prop.equals(CareMapDocumentPanel.SELECTED_APPOINT_DATE_PROP)) {
            findAppoint((String) e.getNewValue());
        }
    }

    private void findAppoint(String date) {
        int size = tableModel.getDataSize();
        String val = null;
        for (int i = 0; i < size; i++) {
            val = (String) tableModel.getValueAt(i, 0);
            if (val.equals(date)) {
                careTable.setRowSelectionInterval(i, i);
                break;
            }
        }
    }

    protected class CareTableModel extends ObjectTableModel {

        private static final long serialVersionUID = -5342312972368806563L;

        public CareTableModel(String[] columnNames, int numRows) {
            super(columnNames, numRows);
        }

        @Override
        public boolean isCellEditable(int row, int col) {
            return (isValidRow(row) && col == MEMO_COLUMN) ? true : false;
        }

        @Override
        public Object getValueAt(int row, int col) {
            AppointmentModel e = (AppointmentModel) getObject(row);
            if (e == null) {
                return null;
            }
            String ret = null;
            switch (col) {

                case 0:
                    ret = ModelUtils.getDateAsString(e.getDate());
                    break;

                case 1:
                    ret = e.getName();
                    break;

                case 2:
                    ret = e.getMemo();
                    break;
            }

            return (Object) ret;
        }

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

            String str = (String) val;
            if (col != MEMO_COLUMN || str == null || str.trim().equals("")) {
                return;
            }

            AppointmentModel entry = (AppointmentModel) getObject(row);

            if (entry != null) {

                entry.setMemo(str);

                if (entry.getState() == AppointmentModel.TT_HAS) {
                    entry.setState(AppointmentModel.TT_REPLACE);
                }

                fireTableCellUpdated(row, col);

                if (!dirty) {
                    dirty = true;
                    parent.setDirty(dirty);
                }
            }
        }

        public void updateAppoint(AppointmentModel appoint) {

            int row = findAppointEntry(appoint);
            int state = appoint.getState();

            if (row == -1 && state == AppointmentModel.TT_NEW) {
                addAppointEntry(appoint);

            } else if (row >= 0) {

                if (appoint.getName() != null) {
                    fireTableRowsUpdated(row, row);

                } else {
                    deleteRow(row);
                }
            }
        }

        @SuppressWarnings("unchecked")
        public void addAppointEntry(AppointmentModel entry) {
            addRow((Object) entry);
            Collections.sort(getObjectList());
            int index = getObjectCount() - 1;
            fireTableRowsUpdated(0, index);
        }

        private int findAppointEntry(AppointmentModel appoint) {

            List objects = getObjectList();

            if (objects == null) {
                return -1;
            }
            int len = objects.size();
            int row = -1;
            for (int i = 0; i < len; i++) {
                if (appoint == (AppointmentModel) objects.get(i)) {
                    row = i;
                    break;
                }
            }
            return row;
        }

        public Object[] getAppointEntries() {
            List list = getObjectList();
            return list != null ? list.toArray() : null;
        }
    }

    /**
     *
     */
    protected class TodayRowRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 4422900791807822090L;

        public TodayRowRenderer() {
        }
    }
}
