/*******************************************************************************
 * Copyright (c) 2012, 2020 Dirk Fauth and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Dirk Fauth - initial API and implementation
 *******************************************************************************/
package org.eclipse.nebula.widgets.nattable.persistence.gui;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.nebula.widgets.nattable.Messages;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.columnChooser.command.DisplayColumnChooserCommandHandler;
import org.eclipse.nebula.widgets.nattable.persistence.PersistenceHelper;
import org.eclipse.nebula.widgets.nattable.persistence.command.DisplayPersistenceDialogCommand;
import org.eclipse.nebula.widgets.nattable.persistence.command.DisplayPersistenceDialogCommandHandler;
import org.eclipse.nebula.widgets.nattable.persistence.command.IStateChangedListener;
import org.eclipse.nebula.widgets.nattable.persistence.command.StateChangeEvent;
import org.eclipse.nebula.widgets.nattable.persistence.command.StateChangeEvent.StateChangeType;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * Dialog that allows to save and load NatTable state. It will operate on the
 * the specified NatTable and Properties instances. If the Properties need to be
 * persisted e.g. in the file system, the developer has to take care of that
 * himself.
 *
 * <p>
 * It is possible to listen for state change events on the view configurations.
 * Rather than adding listeners to this dialog yourself, you should register the
 * listeners to the {@link DisplayColumnChooserCommandHandler}, as it will
 * handle propagating the listeners to newly created instances of this dialog.
 *
 * @see DisplayPersistenceDialogCommand
 * @see DisplayPersistenceDialogCommandHandler
 */
public class PersistenceDialog extends Dialog {

    /**
     * Key under which the name of the active view configuration is stored
     * within the properties. Used to indicate which view configuration is
     * currently active and to be able to restore a view based on the last
     * active one, when persisting the states to a file or database.
     */
    public static final String ACTIVE_VIEW_CONFIGURATION_KEY = "PersistenceDialog.activeViewConfiguration"; //$NON-NLS-1$

    /**
     * Constant ID for the save button of this dialog.
     */
    public static final int SAVE_ID = 2;

    /**
     * Constant ID for the load button of this dialog.
     */
    public static final int LOAD_ID = 3;

    /**
     * Constant ID for the delete button of this dialog.
     */
    public static final int DELETE_ID = 4;

    /**
     * The NatTable instance to apply the save/load operations.
     */
    private NatTable natTable;

    /**
     * The Properties instance that should be used for saving and loading.
     */
    private Properties properties;

    /**
     * Viewer containing the state configurations.
     */
    private TableViewer viewer;

    /**
     * The decoration for the configNameText field. Needed for showing an error
     * when trying to invoke save with an empty name.
     */
    private ControlDecoration configNameDeco;

    /**
     * Text input field for specifying the name of a configuration. If there is
     * no input in this field when saving a state configuration the default
     * state configuration will be used.
     */
    private Text configNameText;

    /**
     * List of {@link IStateChangedListener}s that will be notified if states
     * are changed using this dialog.
     */
    private List<IStateChangedListener> stateChangeListeners = new ArrayList<IStateChangedListener>();

    /**
     * Create a new dialog for handling NatTable state.
     *
     * @param parentShell
     *            the parent shell, or <code>null</code> to create a top-level
     *            shell
     * @param natTable
     *            The NatTable instance to apply the save/load operations.
     * @param properties
     *            The Properties instance that should be used for saving and
     *            loading.
     */
    public PersistenceDialog(Shell parentShell, NatTable natTable,
            Properties properties) {
        super(parentShell);
        setShellStyle(SWT.RESIZE | SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);

        if (natTable == null) {
            throw new IllegalArgumentException("natTable can not be null!"); //$NON-NLS-1$
        }
        if (properties == null) {
            throw new IllegalArgumentException("properties can not be null!"); //$NON-NLS-1$
        }

        this.natTable = natTable;
        this.properties = properties;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets
     * .Composite)
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        Composite control = (Composite) super.createDialogArea(parent);

        Label viewerLabel = new Label(control, SWT.NONE);
        viewerLabel
                .setText(Messages.getString("PersistenceDialog.viewerLabel")); //$NON-NLS-1$
        GridDataFactory.fillDefaults().grab(true, false).applyTo(viewerLabel);

        this.viewer = new TableViewer(control);
        this.viewer.setContentProvider(new ArrayContentProvider());
        this.viewer.setLabelProvider(new ViewConfigurationNameLabelProvider());

        // sort in alphabetical order
        this.viewer.setComparator(new ViewerComparator());

        GridDataFactory.fillDefaults().grab(true, true)
                .applyTo(this.viewer.getControl());

        // layout textbox
        Composite nameContainer = new Composite(control, SWT.NONE);
        GridLayout layout = new GridLayout(2, false);
        layout.marginWidth = 0;
        nameContainer.setLayout(layout);
        GridDataFactory.fillDefaults().grab(true, false).applyTo(nameContainer);
        Label label = new Label(nameContainer, SWT.NONE);
        label.setText(Messages.getString("PersistenceDialog.nameLabel")); //$NON-NLS-1$
        this.configNameText = new Text(nameContainer, SWT.BORDER);
        GridDataFactory.fillDefaults().grab(true, false)
                .applyTo(this.configNameText);

        this.configNameText.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent event) {
                if ((event.keyCode == SWT.CR && event.stateMask == 0)
                        || (event.keyCode == SWT.KEYPAD_CR && event.stateMask == 0)) {
                    buttonPressed(SAVE_ID);
                }
            }
        });

        this.configNameText.addModifyListener(new ModifyListener() {

            @Override
            public void modifyText(ModifyEvent e) {
                if (PersistenceDialog.this.configNameText.getText().length() != 0) {
                    PersistenceDialog.this.configNameDeco.hide();
                }
            }
        });

        this.configNameDeco = new ControlDecoration(this.configNameText,
                SWT.RIGHT);
        Image image = FieldDecorationRegistry.getDefault()
                .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR)
                .getImage();
        this.configNameDeco.setDescriptionText(Messages
                .getString("PersistenceDialog.nameErrorText")); //$NON-NLS-1$
        this.configNameDeco.setImage(image);
        this.configNameDeco.hide();

        // add click listener on viewer
        this.viewer
                .addSelectionChangedListener(new ISelectionChangedListener() {

                    @Override
                    public void selectionChanged(SelectionChangedEvent event) {
                        ISelection selection = event.getSelection();
                        if (selection != null
                                && selection instanceof IStructuredSelection) {
                            String configName = ((IStructuredSelection) selection)
                                    .getFirstElement().toString();
                            PersistenceDialog.this.configNameText.setText(configName);
                        }
                    }
                });

        // add double click listener
        this.viewer.addDoubleClickListener(new IDoubleClickListener() {

            @Override
            public void doubleClick(DoubleClickEvent event) {
                buttonPressed(LOAD_ID);
            }
        });

        this.viewer.add(PersistenceHelper.getAvailableStates(this.properties)
                .toArray());

        return control;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse
     * .swt.widgets.Composite)
     */
    @Override
    protected void createButtonsForButtonBar(Composite parent) {
        createButton(parent, DELETE_ID,
                Messages.getString("PersistenceDialog.buttonDelete"), false); //$NON-NLS-1$
        createButton(parent, SAVE_ID,
                Messages.getString("PersistenceDialog.buttonSave"), false); //$NON-NLS-1$
        createButton(parent, LOAD_ID,
                Messages.getString("PersistenceDialog.buttonLoad"), false); //$NON-NLS-1$
        createButton(parent, IDialogConstants.OK_ID,
                Messages.getString("PersistenceDialog.buttonDone"), false); //$NON-NLS-1$
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
     */
    @Override
    protected void buttonPressed(int buttonId) {
        if (buttonId == SAVE_ID) {
            String configName = this.configNameText.getText();
            if (configName == null || configName.length() == 0) {
                // it is not possible to store an empty configuration with this
                // dialog
                // this is because the configuration with an empty name is the
                // default
                // configuration
                this.configNameDeco.show();
                return;
            } else {
                this.configNameDeco.hide();
            }
            this.natTable.saveState(configName, this.properties);
            String oldActiveName = getActiveViewConfigurationName();
            setActiveViewConfigurationName(configName);
            this.viewer.refresh(oldActiveName, true);

            this.configNameText.setText(""); //$NON-NLS-1$

            for (int i = 0; i < this.viewer.getTable().getItemCount(); i++) {
                String element = this.viewer.getElementAt(i).toString();
                if (configName.equals(element)) {
                    // fire event for a changed view configuration
                    fireStateChange(new StateChangeEvent(configName,
                            StateChangeType.CHANGE));
                    return;
                }
            }

            this.viewer.add(configName);
            // fire event for a newly created view configuration
            fireStateChange(new StateChangeEvent(configName,
                    StateChangeType.CREATE));
        } else if (buttonId == DELETE_ID) {
            ISelection selection = this.viewer.getSelection();
            if (selection != null && selection instanceof IStructuredSelection) {
                String configName = ((IStructuredSelection) selection)
                        .getFirstElement().toString();
                PersistenceHelper.deleteState(configName, this.properties);
                // remove the state name out of the viewer
                this.viewer.getTable().deselectAll();
                this.viewer.remove(configName);
                this.configNameText.setText(""); //$NON-NLS-1$
                // fire event for a deleted view configuration
                fireStateChange(new StateChangeEvent(configName,
                        StateChangeType.DELETE));
            }
        } else if (buttonId == LOAD_ID) {
            ISelection selection = this.viewer.getSelection();
            if (selection != null && selection instanceof IStructuredSelection) {
                String configName = ((IStructuredSelection) selection)
                        .getFirstElement().toString();
                this.natTable.loadState(configName, this.properties);
                setActiveViewConfigurationName(configName);
            }
            super.okPressed();
        } else {
            super.buttonPressed(buttonId);
        }
    }

    @Override
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setText(Messages.getString("PersistenceDialog.title")); //$NON-NLS-1$
        newShell.setImage(GUIHelper.getImage("table_icon")); //$NON-NLS-1$
    }

    @Override
    protected Point getInitialSize() {
        return new Point(
                GUIHelper.convertHorizontalPixelToDpi(500, true),
                GUIHelper.convertVerticalPixelToDpi(300, true));
    };

    /**
     * @return The Properties instance that is used for saving and loading.
     */
    public Properties getProperties() {
        return this.properties;
    }

    /**
     * @param properties
     *            The Properties instance that should be used for saving and
     *            loading.
     */
    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    /**
     * @return The name of the current active view configuration
     */
    public String getActiveViewConfigurationName() {
        return this.properties.getProperty(ACTIVE_VIEW_CONFIGURATION_KEY);
    }

    /**
     * Sets the name of the current active view configuration. Note that this
     * method does not set the active view configuration programmatically. It is
     * just used to support highlighting the current active view configuration
     * in the viewer of this dialog.
     *
     * @param name
     *            The name of the current active view configuration
     */
    public void setActiveViewConfigurationName(String name) {
        this.properties.setProperty(ACTIVE_VIEW_CONFIGURATION_KEY, name);
    }

    /**
     * Add the given {@link IStateChangedListener} to the local list of
     * listeners.
     *
     * @param listener
     *            The listener to add.
     */
    public void addStateChangeListener(IStateChangedListener listener) {
        this.stateChangeListeners.add(listener);
    }

    /**
     * Adds the given {@link IStateChangedListener}s to the local list of
     * listeners.
     *
     * @param listeners
     *            The listeners to add.
     */
    public void addAllStateChangeListener(List<IStateChangedListener> listeners) {
        this.stateChangeListeners.addAll(listeners);
    }

    /**
     * Removes the given {@link IStateChangedListener} from the local list of
     * listeners.
     *
     * @param listener
     *            The listener to remove.
     */
    public void removeStateChangeListener(IStateChangedListener listener) {
        this.stateChangeListeners.remove(listener);
    }

    /**
     * Removes the given {@link IStateChangedListener}s from the local list of
     * listeners.
     *
     * @param listeners
     *            The listeners to remove.
     */
    public void removeAllStateChangeListener(
            List<IStateChangedListener> listeners) {
        this.stateChangeListeners.removeAll(listeners);
    }

    /**
     * Inform all registered listeners about the state change.
     *
     * @param event
     *            The {@link StateChangeEvent} object.
     */
    public void fireStateChange(StateChangeEvent event) {
        for (IStateChangedListener listener : this.stateChangeListeners) {
            listener.handleStateChange(event);
        }
    }

    /**
     * Special StyledCellLabelProvider that will render the default view
     * configuration italic, so a user will know that there is something special
     * about it. Will also add a leading '*' to the current active view
     * configuration.
     */
    class ViewConfigurationNameLabelProvider extends StyledCellLabelProvider {
        private Font italicFont;
        private Styler italicStyler;

        ViewConfigurationNameLabelProvider() {
            this.italicFont = GUIHelper.getFont(new FontData[] { new FontData("Arial", 8, SWT.ITALIC) }); //$NON-NLS-1$
            this.italicStyler = new Styler() {
                @Override
                public void applyStyles(TextStyle textStyle) {
                    textStyle.font = ViewConfigurationNameLabelProvider.this.italicFont;
                }
            };
        }

        @Override
        public void update(ViewerCell cell) {
            Object element = cell.getElement();
            String result = element == null ? "" : element.toString();//$NON-NLS-1$
            String prefix = ""; //$NON-NLS-1$
            if (result.equals(getActiveViewConfigurationName())) {
                prefix = "* "; //$NON-NLS-1$
            }
            Styler styler = null;
            if (result.length() == 0) {
                result = Messages
                        .getString("PersistenceDialog.defaultStateConfigName"); //$NON-NLS-1$
                styler = this.italicStyler;
            }

            StyledString styledString = new StyledString(prefix + result,
                    styler);
            cell.setText(styledString.toString());
            cell.setStyleRanges(styledString.getStyleRanges());

            super.update(cell);
        }
    }
}
