/*
 * 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.apache.log4j.chainsaw.receivers;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.AbstractCellEditor;
import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;

import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.chainsaw.ChainsawConstants;
import org.apache.log4j.chainsaw.Generator;
import org.apache.log4j.chainsaw.helper.TableCellEditorFactory;
import org.apache.log4j.net.SocketHubReceiver;
import org.apache.log4j.plugins.Plugin;


/**
 * A panel that allows the user to edit a particular Plugin, by using introspection
 * this class discovers the modifiable properties of the Plugin
 * @author Paul Smith &lt;psmith@apache.org&gt;
 */
public class PluginPropertyEditorPanel extends JPanel {

    private final JScrollPane scrollPane = new JScrollPane();
    private final JTable propertyTable = new JTable();

    private Plugin plugin;
    private TableModel defaultModel = new DefaultTableModel(
            new String[] { "Property", "Value" }, 1);

    private static final Logger logger = LogManager.getLogger(PluginPropertyEditorPanel.class);
    /**
     *
     */
    public PluginPropertyEditorPanel() {
        super();
        initComponents();
        setupListeners();
    }

    /**
     *
     */
    private void initComponents() {
        propertyTable.setRowHeight(ChainsawConstants.DEFAULT_ROW_HEIGHT);
        setLayout(new BorderLayout());
        scrollPane.setViewportView(propertyTable);

        add(scrollPane, BorderLayout.CENTER);

        propertyTable.setModel(
            defaultModel = new DefaultTableModel(
                    new String[] { "Property", "Value" }, 1));

    }

    /**
     *
     */
    private void setupListeners() {
        addPropertyChangeListener("plugin", new PropertyChangeListener() {

                public void propertyChange(PropertyChangeEvent evt) {

                    final Plugin p = (Plugin) evt.getNewValue();

                    if (p != null) {

                        try {

                            PluginPropertyTableModel model =
                                new PluginPropertyTableModel(p);
                            propertyTable.setModel(model);
                            propertyTable.getColumnModel().getColumn(1)
                            .setCellEditor(new PluginTableCellEditor());
                            propertyTable.setEnabled(true);
                        } catch (Throwable e) {
                            logger.error("Failed to introspect the Plugin", e);
                        }
                    } else {
                        propertyTable.setModel(defaultModel);
                        propertyTable.setEnabled(false);
                    }

                }
            });
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame("Property Editor Test bed");
        frame.addWindowListener(new WindowAdapter() {
                public void windowClosed(WindowEvent e) {
                    System.exit(1);
                }
            });

        PluginPropertyEditorPanel panel = new PluginPropertyEditorPanel();


        frame.getContentPane().add(panel);
        frame.pack();

        frame.setVisible(true);

        SocketHubReceiver r = new SocketHubReceiver();

        panel.setPlugin(r);

        try {
            Thread.sleep(3000);

            panel.setPlugin(new Generator("MyPlugin"));
        } catch (Exception e) {
            // TODO: handle exception
        }


    }

    /**
     * @return Returns the plugin.
     */
    public final Plugin getPlugin() {

        return plugin;
    }

    /**
     * @param plugin The plugin to set.
     */
    public final void setPlugin(Plugin plugin) {

        Plugin oldValue = this.plugin;
        this.plugin = plugin;
        firePropertyChange("plugin", oldValue, this.plugin);
    }

    /**
     * @author psmith
     *
     */
    private class PluginTableCellEditor extends AbstractCellEditor
        implements TableCellEditor {

        private Map editorMap = new HashMap();
        private DefaultCellEditor defaultEditor = new DefaultCellEditor(
                new JTextField());
        private DefaultCellEditor currentEditor = defaultEditor;

        private PluginTableCellEditor() {

            editorMap.put(Boolean.class,
                TableCellEditorFactory.createBooleanTableCellEditor());
            editorMap.put(Level.class,
                TableCellEditorFactory.createLevelTableCellEditor());
            //support primitive boolean parameters with the appropriate editor
            editorMap.put(boolean.class, TableCellEditorFactory.createBooleanTableCellEditor());
        }

        /* (non-Javadoc)
         * @see javax.swing.table.TableCellEditor#getTableCellEditorComponent(javax.swing.JTable, java.lang.Object, boolean, int, int)
         */
        public Component getTableCellEditorComponent(JTable table, Object value,
            boolean isSelected, int row, int column) {

           PluginPropertyTableModel model = (PluginPropertyTableModel) table.getModel();
           PropertyDescriptor descriptor =  model.getDescriptors()[row];
           Class valueClass = descriptor.getPropertyType();
           
            if (editorMap.containsKey(valueClass)) {

                DefaultCellEditor editor =
                    (DefaultCellEditor) editorMap.get(valueClass);
                logger.debug("Located CellEditor for " + valueClass);
                currentEditor = editor;

                return currentEditor.getTableCellEditorComponent(table, value,
                    isSelected, row, column);
            }

            currentEditor = defaultEditor;
            logger.debug("Cell value class " + valueClass +
                " not know, using default editor");

            return defaultEditor.getTableCellEditorComponent(table, value,
                isSelected, row, column);
        }

        /* (non-Javadoc)
         * @see javax.swing.CellEditor#getCellEditorValue()
         */
        public Object getCellEditorValue() {

            return currentEditor.getCellEditorValue();
        }

    }

    private static class PluginPropertyTableModel extends AbstractTableModel {

        private final PropertyDescriptor[] descriptors;
        private final Plugin plugin;

        private PluginPropertyTableModel(Plugin p)
            throws IntrospectionException {
            super();

            BeanInfo beanInfo = Introspector.getBeanInfo(p.getClass());

            List list = new ArrayList(Arrays.asList(
                        beanInfo.getPropertyDescriptors()));

            Collections.sort(list, new Comparator() {

                    public int compare(Object o1, Object o2) {

                        PropertyDescriptor d1 = (PropertyDescriptor) o1;
                        PropertyDescriptor d2 = (PropertyDescriptor) o2;

                        return d1.getDisplayName().compareToIgnoreCase(
                            d2.getDisplayName());
                    }
                });
            this.plugin = p;
            this.descriptors = (PropertyDescriptor[]) list.toArray(
                    new PropertyDescriptor[0]);
        }

        /* (non-Javadoc)
         * @see javax.swing.table.AbstractTableModel#getValueAt(int, int)
         */
        public Object getValueAt(int row, int col) {

            PropertyDescriptor d = descriptors[row];

            switch (col) {

            case 1:

                try {

                    Object object = d.getReadMethod().invoke(plugin);

                    if (object != null) {

                        return object;
                    }
                } catch (Exception e) {
                    logger.error(
                        "Error reading value for PropertyDescriptor " + d);
                }

                return "";

            case 0:
                return d.getName();
            }

            return null;
        }

        /* (non-Javadoc)
         * @see javax.swing.table.AbstractTableModel#getColumnCount()
         */
        public int getColumnCount() {

            return 2;
        }

        /* (non-Javadoc)
         * @see javax.swing.table.AbstractTableModel#getRowCount()
         */
        public int getRowCount() {

            return descriptors.length;
        }

        /* (non-Javadoc)
         * @see javax.swing.table.TableModel#isCellEditable(int, int)
         */
        public boolean isCellEditable(int rowIndex, int columnIndex) {

//        TODO Determine if the property is one of the ones a User could edit
            if (columnIndex == 1) {

                return descriptors[rowIndex].getWriteMethod() != null;
            }

            return false;
        }

        /* (non-Javadoc)
         * @see javax.swing.table.TableModel#getColumnName(int)
         */
        public String getColumnName(int column) {

            return (column == 0) ? "Property" : "Value";
        }

        /* (non-Javadoc)
         * @see javax.swing.table.TableModel#setValueAt(java.lang.Object, int, int)
         */
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {


            if (columnIndex == 1) {
                //ensure name is set
                if (descriptors[rowIndex].getName().equalsIgnoreCase("name") && (aValue == null || aValue.toString().trim().equals(""))) {
                    logger.error("Name required");
                    return;
                }
                aValue = translateValueIfNeeded(rowIndex, aValue);
                logger.debug(
                    "setValueAt, " + rowIndex + ", " + columnIndex +
                    ", value=" + aValue + ", valueClass" + aValue.getClass());

                try {
                    descriptors[rowIndex].getWriteMethod().invoke(plugin,
                            aValue);
                    fireTableCellUpdated(rowIndex, columnIndex);
                } catch (IllegalArgumentException e) {
                    // ignore
                } catch (Exception e) {
                    logger.error(
                        "Failed to modify the Plugin because of Exception", e);
                }

            } else {
                super.setValueAt(aValue, rowIndex, columnIndex);
            }
        }

        /**
         * @param row
         * @param value
         * @return
         */
        private Object translateValueIfNeeded(int row, Object value) {

            if ((descriptors[row].getPropertyType() == int.class) ||
                    (descriptors[row].getPropertyType() == Integer.class)) {

                try {

                    return Integer.valueOf(value.toString());
                } catch (Exception e) {
                    logger.error("Failed to convert to Integer type");
                }
            }

            return value;
        }
        /**
         * @return Returns the descriptors.
         */
        public final PropertyDescriptor[] getDescriptors() {
          return descriptors;
        }
    }
}
