/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jface.viewers;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.ListenerList;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

/**
 * Abstract base class for cell editors. Implements property change listener handling,
 * and SWT window management.
 * <p>
 * Subclasses implement particular kinds of cell editors. This package contains various
 * specialized cell editors:
 * <ul>
 *   <li><code>TextCellEditor</code> - for simple text strings</li>
 *   <li><code>ColorCellEditor</code> - for colors</li>
 *   <li><code>ComboBoxCellEditor</code> - value selected from drop-down combo box</li>
 *   <li><code>CheckboxCellEditor</code> - boolean valued checkbox</li>
 *   <li><code>DialogCellEditor</code> - value from arbitrary dialog</li>
 * </ul>
 * </p>
 */
public abstract class CellEditor {

    /**
     * List of cell editor listeners (element type: <code>ICellEditorListener</code>).
     */
    private ListenerList listeners = new ListenerList(3);

    /**
     * List of cell editor property change listeners 
     * (element type: <code>IPropertyChangeListener</code>).
     */
    private ListenerList propertyChangeListeners = new ListenerList(3);

    /**
     * Indicates whether this cell editor's current value is valid.
     */
    private boolean valid = false;

    /**
     * Optional cell editor validator; <code>null</code> if none.
     */
    private ICellEditorValidator validator = null;

    /**
     * The error message string to display for invalid values;
     * <code>null</code> if none (that is, the value is valid).
     */
    private String errorMessage = null;

    /**
     * Indicates whether this cell editor has been changed recently.
     */
    private boolean dirty = false;

    /**
     * This cell editor's control, or <code>null</code>
     * if not created yet.
     */
    private Control control = null;

    /**
     * Default cell editor style
     */
    private static final int defaultStyle = SWT.NONE;

    /**
     * This cell editor's style
     */
    private int style = defaultStyle;

    /** 
     * Struct-like layout data for cell editors, with reasonable defaults
     * for all fields.
     */
    public static class LayoutData {
        /**
         * Horizontal alignment; <code>SWT.LEFT</code> by default.
         */
        public int horizontalAlignment = SWT.LEFT;

        /**
         * Indicates control grabs additional space; <code>true</code> by default.
         */
        public boolean grabHorizontal = true;

        /**
         * Minimum width in pixels; <code>50</code> pixels by default.
         */
        public int minimumWidth = 50;
    }

    /**
     * Property name for the copy action
     */
    public static final String COPY = "copy"; //$NON-NLS-1$

    /**
     * Property name for the cut action
     */
    public static final String CUT = "cut"; //$NON-NLS-1$

    /**
     * Property name for the delete action
     */
    public static final String DELETE = "delete"; //$NON-NLS-1$

    /**
     * Property name for the find action
     */
    public static final String FIND = "find"; //$NON-NLS-1$

    /**
     * Property name for the paste action
     */
    public static final String PASTE = "paste"; //$NON-NLS-1$

    /**
     * Property name for the redo action
     */
    public static final String REDO = "redo"; //$NON-NLS-1$

    /**
     * Property name for the select all action
     */
    public static final String SELECT_ALL = "selectall"; //$NON-NLS-1$

    /**
     * Property name for the undo action
     */
    public static final String UNDO = "undo"; //$NON-NLS-1$

    /**
     * Creates a new cell editor with no control 
     * The cell editor has no cell validator.
     * @since 2.1
     */
    protected CellEditor() {
    }

    /**
     * Creates a new cell editor under the given parent control.
     * The cell editor has no cell validator.
     *
     * @param parent the parent control
     */
    protected CellEditor(Composite parent) {
        this(parent, defaultStyle);
    }

    /**
     * Creates a new cell editor under the given parent control.
     * The cell editor has no cell validator.
     *
     * @param parent the parent control
     * @param style the style bits
     * @since 2.1
     */
    protected CellEditor(Composite parent, int style) {
        this.style = style;
        create(parent);
    }

    /**
     * Activates this cell editor.
     * <p>
     * The default implementation of this framework method
     * does nothing. Subclasses may reimplement.
     * </p>
     */
    public void activate() {
    }

    /**
     * Adds a listener to this cell editor.
     * Has no effect if an identical listener is already registered.
     *
     * @param listener a cell editor listener
     */
    public void addListener(ICellEditorListener listener) {
        listeners.add(listener);
    }

    /**
     * Adds a property change listener to this cell editor.
     * Has no effect if an identical property change listener 
     * is already registered.
     *
     * @param listener a property change listener
     */
    public void addPropertyChangeListener(IPropertyChangeListener listener) {
        propertyChangeListeners.add(listener);
    }

    /**
     * Creates the control for this cell editor under the given parent control.
     * <p>
     * This framework method must be implemented by concrete
     * subclasses.
     * </p>
     *
     * @param parent the parent control
     * @return the new control, or <code>null</code> if this cell editor has no control
     */
    protected abstract Control createControl(Composite parent);

    /**
     * Creates the control for this cell editor under the given parent control.
     * 
     * @param parent the parent control
     * @since 2.1
     */
    public void create(Composite parent) {
        Assert.isTrue(control == null);
        control = createControl(parent);
        // See 1GD5CA6: ITPUI:ALL - TaskView.setSelection does not work
        // Control is created with isVisible()==true by default.
        // This causes composite.setFocus() to work incorrectly.
        // The cell editor's control grabs focus instead, even if it is not active.
        // Make the control invisible here by default.
        deactivate();
    }

    /**
     * Hides this cell editor's control. Does nothing if this 
     * cell editor is not visible.
     */
    public void deactivate() {
        if (control != null && !control.isDisposed())
            control.setVisible(false);
    }

    /**
     * Disposes of this cell editor and frees any associated SWT resources.
     */
    public void dispose() {
        if (control != null && !control.isDisposed()) {
            control.dispose();
        }
        control = null;
    }

    /**
     * Returns this cell editor's value.
     * <p>
     * This framework method must be implemented by concrete subclasses.
     * </p>
     *
     * @return the value of this cell editor
     * @see #getValue
     */
    protected abstract Object doGetValue();

    /**
     * Sets the focus to the cell editor's control.
     * <p>
     * This framework method must be implemented by concrete subclasses.
     * </p>
     *
     * @see #setFocus
     */
    protected abstract void doSetFocus();

    /**
     * Sets this cell editor's value.
     * <p>
     * This framework method must be implemented by concrete subclasses.
     * </p>
     *
     * @param value the value of this cell editor
     * @see #setValue
     */
    protected abstract void doSetValue(Object value);

    /**
     * Notifies all registered cell editor listeners of an apply event.
     * Only listeners registered at the time this method is called are notified.
     *
     * @see ICellEditorListener#applyEditorValue
     */
    protected void fireApplyEditorValue() {
        Object[] array = listeners.getListeners();
        for (int i = 0; i < array.length; i++) {
            final ICellEditorListener l = (ICellEditorListener) array[i];
            Platform.run(new SafeRunnable() {
                public void run() {
                    l.applyEditorValue();
                }
            });
        }
    }

    /**
     * Notifies all registered cell editor listeners that editing has been
     * canceled.
     *
     * @see ICellEditorListener#cancelEditor
     */
    protected void fireCancelEditor() {
        Object[] array = listeners.getListeners();
        for (int i = 0; i < array.length; i++) {
            final ICellEditorListener l = (ICellEditorListener) array[i];
            Platform.run(new SafeRunnable() {
                public void run() {
                    l.cancelEditor();
                }
            });
        }
    }

    /**
     * Notifies all registered cell editor listeners of a value change.
     *
     * @param oldValidState the valid state before the end user changed the value
     * @param newValidState the current valid state
     * @see ICellEditorListener#editorValueChanged
     */
    protected void fireEditorValueChanged(final boolean oldValidState,
            final boolean newValidState) {
        Object[] array = listeners.getListeners();
        for (int i = 0; i < array.length; i++) {
            final ICellEditorListener l = (ICellEditorListener) array[i];
            Platform.run(new SafeRunnable() {
                public void run() {
                    l.editorValueChanged(oldValidState, newValidState);
                }
            });
        }
    }

    /**
     * Notifies all registered property listeners
     * of an enablement change.
     *
     * @param actionId the id indicating what action's enablement has changed.
     */
    protected void fireEnablementChanged(final String actionId) {
        Object[] array = propertyChangeListeners.getListeners();
        for (int i = 0; i < array.length; i++) {
            final IPropertyChangeListener l = (IPropertyChangeListener) array[i];
            Platform.run(new SafeRunnable() {
                public void run() {
                    l.propertyChange(new PropertyChangeEvent(this, actionId,
                            null, null));
                }
            });
        }
    }

    /**
     * Sets the style bits for this cell editor.
     * 
     * @param style the SWT style bits for this cell editor
     * @since 2.1
     */
    public void setStyle(int style) {
        this.style = style;
    }

    /**
     * Returns the style bits for this cell editor.
     *
     * @return the style for this cell editor
     * @since 2.1
     */
    public int getStyle() {
        return style;
    }

    /**
     * Returns the control used to implement this cell editor.
     *
     * @return the control, or <code>null</code> if this cell editor has no control
     */
    public Control getControl() {
        return control;
    }

    /**
     * Returns the current error message for this cell editor.
     * 
     * @return the error message if the cell editor is in an invalid state,
     *  and <code>null</code> if the cell editor is valid
     */
    public String getErrorMessage() {
        return errorMessage;
    }

    /**
     * Returns a layout data object for this cell editor.
     * This is called each time the cell editor is activated
     * and controls the layout of the SWT table editor.
     * <p>
     * The default implementation of this method sets the 
     * minimum width to the control's preferred width.
     * Subclasses may extend or reimplement.
     * </p>
     *
     * @return the layout data object 
     */
    public LayoutData getLayoutData() {
        LayoutData result = new LayoutData();
        Control control = getControl();
        if (control != null) {
            result.minimumWidth = control.computeSize(SWT.DEFAULT, SWT.DEFAULT,
                    true).x;
        }
        return result;
    }

    /**
     * Returns the input validator for this cell editor.
     *
     * @return the input validator, or <code>null</code> if none
     */
    public ICellEditorValidator getValidator() {
        return validator;
    }

    /**
     * Returns this cell editor's value provided that it has a valid one.
     *
     * @return the value of this cell editor, or <code>null</code>
     *   if the cell editor does not contain a valid value
     */
    public final Object getValue() {
        if (!valid)
            return null;

        return doGetValue();
    }

    /**
     * Returns whether this cell editor is activated.
     *
     * @return <code>true</code> if this cell editor's control is
     *   currently visible, and <code>false</code> if not visible
     */
    public boolean isActivated() {
        return control != null && control.isVisible();
    }

    /**
     * Returns <code>true</code> if this cell editor is
     * able to perform the copy action.
     * <p>
     * This default implementation always returns 
     * <code>false</code>.
     * </p>
     * <p>
     * Subclasses may override
     * </p>
     * @return <code>true</code> if copy is possible,
     *  <code>false</code> otherwise
     */
    public boolean isCopyEnabled() {
        return false;
    }

    /**
     * Returns whether the given value is valid for this cell editor.
     * This cell editor's validator (if any) makes the actual determination.
     *
     * @return <code>true</code> if the value is valid, and <code>false</code>
     *  if invalid
     */
    protected boolean isCorrect(Object value) {
        errorMessage = null;
        if (validator == null)
            return true;

        errorMessage = validator.isValid(value);
        return (errorMessage == null || errorMessage.equals(""));//$NON-NLS-1$
    }

    /**
     * Returns <code>true</code> if this cell editor is
     * able to perform the cut action.
     * <p>
     * This default implementation always returns 
     * <code>false</code>.
     * </p>
     * <p>
     * Subclasses may override
     * </p>
     * @return <code>true</code> if cut is possible,
     *  <code>false</code> otherwise
     */
    public boolean isCutEnabled() {
        return false;
    }

    /**
     * Returns <code>true</code> if this cell editor is
     * able to perform the delete action.
     * <p>
     * This default implementation always returns 
     * <code>false</code>.
     * </p>
     * <p>
     * Subclasses may override
     * </p>
     * @return <code>true</code> if delete is possible,
     *  <code>false</code> otherwise
     */
    public boolean isDeleteEnabled() {
        return false;
    }

    /**
     * Returns whether the value of this cell editor has changed since the
     * last call to <code>setValue</code>.
     *
     * @return <code>true</code> if the value has changed, and <code>false</code>
     *  if unchanged
     */
    public boolean isDirty() {
        return dirty;
    }

    /**
     * Marks this cell editor as dirty.
     * @since 2.1
     */
    protected void markDirty() {
        dirty = true;
    }

    /**
     * Returns <code>true</code> if this cell editor is
     * able to perform the find action.
     * <p>
     * This default implementation always returns 
     * <code>false</code>.
     * </p>
     * <p>
     * Subclasses may override
     * </p>
     * @return <code>true</code> if find is possible,
     *  <code>false</code> otherwise
     */
    public boolean isFindEnabled() {
        return false;
    }

    /**
     * Returns <code>true</code> if this cell editor is
     * able to perform the paste action.
     * <p>
     * This default implementation always returns 
     * <code>false</code>.
     * </p>
     * <p>
     * Subclasses may override
     * </p>
     * @return <code>true</code> if paste is possible,
     *  <code>false</code> otherwise
     */
    public boolean isPasteEnabled() {
        return false;
    }

    /**
     * Returns <code>true</code> if this cell editor is
     * able to perform the redo action.
     * <p>
     * This default implementation always returns 
     * <code>false</code>.
     * </p>
     * <p>
     * Subclasses may override
     * </p>
     * @return <code>true</code> if redo is possible,
     *  <code>false</code> otherwise
     */
    public boolean isRedoEnabled() {
        return false;
    }

    /**
     * Returns <code>true</code> if this cell editor is
     * able to perform the select all action.
     * <p>
     * This default implementation always returns 
     * <code>false</code>.
     * </p>
     * <p>
     * Subclasses may override
     * </p>
     * @return <code>true</code> if select all is possible,
     *  <code>false</code> otherwise
     */
    public boolean isSelectAllEnabled() {
        return false;
    }

    /**
     * Returns <code>true</code> if this cell editor is
     * able to perform the undo action.
     * <p>
     * This default implementation always returns 
     * <code>false</code>.
     * </p>
     * <p>
     * Subclasses may override
     * </p>
     * @return <code>true</code> if undo is possible,
     *  <code>false</code> otherwise
     */
    public boolean isUndoEnabled() {
        return false;
    }

    /**
     * Returns whether this cell editor has a valid value.
     * The default value is false.
     *
     * @return <code>true</code> if the value is valid, and <code>false</code>
     *  if invalid
     *
     * @see #setValueValid(boolean)
     */
    public boolean isValueValid() {
        return valid;
    }

    /**
     * Processes a key release event that occurred in this cell editor.
     * <p>
     * The default implementation of this framework method cancels editing
     * when the ESC key is pressed.  When the RETURN key is pressed the current
     * value is applied and the cell editor deactivates.
     * Subclasses should call this method at appropriate times. 
     * Subclasses may also extend or reimplement.
     * </p>
     *
     * @param keyEvent the key event
     */
    protected void keyReleaseOccured(KeyEvent keyEvent) {
        if (keyEvent.character == '\u001b') { // Escape character
            fireCancelEditor();
        } else if (keyEvent.character == '\r') { // Return key
            fireApplyEditorValue();
            deactivate();
        }
    }

    /**
     * Processes a focus lost event that occurred in this cell editor.
     * <p>
     * The default implementation of this framework method applies the current
     * value and deactivates the cell editor.
     * Subclasses should call this method at appropriate times. 
     * Subclasses may also extend or reimplement.
     * </p>
     */
    protected void focusLost() {
        if (isActivated()) {
            fireApplyEditorValue();
            deactivate();
        }
    }

    /**
     * Performs the copy action.
     * This default implementation does nothing.
     * <p>
     * Subclasses may override
     * </p>
     */
    public void performCopy() {
    }

    /**
     * Performs the cut action.
     * This default implementation does nothing.
     * <p>
     * Subclasses may override
     * </p>
     */
    public void performCut() {
    }

    /**
     * Performs the delete action.
     * This default implementation does nothing.
     * <p>
     * Subclasses may override
     * </p>
     */
    public void performDelete() {
    }

    /**
     * Performs the find action.
     * This default implementation does nothing.
     * <p>
     * Subclasses may override
     * </p>
     */
    public void performFind() {
    }

    /**
     * Performs the paste action.
     * This default implementation does nothing.
     * <p>
     * Subclasses may override
     * </p>
     */
    public void performPaste() {
    }

    /**
     * Performs the redo action.
     * This default implementation does nothing.
     * <p>
     * Subclasses may override
     * </p>
     */
    public void performRedo() {
    }

    /**
     * Performs the select all action.
     * This default implementation does nothing.
     * <p>
     * Subclasses may override
     * </p>
     */
    public void performSelectAll() {
    }

    /**
     * Performs the undo action.
     * This default implementation does nothing.
     * <p>
     * Subclasses may override
     * </p>
     */
    public void performUndo() {
    }

    /**
     * Removes the given listener from this cell editor.
     * Has no affect if an identical listener is not registered.
     *
     * @param listener a cell editor listener
     */
    public void removeListener(ICellEditorListener listener) {
        listeners.remove(listener);
    }

    /**
     * Removes the given property change listener from this cell editor.
     * Has no affect if an identical property change listener is not 
     * registered.
     *
     * @param listener a property change listener
     */
    public void removePropertyChangeListener(IPropertyChangeListener listener) {
        propertyChangeListeners.remove(listener);
    }

    /**
     * Sets or clears the current error message for this cell editor.
     * 
     * @param message the error message, or <code>null</code> to clear
     */
    protected void setErrorMessage(String message) {
        errorMessage = message;
    }

    /**
     * Sets the focus to the cell editor's control.
     */
    public void setFocus() {
        doSetFocus();
    }

    /**
     * Sets the input validator for this cell editor.
     *
     * @param validator the input validator, or <code>null</code> if none
     */
    public void setValidator(ICellEditorValidator validator) {
        this.validator = validator;
    }

    /**
     * Sets this cell editor's value.
     *
     * @param value the value of this cell editor
     */
    public final void setValue(Object value) {
        valid = isCorrect(value);
        dirty = false;
        doSetValue(value);
    }

    /**
     * Sets the valid state of this cell editor.
     * The default value is false.
     * Subclasses should call this method on construction.
     *
     * @param valid <code>true</code> if the current valie is valid,
     *  and <code>false</code> if invalid
     *
     * @see #isValueValid
     */
    protected void setValueValid(boolean valid) {
        this.valid = valid;
    }

    /**
     * The value has changed.  
     * Updates the valid state flag, marks this cell editor as dirty,
     * and notifies all registered cell editor listeners of a value change.
     *
     * @param oldValidState the valid state before the end user changed the value
     * @param newValidState the current valid state
     * @see ICellEditorListener#editorValueChanged
     */
    protected void valueChanged(boolean oldValidState, boolean newValidState) {
        valid = newValidState;
        dirty = true;
        fireEditorValueChanged(oldValidState, newValidState);
    }
}