/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */


package org.netbeans.modules.properties;


import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.MessageFormat;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.event.*;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.table.*;

import org.openide.DialogDescriptor;
import org.openide.NotifyDescriptor;
import org.openide.DialogDisplayer;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import org.openide.util.WeakListeners;
import org.openide.windows.TopComponent;


/**
 * Panel which shows bundle of .properties files encapsulated by <code>PropertiesDataObject</code> in one table view.
 *
 * @author  Petr Jiricka
 * @author  Marian Petras
 */
public class BundleEditPanel extends JPanel implements PropertyChangeListener {
    
    /** PropertiesDataObject this panel presents. */
//    private PropertiesDataObject obj;

    /** */
    private BundleStructure structure;

    /** Document listener for value and comment textareas. */
    private DocumentListener listener;
    
    /** Class representing settings used in table view. */
    private static TableViewSettings settings;
    
    /** Generated serialized version UID. */
    static final long serialVersionUID =-843810329041244483L;
    
    private Element.ItemElem lastSelectedBundleKey;
    private int lastSelectedColumn;
    
    /** Creates new form BundleEditPanel */
    @Deprecated
    public BundleEditPanel(final PropertiesDataObject obj, PropertiesTableModel propTableModel) {
//        this.obj = obj;
        this.structure = obj.getBundleStructure();
        
        initComponents();
        initAccessibility();
        initSettings();
        
        // Sets table column model.
        table.setColumnModel(new TableViewColumnModel());

        // Sets custom table header renderer (with sorting indicators).
        JTableHeader header = table.getTableHeader();
        header.setDefaultRenderer(
                new TableViewHeaderRenderer(obj, header.getDefaultRenderer()));
        
        // Sets table model.
        table.setModel(propTableModel);
        
        // Sets table cell editor.
        JTextField textField = new JTextField();
        // Force the document to accept newlines. The textField doesn't like
        // it, but the same document is used by the <code>textValue</code> text
        // area that must accept newlines.
        textField.getDocument().putProperty("filterNewlines",  Boolean.FALSE); // NOI18N
        textField.setBorder(new LineBorder(Color.black));
        textField.getAccessibleContext().setAccessibleName(NbBundle.getBundle(BundleEditPanel.class).getString("ACSN_CellEditor"));
        textField.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACSD_CellEditor"));
        listener = new ModifiedListener();
        table.setDefaultEditor(PropertiesTableModel.StringPair.class,
            new PropertiesTableCellEditor(textField, textComment, textValue, valueLabel, listener));
        
        // Sets renderer.
        table.setDefaultRenderer(PropertiesTableModel.StringPair.class, new TableViewRenderer());
        
        updateAddButton();
        
        // property change listener - listens to editing state of the table
        table.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getPropertyName().equals("tableCellEditor")) { // NOI18N
                    updateEnabled();
                } else if (evt.getPropertyName().equals("model")) { // NOI18N
                    updateAddButton();
                } else if (evt.getPropertyName().equals("marginChanged")||
                            evt.getPropertyName().equals("columnMoved") ||
                            evt.getPropertyName().equals("componentHidden")) {
                    saveEditorValue(false);
                }
            }
        });
        
        // listens on clikcs on table header, detects column and sort accordingly to chosen one
        table.getTableHeader().addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                TableColumnModel colModel = table.getColumnModel();
                int columnModelIndex = colModel.getColumnIndexAtX(e.getX());
                // No column was clicked.
                if (columnModelIndex < 0) {
                    return;
                }
                int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex();
                // not detected column
                if (modelIndex < 0) {
                    return;
                }
                obj.getBundleStructure().sort(modelIndex);
            }
        });

        
        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent evt) {
                final boolean correctCellSelection = !selectionUpdateDisabled;
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        updateSelection(correctCellSelection);
                    }
                });
            }
        });
        
    } // End of constructor.
    
    /** Creates new form BundleEditPanel */
    public BundleEditPanel(final BundleStructure structure, PropertiesTableModel propTableModel) {
        this.structure = structure;

        initComponents();
        initAccessibility();
        initSettings();

        // Sets table column model.
        table.setColumnModel(new TableViewColumnModel());

        // Sets custom table header renderer (with sorting indicators).
        JTableHeader header = table.getTableHeader();
        header.setDefaultRenderer(
                new TableViewHeaderRenderer(structure, header.getDefaultRenderer()));

        // Sets table model.
        table.setModel(propTableModel);

        // Sets table cell editor.
        JTextField textField = new JTextField();
        // Force the document to accept newlines. The textField doesn't like
        // it, but the same document is used by the <code>textValue</code> text
        // area that must accept newlines.
        textField.getDocument().putProperty("filterNewlines",  Boolean.FALSE); // NOI18N
        textField.setBorder(new LineBorder(Color.black));
        textField.getAccessibleContext().setAccessibleName(NbBundle.getBundle(BundleEditPanel.class).getString("ACSN_CellEditor"));
        textField.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACSD_CellEditor"));
        listener = new ModifiedListener();
        table.setDefaultEditor(PropertiesTableModel.StringPair.class,
            new PropertiesTableCellEditor(textField, textComment, textValue, valueLabel, listener));

        // Sets renderer.
        table.setDefaultRenderer(PropertiesTableModel.StringPair.class, new TableViewRenderer());

        updateAddButton();

        // property change listener - listens to editing state of the table
        table.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getPropertyName().equals("tableCellEditor")) { // NOI18N
                    updateEnabled();
                } else if (evt.getPropertyName().equals("model")) { // NOI18N
                    updateAddButton();
                } else if (evt.getPropertyName().equals("marginChanged")||
                            evt.getPropertyName().equals("columnMoved") ||
                            evt.getPropertyName().equals("componentHidden")) {
                    saveEditorValue(false);
                    if (evt.getPropertyName().equals("columnMoved")) {
                        if (evt.getOldValue()!=null && evt.getNewValue()!=null) {
                            int fromIndex = ((Integer)evt.getOldValue()).intValue();
                            int toIndex = ((Integer)evt.getNewValue()).intValue();
                            if (fromIndex !=0 && toIndex != 0) {
                                ((MultiBundleStructure)structure).moveEntry(fromIndex-1,toIndex-1);
                            }
                        }
                    }
                }
            }
        });

        // listens on clikcs on table header, detects column and sort accordingly to chosen one
        table.getTableHeader().addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                TableColumnModel colModel = table.getColumnModel();
                int columnModelIndex = colModel.getColumnIndexAtX(e.getX());
                // No column was clicked.
                if (columnModelIndex < 0) {
                    return;
                }
                int modelIndex = columnModelIndex;//colModel.getColumn(columnModelIndex).getModelIndex();
                // not detected column
                if (modelIndex < 0) {
                    return;
                }
                saveEditorValue(false);
                structure.sort(modelIndex);
            }
        });

        ListSelectionListener listSelectionListener = new ListSelectionListener() {

            public void valueChanged(ListSelectionEvent evt) {
                final boolean correctCellSelection = !selectionUpdateDisabled;
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        updateSelection(correctCellSelection);
                    }
                });
            }
        };

        table.getColumnModel().getSelectionModel().addListSelectionListener(listSelectionListener);
        table.getSelectionModel().addListSelectionListener(listSelectionListener);

    } // End of constructor.
    
    /** Stops editing if editing is in run. */
    protected void stopEditing() {
        saveEditorValue(true);
    }

    /**
     */
    protected void saveEditorValue(boolean stopEditing) {
        if (!table.isEditing()) {
            return;
        }
        TableCellEditor cellEdit = table.getCellEditor();
        if (cellEdit != null) {
            if (stopEditing) {
                cellEdit.stopCellEditing();
            } else {
                int row = table.getEditingRow();
                int col = table.getEditingColumn();
                if ((row != -1) && (col != -1)) {
                    table.setValueAt(cellEdit.getCellEditorValue(), row, col);
                }
            }
        }
    }
    
    /** Updates the enabled status of the fields */
    private void updateEnabled() {
        // always edit value
        textValue.setEditable(table.isEditing());
        textValue.setEnabled(table.isEditing());
        // sometimes edit the comment
        if (table.isEditing()) {
            PropertiesTableModel.StringPair sp = (PropertiesTableModel.StringPair)table.getCellEditor().getCellEditorValue();
            textComment.setEditable(sp.isCommentEditable());
            textComment.setEnabled(sp.isCommentEditable());
        } else {
            textComment.setEditable(false);
            textComment.setEnabled(false);
        }
    }
    
    /**
     * Checks the currently selected column. If no row is selected
     * and cell selection changes are permitted, it attempts to select
     * the row corresponding to the last selected bundle key.
     * 
     * @param  correctCellSelection  whether change of cell selection
     *                               in the table is permitted
     */
    private void updateSelection(final boolean correctCellSelection) {
        int row = table.getSelectedRow();
        int column = table.getSelectedColumn();
        
        if ((row == -1) && correctCellSelection) {
            final Element.ItemElem ex = lastSelectedBundleKey;
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    if (ex == null) {
                        return;
                    } 
                    String [] keys = structure.getKeys();
                    int idx;
                    for (idx = 0; idx < keys.length; idx++) {
                        String key = keys[idx];
                        if (key.equals(ex.getKey())) {
                            break;
                        }
                    }
                    if (idx < keys.length) {
                        table.requestFocusInWindow();
                        Rectangle rect = table.getCellRect(idx, 0, true);
                        table.scrollRectToVisible(rect);
                        table.changeSelection(idx, lastSelectedColumn, false, false);
                    }
                }
            });
        }
        
        lastSelectedColumn = column;
//        BundleStructure structure = obj.getBundleStructure();
        removeButton.setEnabled((row >= 0) && (!structure.isReadOnly()));
        String value;
        String comment;
        if (column == -1) {
            value = ""; // NOI18N
            comment = ""; // NOI18N
            lastSelectedBundleKey = null;
        } else if (column == 0) {
            Element.ItemElem elem = structure.getItem(0, row);
            value = structure.keyAt(row);
            lastSelectedBundleKey = elem;
            comment = (elem != null) ? elem.getComment() : "";          //NOI18N
        } else {
            Element.ItemElem elem = structure.getItem(column-1, row);
            if (elem != null) {
                value = elem.getValue();
                comment = elem.getComment();
            } else {
                value = "";                                             //NOI18N
                comment = "";                                           //NOI18N
            }
            lastSelectedBundleKey = elem;
        }
        textValue.getDocument().removeDocumentListener(listener);
        textComment.getDocument().removeDocumentListener(listener);
        textValue.setText(value);
        textComment.setText(comment);
        textValue.getDocument().addDocumentListener(listener);
        textComment.getDocument().addDocumentListener(listener);
    }
    
    private void updateAddButton() {
        addButton.setEnabled(!structure.isReadOnly());
    }
    
    /** Returns the main table with all values */
    public JTable getTable() {
        return table;
    }
    
    /** Initializes <code>settings</code> variable. */
    private void initSettings() {
        settings = TableViewSettings.getDefault();
                    
        // Listen on changes of setting settings.
        settings.addPropertyChangeListener(
            WeakListeners.propertyChange(this, settings)
        );
    }

    /**
     * Handler of settings changes
     */
    public void propertyChange(PropertyChangeEvent evt) {
        // settings changed 
        BundleEditPanel.this.repaint();
    }
    
    private void initAccessibility() {
        this.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_BundleEditPanel"));
        
        table.getAccessibleContext().setAccessibleName(NbBundle.getBundle(BundleEditPanel.class).getString("ACSN_CTL_Table"));
        table.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACSD_CTL_Table"));
        textValue.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_CTL_TEXTVALUE"));
        addButton.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_LBL_AddPropertyButton"));
        textComment.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_CTL_TEXTCOMMENT"));
        autoResizeCheck.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_CTL_AutoResize"));
        removeButton.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_LBL_RemovePropertyButton"));
    }
    
    @Override
    public boolean requestFocusInWindow() {
        return table.requestFocusInWindow();
    }
    
    /** 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 FormEditor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        tablePanel = new javax.swing.JPanel();
        scrollPane = new javax.swing.JScrollPane();
        table = new BundleTable();
        valuePanel = new javax.swing.JPanel();
        commentLabel = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        textComment = new javax.swing.JTextArea();
        valueLabel = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        textValue = new javax.swing.JTextArea();
        buttonPanel = new javax.swing.JPanel();
        addButton = new javax.swing.JButton();
        removeButton = new javax.swing.JButton();
        autoResizeCheck = new javax.swing.JCheckBox();

        setFocusCycleRoot(true);
        setLayout(new java.awt.GridBagLayout());

        tablePanel.setLayout(new java.awt.GridBagLayout());

        table.setCellSelectionEnabled(true);
        scrollPane.setViewportView(table);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 11);
        tablePanel.add(scrollPane, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        add(tablePanel, gridBagConstraints);

        valuePanel.setLayout(new java.awt.GridBagLayout());

        commentLabel.setLabelFor(textComment);
        org.openide.awt.Mnemonics.setLocalizedText(commentLabel, NbBundle.getBundle(BundleEditPanel.class).getString("LBL_CommentLabel")); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(11, 11, 0, 0);
        valuePanel.add(commentLabel, gridBagConstraints);

        textComment.setEditable(false);
        textComment.setLineWrap(true);
        textComment.setRows(3);
        textComment.setEnabled(false);
        jScrollPane2.setViewportView(textComment);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(11, 11, 0, 0);
        valuePanel.add(jScrollPane2, gridBagConstraints);

        valueLabel.setLabelFor(textValue);
        org.openide.awt.Mnemonics.setLocalizedText(valueLabel, NbBundle.getBundle(BundleEditPanel.class).getString("LBL_ValueLabel")); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(11, 11, 11, 0);
        valuePanel.add(valueLabel, gridBagConstraints);

        textValue.setEditable(false);
        textValue.setLineWrap(true);
        textValue.setRows(3);
        textValue.setEnabled(false);
        jScrollPane3.setViewportView(textValue);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(7, 11, 11, 0);
        valuePanel.add(jScrollPane3, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        add(valuePanel, gridBagConstraints);

        buttonPanel.setLayout(new java.awt.GridBagLayout());

        org.openide.awt.Mnemonics.setLocalizedText(addButton, NbBundle.getBundle(BundleEditPanel.class).getString("LBL_AddPropertyButton")); // NOI18N
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(11, 11, 0, 11);
        buttonPanel.add(addButton, gridBagConstraints);

        org.openide.awt.Mnemonics.setLocalizedText(removeButton, NbBundle.getBundle(BundleEditPanel.class).getString("LBL_RemovePropertyButton")); // NOI18N
        removeButton.setEnabled(false);
        removeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH;
        gridBagConstraints.insets = new java.awt.Insets(5, 11, 11, 11);
        buttonPanel.add(removeButton, gridBagConstraints);

        autoResizeCheck.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(autoResizeCheck, NbBundle.getBundle(BundleEditPanel.class).getString("CTL_AutoResize")); // NOI18N
        autoResizeCheck.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                autoResizeCheckActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 11);
        buttonPanel.add(autoResizeCheck, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        add(buttonPanel, gridBagConstraints);
    }// </editor-fold>//GEN-END:initComponents
    
    private void autoResizeCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_autoResizeCheckActionPerformed
        if (autoResizeCheck.isSelected()) {
            table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        } else {
            table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        }//GEN-LAST:event_autoResizeCheckActionPerformed
    }                                               
    
    private void removeButtonActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed
        int selectedRow = table.getSelectedRow();
        
        if (selectedRow == -1) {
            return;
        }
        
        stopEditing();
        String key = ((PropertiesTableModel.StringPair)table.getModel().getValueAt(selectedRow, 0)).getValue();
        
        // Don't remove elemnt with key == null ( this is only case -> when there is an empty file with comment only)
        if (key == null) {
            return;
        }
        
        NotifyDescriptor.Confirmation msg = new NotifyDescriptor.Confirmation(
        MessageFormat.format(
        NbBundle.getBundle(BundleEditPanel.class).getString("MSG_DeleteKeyQuestion"),
        new Object[] { key }
        ),
        NotifyDescriptor.OK_CANCEL_OPTION
        );
        
        if (DialogDisplayer.getDefault().notify(msg).equals(NotifyDescriptor.OK_OPTION)) {
            try {
                // Starts "atomic" acion for special undo redo manager of open support.
//                obj.getOpenSupport().atomicUndoRedoFlag = new Object();
                structure.getOpenSupport().atomicUndoRedoFlag = new Object();
                
                for (int i=0; i < structure.getEntryCount(); i++) {
                    PropertiesFileEntry entry = structure.getNthEntry(i);
                    if (entry != null) {
                        PropertiesStructure ps = entry.getHandler().getStructure();
                        if (ps != null) {
                            ps.deleteItem(key);
                        }
                    }
                }
            } finally {
                // finishes "atomic" undo redo action for special undo redo manager of open support
//                obj.getOpenSupport().atomicUndoRedoFlag = null;
                structure.getOpenSupport().atomicUndoRedoFlag = null;
            }
        }
    }//GEN-LAST:event_removeButtonActionPerformed
    
    /**
     * when this flag is set to {@code true}, method {@link #updateSelection}
     * does not actually change cell selection in the table.
     * <p>
     * This flag was added as a prevention from symptoms of bug #122347
     * ("value of new property is taken from the currently selected entry").
     * </p>
     */
    private boolean selectionUpdateDisabled = false;

    private void addButtonActionPerformed (java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
        stopEditing();
        
        final PropertyPanel panel = new PropertyPanel();
        
        Object selectedOption = DialogDisplayer.getDefault().notify(
                new DialogDescriptor(
                        panel,
                        NbBundle.getMessage(BundleEditPanel.class,
                                            "CTL_NewPropertyTitle")));  //NOI18N
        if (selectedOption != NotifyDescriptor.OK_OPTION) {
            return;
        }

        final String key = panel.getKey();
        String value = panel.getValue();
        String comment = panel.getComment();
        
        boolean keyAdded = false;
        
        try {
            selectionUpdateDisabled = true;

            // Starts "atomic" acion for special undo redo manager of open support.
//            obj.getOpenSupport().atomicUndoRedoFlag = new Object();
            structure.getOpenSupport().atomicUndoRedoFlag = new Object();
            String existingLocales = "";
            String comma =",\r\n";
            // add key to all entries
            for (int i=0; i < structure.getEntryCount(); i++) {
                PropertiesFileEntry entry = structure.getNthEntry(i);
                
                if (entry != null && !entry.getHandler().getStructure().addItem(key, value, comment)) {
                    existingLocales += Util.getLocaleLabel(entry) + comma;
                } else {
                    keyAdded = true;
                }
            }
            if (!existingLocales.equals("")) {
                    existingLocales = existingLocales.substring(0,existingLocales.length()-comma.length());
                    NotifyDescriptor.Message msg = new NotifyDescriptor.Message(
                    MessageFormat.format(
                    NbBundle.getBundle(BundleEditPanel.class).getString("MSG_KeyExists"),
                    new Object[] {
                        key,
                        existingLocales
                    }
                    ),
                    NotifyDescriptor.ERROR_MESSAGE);
                    DialogDisplayer.getDefault().notify(msg);
            }
        } finally {
            // Finishes "atomic" undo redo action for special undo redo manager of open support.
//            obj.getOpenSupport().atomicUndoRedoFlag = null;
            structure.getOpenSupport().atomicUndoRedoFlag = null;

            selectionUpdateDisabled = false;
        }
        
        if(keyAdded) {
            // Item was added succesfully, go to edit it.
            // PENDING: this is in request processor queue only
            // due to reason that properties structure has just after
            // adding new item inconsistence gap until it's reparsed anew.
            // This should be removed when the parsing will be redsigned.
            PropertiesRequestProcessor.getInstance().post(new Runnable() {
                public void run() {
                    // Find indexes.
                    int rowIndex = structure.getKeyIndexByName(key);
                    
                    if((rowIndex != -1)) {
                        final int row = rowIndex;
                        final int column = 1; // Default locale.
                        
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                try {
                                    selectionUpdateDisabled = true;

                                    // Autoscroll to cell if possible and necessary.
                                    if(table.getAutoscrolls()) {
                                        Rectangle cellRect = table.getCellRect(row, column, false);
                                        if (cellRect != null) {
                                            table.scrollRectToVisible(cellRect);
                                        }
                                    }
                                    
                                    // Update selection & edit.
                                    table.getColumnModel().getSelectionModel().setSelectionInterval(column, column);
                                    table.getSelectionModel().setSelectionInterval(row, row);
                                    
                                    table.requestFocusInWindow();
                                    table.editCellAt(row, column);
                                } finally {
                                    selectionUpdateDisabled = false;
                                }
                            }
                        });
                    }
                }
            });
        }
    }//GEN-LAST:event_addButtonActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JCheckBox autoResizeCheck;
    private javax.swing.JPanel buttonPanel;
    private javax.swing.JLabel commentLabel;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JButton removeButton;
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JTable table;
    private javax.swing.JPanel tablePanel;
    private javax.swing.JTextArea textComment;
    private javax.swing.JTextArea textValue;
    private javax.swing.JLabel valueLabel;
    private javax.swing.JPanel valuePanel;
    // End of variables declaration//GEN-END:variables
    
    
    /** Header renderer used in table view. */
    @SuppressWarnings("serial")
    private static final class TableViewHeaderRenderer implements TableCellRenderer {

        /*
         * The source code of this class is a slightly modified copy
         * of source code of class
         * org.netbeans.modules.tasklist.ui.TaskListTable.SortingHeaderRenderer.
         */
        
        private static final String ICON_PKG = "org/netbeans/modules/properties/";      //NOI18N
        private static final String SORT_ASC_ICON = ICON_PKG + "columnSortedAsc.gif";   //NOI18N
        private static final String SORT_DESC_ICON = ICON_PKG + "columnSortedDesc.gif"; //NOI18N

        private final BundleStructure bundleStructure;
        private final TableCellRenderer origRenderer;
        private ImageIcon iconSortAsc, iconSortDesc;

        @Deprecated
        TableViewHeaderRenderer(PropertiesDataObject propDataObj,
                                TableCellRenderer origRenderer) {
            bundleStructure = propDataObj.getBundleStructure();
            this.origRenderer = origRenderer;
        }

        TableViewHeaderRenderer(BundleStructure bundleStructure,
                                TableCellRenderer origRenderer) {
            this.bundleStructure = bundleStructure;
            this.origRenderer = origRenderer;
        }

        public Component getTableCellRendererComponent(JTable table,
                                                       Object value,
                                                       boolean isSelected,
                                                       boolean hasFocus,
                                                       int row,
                                                       int column) {
            Component comp = origRenderer.getTableCellRendererComponent(
                               table, value, isSelected, hasFocus, row, column);

            if (comp instanceof JLabel) {
                JLabel label = (JLabel) comp;
                BundleStructure bundleStruct = bundleStructure;
                int sortIndex = table.convertColumnIndexToView(
                                        bundleStruct.getSortIndex());
                if (column == sortIndex) {
                    boolean ascending = bundleStruct.getSortOrder();
                    label.setIcon(getSortIcon(ascending));
                    label.setHorizontalTextPosition(SwingConstants.LEFT);
                } else {
                    label.setIcon(null);
                }
            }

            return comp;
        }

        private ImageIcon getSortIcon(boolean ascending) {
            if (ascending) {
                if (iconSortAsc == null) {
                    iconSortAsc = ImageUtilities.loadImageIcon(SORT_ASC_ICON, false);
                }
                return iconSortAsc;
            } else {
                if (iconSortDesc == null) {
                    iconSortDesc = ImageUtilities.loadImageIcon(SORT_DESC_ICON, false);
                }
                return iconSortDesc;
            }
        }

    } // End of inner class TableViewHeaderRenderer.
    

    /**
     * This subclass of Default column model is provided due correct set of column widths,
     * see the JTable and horizontal scrolling problem in Java Discussion Forum.
     */
    @SuppressWarnings("serial")
    private class TableViewColumnModel extends DefaultTableColumnModel {
        /** Helper listener. */
        private AncestorListener ancestorListener;

        @Override
        public void moveColumn(int fromIndex, int toIndex) {
            super.moveColumn(fromIndex, toIndex);
            if (fromIndex == 0 || toIndex==0) {
                if (fromIndex != toIndex) {
                    super.moveColumn(toIndex, fromIndex);
                }
            }
        }


        /** Overrides superclass method. */
        @Override
        public void addColumn(TableColumn aColumn) {
            if (aColumn == null) {
                throw new IllegalArgumentException("Object is null"); // NOI18N
            }
            
            tableColumns.addElement(aColumn);
            aColumn.addPropertyChangeListener(this);
            
            // this method call is only difference with overriden superclass method
            adjustColumnWidths();
            
            // Post columnAdded event notification
            fireColumnAdded(new TableColumnModelEvent(this, 0,
            getColumnCount() - 1));
        }
        
        /** Helper method adjusting the table according top component or mode which contains it, the
         * minimal width of column is 1/10 of screen width. */
        private void adjustColumnWidths() {
            // The least initial width of column (1/10 of screen witdh).
            Rectangle screenBounds = org.openide.util.Utilities.getUsableScreenBounds();
            int columnWidth = screenBounds.width / 10;
            
            // Try to set widths according parent (viewport) width.
            int totalWidth = 0;
            TopComponent tc = (TopComponent)SwingUtilities.getAncestorOfClass(TopComponent.class, table);
            if(tc != null) {
                totalWidth = tc.getBounds().width;
            } else {
                if(ancestorListener == null) {
                    table.addAncestorListener(ancestorListener = new AncestorListener() {
                        /** If the ancestor is TopComponent adjustColumnWidths. */
                        public void ancestorAdded(AncestorEvent evt) {
                            if(evt.getAncestor() instanceof TopComponent) {
                                adjustColumnWidths();
                                table.removeAncestorListener(ancestorListener);
                                ancestorListener = null;
                            }
                        }
                        
                        /** Does nothing. */
                        public void ancestorMoved(AncestorEvent evt) {
                        }
                        
                        /** Does nothing. */
                        public void ancestorRemoved(AncestorEvent evt) {
                        }
                    });
                }
            }
            
            // Decrease of insets of scrollpane and insets set in layout manager.
            // Note: Layout constraints hardcoded instead of getting via method call ->
            // keep consistent with numbers in initComponents method.
            totalWidth -= scrollPane.getInsets().left + scrollPane.getInsets().right + 12 + 11;
            
            // Helper variable for keeping additional pixels which remains after division.
            int remainder = 0;
            
            // If calculations were succesful try to set the widths in case calculated width
            // for one column is not less than 1/10 of screen width.
            if(totalWidth > 0) {
                int computedColumnWidth = totalWidth / table.getColumnCount();
                if(computedColumnWidth > columnWidth) {
                    columnWidth = computedColumnWidth - table.getColumnModel().getColumnMargin();
                    remainder = totalWidth % table.getColumnCount();
                }
            }
            
            // Set the column widths.
            for (int i = 0; i < table.getColumnCount(); i++) {
                TableColumn column = table.getColumnModel().getColumn(i);
                
                // Add remainder to first column.
                if(i==0) {
                    // It is necessary to set both 'widths', see javax.swing.TableColumn.
                    column.setPreferredWidth(columnWidth + remainder);
                    column.setWidth(columnWidth + remainder);
                } else {
                    // It is necessary to set both 'widths', see javax.swing.TableColumn.
                    column.setPreferredWidth(columnWidth);
                    column.setWidth(columnWidth);
                }
            }
            
            // Recalculate total column width.
            recalcWidthCache();
            
            // Revalidate table so the widths will fit properly.
            table.revalidate();
            
            // Repaint header afterwards. Seems stupid but necessary.
            table.getTableHeader().repaint();
        }
    } // End of inner class TableViewColumnModel.


    /** Renderer which renders cells in table view. */
    @SuppressWarnings("serial")
    private class TableViewRenderer extends DefaultTableCellRenderer {
        /** Overrides superclass method. */
        @Override
        public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            
            if (value == null) {
                return this;
            }
            
            PropertiesTableModel.StringPair sp = (PropertiesTableModel.StringPair)value;                        
            
            setFont(settings.getFont());
            
            if(hasFocus) {
                setBorder(UIManager.getBorder("Table.focusCellHighlightBorder") ); // NOI18N
            } else {
                setBorder(noFocusBorder);
            }
            
            String text = null;
            
            if(sp.getValue() != null) {
                text = sp.getValue();
            }
            
            // XXX Ugly hack to prevent problems showing 'html-ed' labels.
            if(BasicHTML.isHTMLString(text)) { // NOI18N
                text = " " + text; // NOI18N
            }
            
            setValue(text == null ? "" : text); // NOI18N
            
            // Set background color.
            if (sp.isKeyType()) {
                setBackground(settings.getKeyBackground());
            } else {
                if (sp.getValue() != null) {
                    setBackground(settings.getValueBackground());
                } else {
                    setBackground(settings.getShadowColor());
                }
            }
            
            // Set foregound color.
            if (sp.isKeyType()) {
                setForeground(settings.getKeyColor());
            } else {
                setForeground(settings.getValueColor());
            }
            
            // Optimization to avoid painting background if is the same like table's.
            Color back = getBackground();
            boolean colorMatch = (back != null) && (back.equals(table.getBackground()) ) && table.isOpaque();
            setOpaque(!colorMatch);
            
            return this;
        }
        
        /** Overrides superclass method. It adds the highlighting of search occurences in it. */
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            
            // If there is a highlihgt flag set do additional drawings.
            if(FindPerformer.getFindPerformer(BundleEditPanel.this.table).isHighlightSearch()) {
                String text = getText();
                String findString = FindPerformer.getFindPerformer(BundleEditPanel.this.table).getFindString();
                
                // If there is a findString and the cell could contain it go ahead.
                if(text != null && text.length()>0 && findString != null && findString.length()>0) {
                    int index = 0;
                    int width = (int)g.getFontMetrics().getStringBounds(findString, g).getWidth();
                    
                    Color oldColor = g.getColor();
                    // In each iteration highlight one occurence of findString in this cell.
                    while((index = text.indexOf(findString, index)) >= 0) {
                        
                        int x = (int)g.getFontMetrics().getStringBounds(text.substring(0, index), g).getWidth()+this.getInsets().left;
                        
                        g.setColor(settings.getHighlightBackground());
                        g.fillRect(x, 0, width, g.getClipBounds().height);
                        
                        g.setColor(settings.getHighlightColor());
                        g.drawString(findString, x, -(int)g.getFontMetrics().getStringBounds(findString, g).getY());
                        
                        index += findString.length();
                    }
                    // Reset original color.
                    g.setColor(oldColor);
                }
            }
        }
    } // End of inner class TableViewRenderer.
    


    /** <code>JTable</code> with one bug fix.
     * @see #removeEditorSilent */
    @SuppressWarnings("serial")
    static class BundleTable extends JTable {

        public BundleTable(){
            super();
            this.setRowHeight(getCellFontHeight() + 1);
        }

        @Override
        public int convertColumnIndexToModel(int arg0) {
            return arg0;
        }

        @Override
        public int convertColumnIndexToView(int arg0) {
            return arg0;
        }


        @Override
        public void columnMoved(TableColumnModelEvent evt) {
            if (evt.getFromIndex() == evt.getToIndex()) {
                //This case needed because when specifying equal indexes, but not null,
                //it is not passed  to propertyChange method 
                firePropertyChange("columnMoved", null,null); //NOI18N
            } else
                firePropertyChange("columnMoved", evt.getFromIndex(), evt.getToIndex()); //NOI18N
            super.columnMoved(evt);
        }
        @Override
        public void columnMarginChanged(ChangeEvent evt) {
            if (this.isEditing()) {
            //Need to notify table's PropertyChangeListener to save editing values
                firePropertyChange("marginChanged", null, null); //NOI18N
            }
            super.columnMarginChanged(evt);
        }
        
        /**
         * The same like superclass removeEditor except it doesn't request focus back to table.
         * We need this kind of behaviour (see bug in IssueaZilla #9237). The table shoudl request focus
         * after canceling editing when is showing only (submit bug to jdk ?).
         * @see javax.swing.JTable#removeEditor */
        public void removeEditorSilent() {
            TableCellEditor editor = getCellEditor();
            if(editor != null) {
                editor.removeCellEditorListener(this);
                
                // requestFocus();
                if (editorComp != null) {
                    remove(editorComp);
                }
                
                Rectangle cellRect = getCellRect(editingRow, editingColumn, false);

                setCellEditor(null);
                setEditingColumn(-1);
                setEditingRow(-1);
                editorComp = null;
                
                repaint(cellRect);
            }
        }
        
        private int getCellFontHeight() {
            Font cellFont = UIManager.getFont("TextField.font");
            if (cellFont != null) {
                FontMetrics fm = getFontMetrics(cellFont);
                if (fm != null) {
                    return fm.getHeight();
                }
            }
            return 14;
        }        
        
    } // End of BundleTable class.
    private class ModifiedListener implements DocumentListener {
        
        public void changedUpdate(DocumentEvent e) {
            documentModified();
        }
        
        public void insertUpdate(DocumentEvent e) {
            documentModified();
        }
        
        public void removeUpdate(DocumentEvent e) {
            documentModified();
        }
        
        private void documentModified() {
            int column = table.getEditingColumn();
            if (column != 0) {
                ((PropertiesTableModel)table.getModel()).getFileEntry(column).getDataObject().setModified(true);
//            obj.setModified(true);
            } else {
                //Modified Key column need setModified all files in bundle
                for (int i = 0; i<structure.getEntryCount();i++) {
                    PropertiesDataObject dataObject = (PropertiesDataObject) structure.getNthEntry(i).getDataObject();
                    dataObject.setModified(true);
                }
            }
        }
        
    }

}
