/*******************************************************************************
 * Copyright (c) 2005, 2006 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.jdt.internal.ui.dialogs;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
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.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;

import org.eclipse.jface.contentassist.SubjectControlContentAssistant;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;

import org.eclipse.jdt.internal.corext.util.Messages;

/**
 * <code>TableTextCellEditor</code> is a copy of TextCellEditor, with the
 * following changes:
 * 
 * <ul>
 * <li> modify events are sent out as the text is changed, and not only after
 * editing is done </li>
 * 
 * <li>a content assistant is supported</li>
 * 
 * <li>the <code>Control</code> from <code>getControl(Composite)</code>
 * does not notify registered FocusListeners. This is a workaround for bug
 * 58777. </li>
 * 
 * <li>the user can go to the next/previous row with up and down keys</li>
 * </ul>
 */
public class TableTextCellEditor extends CellEditor {
	public interface IActivationListener {
		public void activate();
	}
	
	private final TableViewer fTableViewer;
	private final int fColumn;
	private final String fProperty;
	/**
	 * The editor's value on activation. This value is reset to the
	 * cell when the editor is left via ESC key.
	 */
	String fOriginalValue;
	SubjectControlContentAssistant fContentAssistant;
	private IActivationListener fActivationListener;
	
    protected Text text;

    private boolean isSelection = false;
    private boolean isDeleteable = false;
    private boolean isSelectable = false;

    private static final int defaultStyle = SWT.SINGLE;
	private ModifyListener fModifyListener;
	
	public TableTextCellEditor(TableViewer tableViewer, int column) {
		super(tableViewer.getTable(), defaultStyle);
		fTableViewer= tableViewer;
		fColumn= column;
		fProperty= (String) tableViewer.getColumnProperties()[column];
	}
	
	public void activate() {
		super.activate();
		if (fActivationListener != null)
			fActivationListener.activate();
		fOriginalValue= text.getText();
	}
	
	private void fireModifyEvent(Object newValue) {
		fTableViewer.getCellModifier().modify(
				((IStructuredSelection) fTableViewer.getSelection()).getFirstElement(),
				fProperty, newValue);
	}
	
	protected void focusLost() {
		if (fContentAssistant != null && fContentAssistant.hasProposalPopupFocus()) {
			// skip focus lost if it went to the content assist popup
		} else {
			super.focusLost();
		}
	}
	
	public void setContentAssistant(SubjectControlContentAssistant assistant) {
		fContentAssistant= assistant;
	}
	
	public void setActivationListener(IActivationListener listener) {
		fActivationListener= listener;
	}
	
	public Text getText() {
		return text;
	}
	
    protected void checkDeleteable() {
        boolean oldIsDeleteable = isDeleteable;
        isDeleteable = isDeleteEnabled();
        if (oldIsDeleteable != isDeleteable) {
            fireEnablementChanged(DELETE);
        }
    }

    protected void checkSelectable() {
        boolean oldIsSelectable = isSelectable;
        isSelectable = isSelectAllEnabled();
        if (oldIsSelectable != isSelectable) {
            fireEnablementChanged(SELECT_ALL);
        }
    }

    protected void checkSelection() {
        boolean oldIsSelection = isSelection;
        isSelection = text.getSelectionCount() > 0;
        if (oldIsSelection != isSelection) {
            fireEnablementChanged(COPY);
            fireEnablementChanged(CUT);
        }
    }

	private ModifyListener getModifyListener() {
	    if (fModifyListener == null) {
	        fModifyListener = new ModifyListener() {
	            public void modifyText(ModifyEvent e) {
	                editOccured(e);
	            }
	        };
	    }
	    return fModifyListener;
	}

    /* (non-Javadoc)
     * Method declared on CellEditor.
     */
    protected Control createControl(Composite parent) {
		//workaround for bug 58777: don't accept focus listeners on the text control
		final Control[] textControl= new Control[1];
		Composite result= new Composite(parent, SWT.NONE) {
			public void addListener(int eventType, final Listener listener) {
				if (eventType != SWT.FocusIn && eventType != SWT.FocusOut) {
					textControl[0].addListener(eventType, listener);
				}
			}
		};
        result.setFont(parent.getFont());
        result.setBackground(parent.getBackground());
		result.setLayout(new FillLayout());
		
        text = new Text(result, getStyle());
		textControl[0]= text;
        text.addSelectionListener(new SelectionAdapter() {
            public void widgetDefaultSelected(SelectionEvent e) {
                handleDefaultSelection(e);
            }
        });
		text.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				// support switching rows while editing:
				if (e.stateMask == SWT.MOD1 || e.stateMask == SWT.MOD2) {
					if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN) {
					    // allow starting multi-selection even if in edit mode
						deactivate();
						e.doit= false;
						return;
					}
				}
				
				if (e.stateMask != SWT.NONE)
					return;
				
				switch (e.keyCode) {
				case SWT.ARROW_DOWN :
					e.doit= false;
					int nextRow= fTableViewer.getTable().getSelectionIndex() + 1;
					if (nextRow >= fTableViewer.getTable().getItemCount())
						break;
					editRow(nextRow);
					break;
					
				case SWT.ARROW_UP :
					e.doit= false;
					int prevRow= fTableViewer.getTable().getSelectionIndex() - 1;
					if (prevRow < 0)
						break;
					editRow(prevRow);
					break;
					
				case SWT.F2 :
					e.doit= false;
					deactivate();
					break;
				}
			}

			private void editRow(int row) {
				fTableViewer.getTable().setSelection(row);
				IStructuredSelection newSelection= (IStructuredSelection) fTableViewer.getSelection();
				if (newSelection.size() == 1)
					fTableViewer.editElement(newSelection.getFirstElement(), fColumn);
			}
		});
        text.addKeyListener(new KeyAdapter() {
            // hook key pressed - see PR 14201  
            public void keyPressed(KeyEvent e) {
                keyReleaseOccured(e);

                // as a result of processing the above call, clients may have
                // disposed this cell editor
                if ((getControl() == null) || getControl().isDisposed())
                    return;
                checkSelection(); // see explaination below
                checkDeleteable();
                checkSelectable();
            }
        });
        text.addTraverseListener(new TraverseListener() {
            public void keyTraversed(TraverseEvent e) {
                if (e.detail == SWT.TRAVERSE_ESCAPE
                        || e.detail == SWT.TRAVERSE_RETURN) {
                    e.doit = false;
                }
            }
        });
        // We really want a selection listener but it is not supported so we
        // use a key listener and a mouse listener to know when selection changes
        // may have occured
        text.addMouseListener(new MouseAdapter() {
            public void mouseUp(MouseEvent e) {
                checkSelection();
                checkDeleteable();
                checkSelectable();
            }
        });
        text.addFocusListener(new FocusAdapter() {
            public void focusLost(FocusEvent e) {
                TableTextCellEditor.this.focusLost();
            }
        });
        text.setFont(parent.getFont());
        text.setBackground(parent.getBackground());
        text.setText("");//$NON-NLS-1$
        text.addModifyListener(getModifyListener());
		
		return result;
    }

    protected void fireCancelEditor() {
		/* bug 58540: change signature refactoring interaction: validate as you type [refactoring] */
    	text.setText(fOriginalValue);
		super.fireApplyEditorValue();
    }
		
    /**
     * The <code>TextCellEditor</code> implementation of
     * this <code>CellEditor</code> framework method returns
     * the text string.
     *
     * @return the text string
     */
    protected Object doGetValue() {
        return text.getText();
    }

    protected void doSetFocus() {
        if (text != null) {
            text.selectAll();
            text.setFocus();
            checkSelection();
            checkDeleteable();
            checkSelectable();
        }
    }

    /**
     * The <code>TextCellEditor2</code> implementation of
     * this <code>CellEditor</code> framework method accepts
     * a text string (type <code>String</code>).
     *
     * @param value a text string (type <code>String</code>)
     */
    protected void doSetValue(Object value) {
        Assert.isTrue(text != null && (value instanceof String));
        text.removeModifyListener(getModifyListener());
        text.setText((String) value);
        text.addModifyListener(getModifyListener());
    }

    /**
     * Processes a modify event that occurred in this text cell editor.
     * This framework method performs validation and sets the error message
     * accordingly, and then reports a change via <code>fireEditorValueChanged</code>.
     * Subclasses should call this method at appropriate times. Subclasses
     * may extend or reimplement.
     *
     * @param e the SWT modify event
     */
    protected void editOccured(ModifyEvent e) {
        String value = text.getText();
        boolean oldValidState = isValueValid();
        boolean newValidState = isCorrect(value);
        if (!newValidState) {
            // try to insert the current value into the error message.
            setErrorMessage(Messages.format(getErrorMessage(),
                    new Object[] { value }));
        }
        valueChanged(oldValidState, newValidState);
		fireModifyEvent(text.getText()); // update model on-the-fly
    }

    public LayoutData getLayoutData() {
        return new LayoutData();
    }

    protected void handleDefaultSelection(SelectionEvent event) {
        // same with enter-key handling code in keyReleaseOccured(e);
        fireApplyEditorValue();
        deactivate();
    }

    public boolean isCopyEnabled() {
        if (text == null || text.isDisposed())
            return false;
        return text.getSelectionCount() > 0;
    }

    public boolean isCutEnabled() {
        if (text == null || text.isDisposed())
            return false;
        return text.getSelectionCount() > 0;
    }

    public boolean isDeleteEnabled() {
        if (text == null || text.isDisposed())
            return false;
        return text.getSelectionCount() > 0
                || text.getCaretPosition() < text.getCharCount();
    }

    public boolean isPasteEnabled() {
        if (text == null || text.isDisposed())
            return false;
        return true;
    }

    public boolean isSelectAllEnabled() {
        if (text == null || text.isDisposed())
            return false;
        return text.getCharCount() > 0;
    }

    protected void keyReleaseOccured(KeyEvent keyEvent) {
        if (keyEvent.character == '\r') { // Return key
            // Enter is handled in handleDefaultSelection.
            // Do not apply the editor value in response to an Enter key event
            // since this can be received from the IME when the intent is -not-
            // to apply the value.  
            // See bug 39074 [CellEditors] [DBCS] canna input mode fires bogus event from Text Control
            //
            // An exception is made for Ctrl+Enter for multi-line texts, since
            // a default selection event is not sent in this case. 
            if (text != null && !text.isDisposed()
                    && (text.getStyle() & SWT.MULTI) != 0) {
                if ((keyEvent.stateMask & SWT.CTRL) != 0) {
                    super.keyReleaseOccured(keyEvent);
                }
            }
            return;
        }
        super.keyReleaseOccured(keyEvent);
    }

    public void performCopy() {
        text.copy();
    }

    public void performCut() {
        text.cut();
        checkSelection();
        checkDeleteable();
        checkSelectable();
    }

    public void performDelete() {
        if (text.getSelectionCount() > 0)
            // remove the contents of the current selection
            text.insert(""); //$NON-NLS-1$
        else {
            // remove the next character
            int pos = text.getCaretPosition();
            if (pos < text.getCharCount()) {
                text.setSelection(pos, pos + 1);
                text.insert(""); //$NON-NLS-1$
            }
        }
        checkSelection();
        checkDeleteable();
        checkSelectable();
    }

    public void performPaste() {
        text.paste();
        checkSelection();
        checkDeleteable();
        checkSelectable();
    }

    public void performSelectAll() {
        text.selectAll();
        checkSelection();
        checkDeleteable();
    }

}
