/*******************************************************************************
 * Copyright (c) 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.jface.viewers;

import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Item;

/**
 * Internal tree viewer implementation.
 * 
 * @since 3.1
 */
/* package */abstract class TreeEditorImpl {

    private CellEditor cellEditor;

    private CellEditor[] cellEditors;

    private ICellModifier cellModifier;

    private String[] columnProperties;

    private Item treeItem;

    private int columnNumber;

    private ICellEditorListener cellEditorListener;

    private FocusListener focusListener;

    private MouseListener mouseListener;

    private int doubleClickExpirationTime;

    private StructuredViewer viewer;

    TreeEditorImpl(StructuredViewer viewer) {
        this.viewer = viewer;
        initCellEditorListener();
    }

    /**
     * Returns this <code>TreeViewerImpl</code> viewer
     * 
     * @return the viewer
     */
    public StructuredViewer getViewer() {
        return viewer;
    }

    private void activateCellEditor() {
        if (cellEditors != null) {
            if (cellEditors[columnNumber] != null && cellModifier != null) {
                Object element = treeItem.getData();
                String property = columnProperties[columnNumber];
                if (cellModifier.canModify(element, property)) {
                    cellEditor = cellEditors[columnNumber];
                    //tree.showSelection();
                    cellEditor.addListener(cellEditorListener);
                    Object value = cellModifier.getValue(element, property);
                    cellEditor.setValue(value);
                    // Tricky flow of control here:
                    // activate() can trigger callback to cellEditorListener which will clear cellEditor
                    // so must get control first, but must still call activate() even if there is no control.
                    final Control control = cellEditor.getControl();
                    cellEditor.activate();
                    if (control == null)
                        return;
                    setLayoutData(cellEditor.getLayoutData());
                    setEditor(control, treeItem, columnNumber);
                    cellEditor.setFocus();
                    if (focusListener == null) {
                        focusListener = new FocusAdapter() {
                            public void focusLost(FocusEvent e) {
                                applyEditorValue();
                            }
                        };
                    }
                    control.addFocusListener(focusListener);
                    mouseListener = new MouseAdapter() {
                        public void mouseDown(MouseEvent e) {
                            // time wrap?	
                            // check for expiration of doubleClickTime
                            if (e.time <= doubleClickExpirationTime) {
                                control.removeMouseListener(mouseListener);
                                cancelEditing();
                                handleDoubleClickEvent();
                            } else if (mouseListener != null) {
                                control.removeMouseListener(mouseListener);
                            }
                        }
                    };
                    control.addMouseListener(mouseListener);
                }
            }
        }
    }

    /**
     * Activate a cell editor for the given mouse position.
     */
    private void activateCellEditor(MouseEvent event) {
        if (treeItem == null || treeItem.isDisposed()) {
            //item no longer exists
            return;
        }
        int columnToEdit;
        int columns = getColumnCount();
        if (columns == 0) {
            // If no TreeColumn, Tree acts as if it has a single column
            // which takes the whole width.
            columnToEdit = 0;
        } else {
            columnToEdit = -1;
            for (int i = 0; i < columns; i++) {
                Rectangle bounds = getBounds(treeItem, i);
                if (bounds.contains(event.x, event.y)) {
                    columnToEdit = i;
                    break;
                }
            }
            if (columnToEdit == -1) {
                return;
            }
        }

        columnNumber = columnToEdit;
        activateCellEditor();
    }

    /**
     * Deactivates the currently active cell editor.
     */
    public void applyEditorValue() {
        CellEditor c = this.cellEditor;
        if (c != null) {
            // null out cell editor before calling save
            // in case save results in applyEditorValue being re-entered
            // see 1GAHI8Z: ITPUI:ALL - How to code event notification when using cell editor ?
            this.cellEditor = null;
            Item t = this.treeItem;
            // don't null out tree item -- same item is still selected
            if (t != null && !t.isDisposed()) {
                saveEditorValue(c, t);
            }
            setEditor(null, null, 0);
            c.removeListener(cellEditorListener);
            Control control = c.getControl();
            if (control != null) {
                if (mouseListener != null) {
                    control.removeMouseListener(mouseListener);
                }
                if (focusListener != null) {
                    control.removeFocusListener(focusListener);
                }
            }
            c.deactivate();
        }
    }

    /**
     * Cancels the active cell editor, without saving the value 
     * back to the domain model.
     */
    public void cancelEditing() {
        if (cellEditor != null) {
            setEditor(null, null, 0);
            cellEditor.removeListener(cellEditorListener);
            CellEditor oldEditor = cellEditor;
            cellEditor = null;
            oldEditor.deactivate();
        }
    }

    /**
     * Start editing the given element. 
     * @param element
     * @param column
     */
    public void editElement(Object element, int column) {
        if (cellEditor != null)
            applyEditorValue();

        IStructuredSelection structuredSelection;
        if(element instanceof TreePath) {
        	structuredSelection = new TreeSelection((TreePath)element);
        } else {
        	structuredSelection = new StructuredSelection(element);
        }
        setSelection(structuredSelection, true);
        Item[] selection = getSelection();
        if (selection.length != 1)
            return;

        treeItem = selection[0];

        // Make sure selection is visible
        showSelection();
        columnNumber = column;
        activateCellEditor();

    }

    abstract Rectangle getBounds(Item item, int columnNumber);

    /**
     * Get the Cell Editors for the receiver.
     * @return CellEditor[]
     */
    public CellEditor[] getCellEditors() {
        return cellEditors;
    }

    /**
     * Get the cell modifier for the receiver.
     * @return ICellModifier
     */
    public ICellModifier getCellModifier() {
        return cellModifier;
    }

    abstract int getColumnCount();

    /**
     * Get the column properties for the receiver.
     * @return Object[]
     */
    public Object[] getColumnProperties() {
        return columnProperties;
    }

    abstract Item[] getSelection();

    /**
     * Handles the mouse down event; activates the cell editor.
     * @param event
     */
    public void handleMouseDown(MouseEvent event) {
        if (event.button != 1)
            return;

        if (cellEditor != null)
            applyEditorValue();

        // activate the cell editor immediately.  If a second mouseDown
        // is received prior to the expiration of the doubleClick time then
        // the cell editor will be deactivated and a doubleClick event will
        // be processed.
        //
        doubleClickExpirationTime = event.time
                + Display.getCurrent().getDoubleClickTime();

        Item[] items = getSelection();
        // Do not edit if more than one row is selected.
        if (items.length != 1) {
            treeItem = null;
            return;
        }
        treeItem = items[0];
        activateCellEditor(event);
    }

    private void initCellEditorListener() {
        cellEditorListener = new ICellEditorListener() {
            public void editorValueChanged(boolean oldValidState,
                    boolean newValidState) {
                // Ignore.
            }

            public void cancelEditor() {
                TreeEditorImpl.this.cancelEditing();
            }

            public void applyEditorValue() {
                TreeEditorImpl.this.applyEditorValue();
            }
        };
    }

    /**
     * Return whether or not there is an active cell editor.
     * @return boolean <code>true</code> if there is an active cell editor; otherwise
     * <code>false</code> is returned.
     */
    public boolean isCellEditorActive() {
        return cellEditor != null;
    }

    /**
     * Saves the value of the currently active cell editor,
     * by delegating to the cell modifier.
     */
    private void saveEditorValue(CellEditor cellEditor, Item treeItem) {
        if (cellModifier != null) {
            String property = null;
            if (columnProperties != null
                    && columnNumber < columnProperties.length)
                property = columnProperties[columnNumber];
            cellModifier.modify(treeItem, property, cellEditor.getValue());
        }
    }

    /**
     * Set the cell editors for the receiver.
     * @param editors
     */
    public void setCellEditors(CellEditor[] editors) {
        this.cellEditors = editors;
    }

    /**
     * Set the cell modifier for the receiver.
     * @param modifier
     */
    public void setCellModifier(ICellModifier modifier) {
        this.cellModifier = modifier;
    }

    /**
     * Set the column properties for the receiver.
     * @param columnProperties
     */
    public void setColumnProperties(String[] columnProperties) {
        this.columnProperties = columnProperties;
    }

    abstract void setEditor(Control w, Item item, int fColumnNumber);

    abstract void setLayoutData(CellEditor.LayoutData layoutData);

    abstract void setSelection(IStructuredSelection selection, boolean b);

    abstract void showSelection();

    abstract void handleDoubleClickEvent();
}
