package vismon.gui;

import info.clearthought.layout.TableLayout;
import info.clearthought.layout.TableLayoutConstants;
import vismon.data.MngOption;
import vismon.data.Session;
import vismon.data.VisualRefLine;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class VisualRefLineDialog {

    private JFrame frame;
    private JPanel mainPanel;

    private JTable table;
    private RefLineTableModel tableModel;
    private final Object[] tableLastRow = new Object[]{Session.getMngOption(0).getName(), "", ""};

    public void run() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                setUp();
                start();
            }
        });
    }

    protected void setUp() {
        initComponents();
    }

    protected void start() {
        addPanel();
        addTable();

        frame.setVisible(true);
    }

    protected void initComponents() {
        int width = 500;
        int height = 300;

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int xLocation = (int)((screenSize.getWidth() - width) * 0.5);
        int yLocation = (int)((screenSize.getHeight() - height) * 0.5);

        this.frame = new JFrame("Visual Reference Lines");
        this.frame.setSize(new Dimension(width, height));
        this.frame.setLocation(xLocation, yLocation);
        this.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent windowEvent) {
                Vismon.getVismonInstance().closeVisualRefLineDialog();
            }
        });

        this.frame.getContentPane().setLayout(new TableLayout(new double[][]{{0, -1, 0}, {0, -1, 0}}));
    }

    protected void addPanel() {
        mainPanel = new JPanel();
        mainPanel.setBackground(Color.WHITE);

        Container frameContainer = this.frame.getContentPane();
        frameContainer.setLayout(new BorderLayout());
        frameContainer.add(mainPanel, BorderLayout.CENTER);
    }

    private class RefLineTableModel extends DefaultTableModel {
        private int lastRowNum;

        public RefLineTableModel() {
            lastRowNum = 0;
        }

        public void addLastRowNum(int value) {
            lastRowNum += value;
        }

        @Override
        public boolean isCellEditable(int row, int col) {
            if (row == lastRowNum || col == 2)
                return true;
            return false;
        }
    }



    protected void addTable() {
        tableModel = new RefLineTableModel();
        int currentVRLNum = Session.getVisualRefLines().size();
        Object[][] tableRows = new Object[currentVRLNum+1][];
        for (int i = 0; i < currentVRLNum; ++i) {
            VisualRefLine vrl = Session.getVisualRefLines().get(i);
            tableRows[i] = new Object[]{vrl.getMngOption().getName(), vrl.getValue(), ""};
        }
        tableRows[tableRows.length-1] = tableLastRow;

        tableModel.setDataVector(tableRows,
                new Object[]{"Management Option", "Value", "Add/Delete"});
        tableModel.addLastRowNum(currentVRLNum);

        table = new JTable(tableModel);
        table.setShowGrid(true);
        table.setGridColor(Color.LIGHT_GRAY);

        String[] mngOptionsNameList = new String[Session.getMngOptionNum()];
        for (int i = 0; i < mngOptionsNameList.length; ++i)
            mngOptionsNameList[i] = Session.getMngOption(i).getName();
        TableColumn mngColumn = table.getColumnModel().getColumn(0);
        mngColumn.setCellEditor(new MyComboBoxEditor(mngOptionsNameList));
        mngColumn.setCellRenderer(new MyComboBoxRenderer(mngOptionsNameList));

        TableColumn addDelColumn = table.getColumnModel().getColumn(2);
        addDelColumn.setCellRenderer(new MyButtonRenderer());
        addDelColumn.setCellEditor(new MyButtonEditor(new JCheckBox()));

        table.setRowHeight(25);

        table.addKeyListener(new KeyListener() {
            public void keyTyped(KeyEvent keyEvent) {
                int row = table.getSelectedRow();
                int col = table.getSelectedColumn();

                if (row == (table.getRowCount()-1) && col == 1) {
                    if (keyEvent.getKeyCode() == 0)
                        table.setValueAt("", row, col);
                    else
                        table.setValueAt(KeyEvent.getKeyText(keyEvent.getKeyCode()), row, col);
                }
            }

            public void keyPressed(KeyEvent keyEvent) {
                int row = table.getSelectedRow();
                int col = table.getSelectedColumn();

                if (row == (table.getRowCount()-1) && col == 2 && keyEvent.getKeyCode() == KeyEvent.VK_ENTER)
                    createVRL();
            }

            public void keyReleased(KeyEvent keyEvent) {
            }
        });

        JScrollPane tableScrollPane = new JScrollPane(table);

        double[][] tableLayout = new double[][]{{TableLayoutConstants.FILL},
                {TableLayoutConstants.FILL}};
        mainPanel.setLayout(new TableLayout(tableLayout));
        mainPanel.add(tableScrollPane, "0,0");
    }

    private void removeVRL(int rowNum) {
        Session.removeVisualRefLine(rowNum);

        tableModel.removeRow(rowNum);
        tableModel.addLastRowNum(-1);
    }

    private void createVRL() {
        MngOption selectedMngOption = Session.getMngOption(0);
        for (MngOption mngOption : Session.getMngOptions())
            if (mngOption.getName().equals(table.getValueAt(table.getRowCount() - 1, 0))) {
                selectedMngOption = mngOption;
                break;
            }
        double value = Double.parseDouble((String) (table.getValueAt(table.getRowCount() - 1, 1)));
        Session.addVisualRefLine(new VisualRefLine(selectedMngOption, value));

        tableModel.addRow(new Object[]{selectedMngOption.getName(), value, ""});
        tableModel.addRow(tableLastRow);
        tableModel.removeRow(table.getRowCount() - 2);
        tableModel.addLastRowNum(1);
    }

    public void close() {
        frame.setVisible(false);
        frame.dispose();
    }

    /********************************************************************************/


    private class MyComboBoxRenderer extends JComboBox implements TableCellRenderer {
        public MyComboBoxRenderer(String[] items) {
            super(items);
        }

        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            // Select the current value
            setSelectedItem(value);
            return this;
        }
    }

    private class MyComboBoxEditor extends DefaultCellEditor {
        public MyComboBoxEditor(String[] items) {
            super(new JComboBox(items));
        }
    }

    private class MyButtonRenderer implements TableCellRenderer {

        private JButton button;

        public MyButtonRenderer() {
            super();
            button = new JButton("");
            button.setBorder(BorderFactory.createEmptyBorder());
        }

        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (row == (table.getRowCount() - 1))
                button.setIcon(new ImageIcon("images/add.png"));
            else
                button.setIcon(new ImageIcon("images/remove.png"));
            return button;
        }
    }

    private class MyButtonEditor extends DefaultCellEditor {
        protected JButton button;
        private boolean isPushed;
        private boolean isLastRow;
        private int rowNum;
        private JTable table;

        public MyButtonEditor(JCheckBox checkBox) {
            super(checkBox);
            button = new JButton();
            button.setOpaque(true);
            button.setBorder(BorderFactory.createEmptyBorder());
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    fireEditingStopped();
                }
            });
        }

        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            rowNum = row;
            this.table = table;
            if (row == (table.getRowCount() - 1))
                button.setIcon(new ImageIcon("images/add.png"));
            else
                button.setIcon(new ImageIcon("images/remove.png"));

            isPushed = true;
            if (row == (table.getRowCount() - 1))
                isLastRow = true;
            else
                isLastRow = false;
            return button;
        }

        public Object getCellEditorValue() {
            if (isPushed) {
                if (isLastRow) {
                    createVRL();
                } else {
                    removeVRL(rowNum);
                }
            }
            isPushed = false;
            Vismon.getVismonInstance().repaintCplomPanel();
            return new String("");
        }

        public boolean stopCellEditing() {
            isPushed = false;
            return super.stopCellEditing();
        }

        protected void fireEditingStopped() {
            super.fireEditingStopped();
        }
    }
}



