/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.part;

import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;

/**
 * Handles the redirection of the global actions Cut, Copy, Paste,
 * Delete, Select All, Find, Undo and Redo to either the current
 * inline cell editor or the part's supplied action handler.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p><p>
 * Example usage:
 * <pre>
 * actionHandler = new CellEditorActionHandler(this.getViewSite().getActionBars());
 * actionHandler.addCellEditor(textCellEditor1);
 * actionHandler.addCellEditor(textCellEditor2);
 * actionHandler.setSelectAllAction(selectAllAction);
 * </pre>
 * </p>
 */
public class CellEditorActionHandler {
    private CutActionHandler cellCutAction = new CutActionHandler();

    private CopyActionHandler cellCopyAction = new CopyActionHandler();

    private PasteActionHandler cellPasteAction = new PasteActionHandler();

    private DeleteActionHandler cellDeleteAction = new DeleteActionHandler();

    private SelectAllActionHandler cellSelectAllAction = new SelectAllActionHandler();

    private FindActionHandler cellFindAction = new FindActionHandler();

    private UndoActionHandler cellUndoAction = new UndoActionHandler();

    private RedoActionHandler cellRedoAction = new RedoActionHandler();

    private IAction cutAction;

    private IAction copyAction;

    private IAction pasteAction;

    private IAction deleteAction;

    private IAction selectAllAction;

    private IAction findAction;

    private IAction undoAction;

    private IAction redoAction;

    private IPropertyChangeListener cutActionListener = new ActionEnabledChangeListener(
            cellCutAction);

    private IPropertyChangeListener copyActionListener = new ActionEnabledChangeListener(
            cellCopyAction);

    private IPropertyChangeListener pasteActionListener = new ActionEnabledChangeListener(
            cellPasteAction);

    private IPropertyChangeListener deleteActionListener = new ActionEnabledChangeListener(
            cellDeleteAction);

    private IPropertyChangeListener selectAllActionListener = new ActionEnabledChangeListener(
            cellSelectAllAction);

    private IPropertyChangeListener findActionListener = new ActionEnabledChangeListener(
            cellFindAction);

    private IPropertyChangeListener undoActionListener = new ActionEnabledChangeListener(
            cellRedoAction);

    private IPropertyChangeListener redoActionListener = new ActionEnabledChangeListener(
            cellUndoAction);

    private CellEditor activeEditor;

    private IPropertyChangeListener cellListener = new CellChangeListener();

    private Listener controlListener = new ControlListener();

    private HashMap controlToEditor = new HashMap();

    private class ControlListener implements Listener {
        public void handleEvent(Event event) {
            switch (event.type) {
            case SWT.Activate:
                activeEditor = (CellEditor) controlToEditor.get(event.widget);
                if (activeEditor != null) {
					activeEditor.addPropertyChangeListener(cellListener);
				}
                updateActionsEnableState();
                break;
            case SWT.Deactivate:
                if (activeEditor != null) {
					activeEditor.removePropertyChangeListener(cellListener);
				}
                activeEditor = null;
                updateActionsEnableState();
                break;
            default:
                break;
            }
        }
    }

    private class ActionEnabledChangeListener implements
            IPropertyChangeListener {
        private IAction actionHandler;

        protected ActionEnabledChangeListener(IAction actionHandler) {
            super();
            this.actionHandler = actionHandler;
        }

        public void propertyChange(PropertyChangeEvent event) {
            if (activeEditor != null) {
				return;
			}
            if (event.getProperty().equals(IAction.ENABLED)) {
                Boolean bool = (Boolean) event.getNewValue();
                actionHandler.setEnabled(bool.booleanValue());
                return;
            }
        }
    }

    private class CellChangeListener implements IPropertyChangeListener {
        public void propertyChange(PropertyChangeEvent event) {
            if (activeEditor == null) {
				return;
			}
            if (event.getProperty().equals(CellEditor.CUT)) {
                cellCutAction.setEnabled(activeEditor.isCutEnabled());
                return;
            }
            if (event.getProperty().equals(CellEditor.COPY)) {
                cellCopyAction.setEnabled(activeEditor.isCopyEnabled());
                return;
            }
            if (event.getProperty().equals(CellEditor.PASTE)) {
                cellPasteAction.setEnabled(activeEditor.isPasteEnabled());
                return;
            }
            if (event.getProperty().equals(CellEditor.DELETE)) {
                cellDeleteAction.setEnabled(activeEditor.isDeleteEnabled());
                return;
            }
            if (event.getProperty().equals(CellEditor.SELECT_ALL)) {
                cellSelectAllAction.setEnabled(activeEditor
                        .isSelectAllEnabled());
                return;
            }
            if (event.getProperty().equals(CellEditor.FIND)) {
                cellFindAction.setEnabled(activeEditor.isFindEnabled());
                return;
            }
            if (event.getProperty().equals(CellEditor.UNDO)) {
                cellUndoAction.setEnabled(activeEditor.isUndoEnabled());
                return;
            }
            if (event.getProperty().equals(CellEditor.REDO)) {
                cellRedoAction.setEnabled(activeEditor.isRedoEnabled());
                return;
            }
        }
    }

    private class CutActionHandler extends Action {
        protected CutActionHandler() {
            setId("CellEditorCutActionHandler");//$NON-NLS-1$
            setEnabled(false);
            PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IWorkbenchHelpContextIds.CELL_CUT_ACTION);
        }

        public void runWithEvent(Event event) {
            if (activeEditor != null) {
                activeEditor.performCut();
                return;
            }
            if (cutAction != null) {
                cutAction.runWithEvent(event);
                return;
            }
        }

        public void updateEnabledState() {
            if (activeEditor != null) {
                setEnabled(activeEditor.isCutEnabled());
                return;
            }
            if (cutAction != null) {
                setEnabled(cutAction.isEnabled());
                return;
            }
            setEnabled(false);
        }
    }

    private class CopyActionHandler extends Action {
        protected CopyActionHandler() {
            setId("CellEditorCopyActionHandler");//$NON-NLS-1$
            setEnabled(false);
            PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IWorkbenchHelpContextIds.CELL_COPY_ACTION);
        }

        public void runWithEvent(Event event) {
            if (activeEditor != null) {
                activeEditor.performCopy();
                return;
            }
            if (copyAction != null) {
                copyAction.runWithEvent(event);
                return;
            }
        }

        public void updateEnabledState() {
            if (activeEditor != null) {
                setEnabled(activeEditor.isCopyEnabled());
                return;
            }
            if (copyAction != null) {
                setEnabled(copyAction.isEnabled());
                return;
            }
            setEnabled(false);
        }
    }

    private class PasteActionHandler extends Action {
        protected PasteActionHandler() {
            setId("CellEditorPasteActionHandler");//$NON-NLS-1$
            setEnabled(false);
            PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IWorkbenchHelpContextIds.CELL_PASTE_ACTION);
        }

        public void runWithEvent(Event event) {
            if (activeEditor != null) {
                activeEditor.performPaste();
                return;
            }
            if (pasteAction != null) {
                pasteAction.runWithEvent(event);
                return;
            }
        }

        public void updateEnabledState() {
            if (activeEditor != null) {
                setEnabled(activeEditor.isPasteEnabled());
                return;
            }
            if (pasteAction != null) {
                setEnabled(pasteAction.isEnabled());
                return;
            }
            setEnabled(false);
        }
    }

    private class DeleteActionHandler extends Action {
        protected DeleteActionHandler() {
            setId("CellEditorDeleteActionHandler");//$NON-NLS-1$
            setEnabled(false);
            PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IWorkbenchHelpContextIds.CELL_DELETE_ACTION);
        }

        public void runWithEvent(Event event) {
            if (activeEditor != null) {
                activeEditor.performDelete();
                return;
            }
            if (deleteAction != null) {
                deleteAction.runWithEvent(event);
                return;
            }
        }

        public void updateEnabledState() {
            if (activeEditor != null) {
                setEnabled(activeEditor.isDeleteEnabled());
                return;
            }
            if (deleteAction != null) {
                setEnabled(deleteAction.isEnabled());
                return;
            }
            setEnabled(false);
        }
    }

    private class SelectAllActionHandler extends Action {
        protected SelectAllActionHandler() {
            setId("CellEditorSelectAllActionHandler");//$NON-NLS-1$
            setEnabled(false);
            PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IWorkbenchHelpContextIds.CELL_SELECT_ALL_ACTION);
        }

        public void runWithEvent(Event event) {
            if (activeEditor != null) {
                activeEditor.performSelectAll();
                return;
            }
            if (selectAllAction != null) {
                selectAllAction.runWithEvent(event);
                return;
            }
        }

        public void updateEnabledState() {
            if (activeEditor != null) {
                setEnabled(activeEditor.isSelectAllEnabled());
                return;
            }
            if (selectAllAction != null) {
                setEnabled(selectAllAction.isEnabled());
                return;
            }
            setEnabled(false);
        }
    }

    private class FindActionHandler extends Action {
        protected FindActionHandler() {
            setId("CellEditorFindActionHandler");//$NON-NLS-1$
            setEnabled(false);
            PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IWorkbenchHelpContextIds.CELL_FIND_ACTION);
        }

        public void runWithEvent(Event event) {
            if (activeEditor != null) {
                activeEditor.performFind();
                return;
            }
            if (findAction != null) {
                findAction.runWithEvent(event);
                return;
            }
        }

        public void updateEnabledState() {
            if (activeEditor != null) {
                setEnabled(activeEditor.isFindEnabled());
                return;
            }
            if (findAction != null) {
                setEnabled(findAction.isEnabled());
                return;
            }
            setEnabled(false);
        }
    }

    private class UndoActionHandler extends Action {
        protected UndoActionHandler() {
            setId("CellEditorUndoActionHandler");//$NON-NLS-1$
            setEnabled(false);
            PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IWorkbenchHelpContextIds.CELL_UNDO_ACTION);
        }

        public void runWithEvent(Event event) {
            if (activeEditor != null) {
                activeEditor.performUndo();
                return;
            }
            if (undoAction != null) {
                undoAction.runWithEvent(event);
                return;
            }
        }

        public void updateEnabledState() {
            if (activeEditor != null) {
                setEnabled(activeEditor.isUndoEnabled());
                return;
            }
            if (undoAction != null) {
                setEnabled(undoAction.isEnabled());
                return;
            }
            setEnabled(false);
        }
    }

    private class RedoActionHandler extends Action {
        protected RedoActionHandler() {
            setId("CellEditorRedoActionHandler");//$NON-NLS-1$
            setEnabled(false);
            PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IWorkbenchHelpContextIds.CELL_REDO_ACTION);
        }

        public void runWithEvent(Event event) {
            if (activeEditor != null) {
                activeEditor.performRedo();
                return;
            }
            if (redoAction != null) {
                redoAction.runWithEvent(event);
                return;
            }
        }

        public void updateEnabledState() {
            if (activeEditor != null) {
                setEnabled(activeEditor.isRedoEnabled());
                return;
            }
            if (redoAction != null) {
                setEnabled(redoAction.isEnabled());
                return;
            }
            setEnabled(false);
        }
    }

    /**
     * Creates a <code>CellEditor</code> action handler
     * for the global Cut, Copy, Paste, Delete, Select All,
     * Find, Undo, and Redo of the action bar.
     *
     * @param actionBar the action bar to register global
     *    action handlers.
     */
    public CellEditorActionHandler(IActionBars actionBar) {
        super();
        actionBar.setGlobalActionHandler(ActionFactory.CUT.getId(),
                cellCutAction);
        actionBar.setGlobalActionHandler(ActionFactory.COPY.getId(),
                cellCopyAction);
        actionBar.setGlobalActionHandler(ActionFactory.PASTE.getId(),
                cellPasteAction);
        actionBar.setGlobalActionHandler(ActionFactory.DELETE.getId(),
                cellDeleteAction);
        actionBar.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
                cellSelectAllAction);
        actionBar.setGlobalActionHandler(ActionFactory.FIND.getId(),
                cellFindAction);
        actionBar.setGlobalActionHandler(ActionFactory.UNDO.getId(),
                cellUndoAction);
        actionBar.setGlobalActionHandler(ActionFactory.REDO.getId(),
                cellRedoAction);
    }

    /**
     * Adds a <code>CellEditor</code> to the handler so that the
     * Cut, Copy, Paste, Delete, Select All, Find, Undo, and Redo
     * actions are redirected to it when active.
     *
     * @param editor the <code>CellEditor</code>
     */
    public void addCellEditor(CellEditor editor) {
        if (editor == null) {
			return;
		}

        Control control = editor.getControl();
        Assert.isNotNull(control);
        controlToEditor.put(control, editor);
        control.addListener(SWT.Activate, controlListener);
        control.addListener(SWT.Deactivate, controlListener);

        if (control.isFocusControl()) {
            activeEditor = editor;
            editor.addPropertyChangeListener(cellListener);
            updateActionsEnableState();
        }
    }

    /**
     * Disposes of this action handler
     */
    public void dispose() {
        setCutAction(null);
        setCopyAction(null);
        setPasteAction(null);
        setDeleteAction(null);
        setSelectAllAction(null);
        setFindAction(null);
        setUndoAction(null);
        setRedoAction(null);

        Iterator itr = controlToEditor.keySet().iterator();
        while (itr.hasNext()) {
            Control control = (Control) itr.next();
            if (!control.isDisposed()) {
                control.removeListener(SWT.Activate, controlListener);
                control.removeListener(SWT.Deactivate, controlListener);
            }
        }
        controlToEditor.clear();

        if (activeEditor != null) {
			activeEditor.removePropertyChangeListener(cellListener);
		}
        activeEditor = null;

    }

    /**
     * Removes a <code>CellEditor</code> from the handler
     * so that the Cut, Copy, Paste, Delete, Select All, Find
     * Undo, and Redo actions are no longer redirected to it.
     *
     * @param editor the <code>CellEditor</code>
     */
    public void removeCellEditor(CellEditor editor) {
        if (editor == null) {
			return;
		}

        if (activeEditor == editor) {
            activeEditor.removePropertyChangeListener(cellListener);
            activeEditor = null;
        }

        Control control = editor.getControl();
        if (control != null) {
            controlToEditor.remove(control);
            if (!control.isDisposed()) {
                control.removeListener(SWT.Activate, controlListener);
                control.removeListener(SWT.Deactivate, controlListener);
            }
        }
    }

    /**
     * Sets the default <code>IAction</code> handler for the Copy
     * action. This <code>IAction</code> is run only if no active
     * cell editor control.
     *
     * @param action the <code>IAction</code> to run for the
     *    Copy action, or <code>null</code> if not interested.
     */
    public void setCopyAction(IAction action) {
        if (copyAction == action) {
			return;
		}

        if (copyAction != null) {
			copyAction.removePropertyChangeListener(copyActionListener);
		}

        copyAction = action;

        if (copyAction != null) {
			copyAction.addPropertyChangeListener(copyActionListener);
		}

        cellCopyAction.updateEnabledState();
    }

    /**
     * Sets the default <code>IAction</code> handler for the Cut
     * action. This <code>IAction</code> is run only if no active
     * cell editor control.
     *
     * @param action the <code>IAction</code> to run for the
     *    Cut action, or <code>null</code> if not interested.
     */
    public void setCutAction(IAction action) {
        if (cutAction == action) {
			return;
		}

        if (cutAction != null) {
			cutAction.removePropertyChangeListener(cutActionListener);
		}

        cutAction = action;

        if (cutAction != null) {
			cutAction.addPropertyChangeListener(cutActionListener);
		}

        cellCutAction.updateEnabledState();
    }

    /**
     * Sets the default <code>IAction</code> handler for the Delete
     * action. This <code>IAction</code> is run only if no active
     * cell editor control.
     *
     * @param action the <code>IAction</code> to run for the
     *    Delete action, or <code>null</code> if not interested.
     */
    public void setDeleteAction(IAction action) {
        if (deleteAction == action) {
			return;
		}

        if (deleteAction != null) {
			deleteAction.removePropertyChangeListener(deleteActionListener);
		}

        deleteAction = action;

        if (deleteAction != null) {
			deleteAction.addPropertyChangeListener(deleteActionListener);
		}

        cellDeleteAction.updateEnabledState();
    }

    /**
     * Sets the default <code>IAction</code> handler for the Find
     * action. This <code>IAction</code> is run only if no active
     * cell editor control.
     *
     * @param action the <code>IAction</code> to run for the
     *    Find action, or <code>null</code> if not interested.
     */
    public void setFindAction(IAction action) {
        if (findAction == action) {
			return;
		}

        if (findAction != null) {
			findAction.removePropertyChangeListener(findActionListener);
		}

        findAction = action;

        if (findAction != null) {
			findAction.addPropertyChangeListener(findActionListener);
		}

        cellFindAction.updateEnabledState();
    }

    /**
     * Sets the default <code>IAction</code> handler for the Paste
     * action. This <code>IAction</code> is run only if no active
     * cell editor control.
     *
     * @param action the <code>IAction</code> to run for the
     *    Paste action, or <code>null</code> if not interested.
     */
    public void setPasteAction(IAction action) {
        if (pasteAction == action) {
			return;
		}

        if (pasteAction != null) {
			pasteAction.removePropertyChangeListener(pasteActionListener);
		}

        pasteAction = action;

        if (pasteAction != null) {
			pasteAction.addPropertyChangeListener(pasteActionListener);
		}

        cellPasteAction.updateEnabledState();
    }

    /**
     * Sets the default <code>IAction</code> handler for the Redo
     * action. This <code>IAction</code> is run only if no active
     * cell editor control.
     *
     * @param action the <code>IAction</code> to run for the
     *    Redo action, or <code>null</code> if not interested.
     */
    public void setRedoAction(IAction action) {
        if (redoAction == action) {
			return;
		}

        if (redoAction != null) {
			redoAction.removePropertyChangeListener(redoActionListener);
		}

        redoAction = action;

        if (redoAction != null) {
			redoAction.addPropertyChangeListener(redoActionListener);
		}

        cellRedoAction.updateEnabledState();
    }

    /**
     * Sets the default <code>IAction</code> handler for the Select All
     * action. This <code>IAction</code> is run only if no active
     * cell editor control.
     *
     * @param action the <code>IAction</code> to run for the
     *    Select All action, or <code>null</code> if not interested.
     */
    public void setSelectAllAction(IAction action) {
        if (selectAllAction == action) {
			return;
		}

        if (selectAllAction != null) {
			selectAllAction
                    .removePropertyChangeListener(selectAllActionListener);
		}

        selectAllAction = action;

        if (selectAllAction != null) {
			selectAllAction.addPropertyChangeListener(selectAllActionListener);
		}

        cellSelectAllAction.updateEnabledState();
    }

    /**
     * Sets the default <code>IAction</code> handler for the Undo
     * action. This <code>IAction</code> is run only if no active
     * cell editor control.
     *
     * @param action the <code>IAction</code> to run for the
     *    Undo action, or <code>null</code> if not interested.
     */
    public void setUndoAction(IAction action) {
        if (undoAction == action) {
			return;
		}

        if (undoAction != null) {
			undoAction.removePropertyChangeListener(undoActionListener);
		}

        undoAction = action;

        if (undoAction != null) {
			undoAction.addPropertyChangeListener(undoActionListener);
		}

        cellUndoAction.updateEnabledState();
    }

    /**
     * Updates the enable state of the Cut, Copy,
     * Paste, Delete, Select All, Find, Undo, and
     * Redo action handlers
     */
    private void updateActionsEnableState() {
        cellCutAction.updateEnabledState();
        cellCopyAction.updateEnabledState();
        cellPasteAction.updateEnabledState();
        cellDeleteAction.updateEnabledState();
        cellSelectAllAction.updateEnabledState();
        cellFindAction.updateEnabledState();
        cellUndoAction.updateEnabledState();
        cellRedoAction.updateEnabledState();
    }
}
