/*******************************************************************************
 * 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 com.ibm.icu.text.BreakIterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;

import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.bindings.keys.SWTKeySupport;
import org.eclipse.jface.preference.IPreferenceStore;

import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.keys.IBindingService;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;

import org.eclipse.jdt.ui.PreferenceConstants;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.text.JavaWordIterator;

/**
 * Support for camelCase-aware sub-word navigation in dialog fields.
 */
public class TextFieldNavigationHandler {
	
	public static void install(Text text) {
		if (isSubWordNavigationEnabled())
			new FocusHandler(new TextNavigable(text));
	}

	public static void install(StyledText styledText) {
		if (isSubWordNavigationEnabled())
			new FocusHandler(new StyledTextNavigable(styledText));
	}
	
	public static void install(Combo combo) {
		if (isSubWordNavigationEnabled())
			new FocusHandler(new ComboNavigable(combo));
	}
	
	private static boolean isSubWordNavigationEnabled() {
		IPreferenceStore preferenceStore= JavaPlugin.getDefault().getCombinedPreferenceStore();
		return preferenceStore.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION);
	}
	
	private abstract static class WorkaroundNavigable extends Navigable {
		/* workarounds for:
		 * - bug 103630: Add API: Combo#getCaretPosition()
		 * - bug 106024: Text#setSelection(int, int) does not handle start > end with SWT.SINGLE
		 */ 
		Point fLastSelection;
		int fCaretPosition;
		
		void selectionChanged() {
			Point selection= getSelection();
			if (selection.equals(fLastSelection)) {
				// leave caret position
			} else if (selection.x == selection.y) { //empty range
				fCaretPosition= selection.x;
			} else if (fLastSelection.y == selection.y) {
				fCaretPosition= selection.x; //same end -> assume caret at start
			} else {
				fCaretPosition= selection.y;
			}
			fLastSelection= selection;
		}
	}
	
	private abstract static class Navigable {
		public abstract Control getControl();
		
		public abstract String getText();

		public abstract void setText(String text);
		
		public abstract Point getSelection();

		public abstract void setSelection(int start, int end);
		
		public abstract int getCaretPosition();
	}
	
	private static class TextNavigable extends WorkaroundNavigable {
		static final boolean BUG_106024_TEXT_SELECTION=
				"win32".equals(SWT.getPlatform()) //$NON-NLS-1$
				// on carbon, getCaretPosition() always returns getSelection().x
				|| "carbon".equals(SWT.getPlatform()); //$NON-NLS-1$
		
		private final Text fText;
		
		public TextNavigable(Text text) {
			fText= text;
			// workaround for bug 106024:
			if (BUG_106024_TEXT_SELECTION) {
				fLastSelection= getSelection();
				fCaretPosition= fLastSelection.y;
				fText.addKeyListener(new KeyAdapter() {
					public void keyReleased(KeyEvent e) {
						selectionChanged();
					}
				});
				fText.addMouseListener(new MouseAdapter() {
					public void mouseUp(MouseEvent e) {
						selectionChanged();
					}
				});
			}
		}
		
		public Control getControl() {
			return fText;
		}

		public String getText() {
			return fText.getText();
		}

		public void setText(String text) {
			fText.setText(text);
		}
		
		public Point getSelection() {
			return fText.getSelection();
		}

		public int getCaretPosition() {
			if (BUG_106024_TEXT_SELECTION) {
				selectionChanged();
				return fCaretPosition;
			} else {
				return fText.getCaretPosition();
			}
		}

		public void setSelection(int start, int end) {
			fText.setSelection(start, end);
		}
	}
	
	private static class StyledTextNavigable extends Navigable {
		private final StyledText fStyledText;
		
		public StyledTextNavigable(StyledText styledText) {
			fStyledText= styledText;
		}
		
		public Control getControl() {
			return fStyledText;
		}
		
		public String getText() {
			return fStyledText.getText();
		}
		
		public void setText(String text) {
			fStyledText.setText(text);
		}
		
		public Point getSelection() {
			return fStyledText.getSelection();
		}
		
		public int getCaretPosition() {
			return fStyledText.getCaretOffset();
		}
		
		public void setSelection(int start, int end) {
			fStyledText.setSelection(start, end);
		}
	}
	
	private static class ComboNavigable extends WorkaroundNavigable {
		private final Combo fCombo;
		
		public ComboNavigable(Combo combo) {
			fCombo= combo;
			// workaround for bug 103630:
			fLastSelection= getSelection();
			fCaretPosition= fLastSelection.y;
			fCombo.addKeyListener(new KeyAdapter() {
				public void keyReleased(KeyEvent e) {
					selectionChanged();
				}
			});
			fCombo.addMouseListener(new MouseAdapter() {
				public void mouseUp(MouseEvent e) {
					selectionChanged();
				}
			});
		}
		
		public Control getControl() {
			return fCombo;
		}

		public String getText() {
			return fCombo.getText();
		}
		
		public void setText(String text) {
			fCombo.setText(text);
		}
		
		public Point getSelection() {
			return fCombo.getSelection();
		}
		
		public int getCaretPosition() {
			selectionChanged();
			return fCaretPosition;
//			return fCombo.getCaretPosition(); // not available: bug 103630
		}
		
		public void setSelection(int start, int end) {
			fCombo.setSelection(new Point(start, end));
		}
	}
	
	private static class FocusHandler implements FocusListener {
		
		private static final String EMPTY_TEXT= ""; //$NON-NLS-1$
		
		private final JavaWordIterator fIterator;
		private final Navigable fNavigable;
		private KeyAdapter fKeyListener;
		
		private FocusHandler(Navigable navigable) {
			fIterator= new JavaWordIterator();
			fNavigable= navigable;
			
			Control control= navigable.getControl();
			control.addFocusListener(this);
			if (control.isFocusControl())
				activate();
			control.addDisposeListener(new DisposeListener() {
				public void widgetDisposed(DisposeEvent e) {
					deactivate();
				}
			});
		}

		public void focusGained(FocusEvent e) {
			activate();
		}

		public void focusLost(FocusEvent e) {
			deactivate();
		}

		private void activate() {
			fNavigable.getControl().addKeyListener(getKeyListener());
		}
		
		private void deactivate() {
			if (fKeyListener != null) {
				Control control= fNavigable.getControl();
				if (! control.isDisposed())
					control.removeKeyListener(fKeyListener);
				fKeyListener= null;
			}
		}
		
		private KeyAdapter getKeyListener() {
			if (fKeyListener == null) {
				fKeyListener= new KeyAdapter() {
					private static final String TEXT_EDITOR_CONTEXT_ID= "org.eclipse.ui.textEditorScope"; //$NON-NLS-1$
					private final boolean IS_WORKAROUND= (fNavigable instanceof ComboNavigable)
							|| (fNavigable instanceof TextNavigable && TextNavigable.BUG_106024_TEXT_SELECTION);
					private List/*<Submission>*/ fSubmissions;

					public void keyPressed(KeyEvent e) {
						if (IS_WORKAROUND) {
							if (e.keyCode == SWT.ARROW_LEFT && e.stateMask == SWT.MOD2) {
								int caretPosition= fNavigable.getCaretPosition();
								if (caretPosition != 0) {
									Point selection= fNavigable.getSelection();
									if (caretPosition == selection.x)
										fNavigable.setSelection(selection.y, caretPosition - 1);
									else
										fNavigable.setSelection(selection.x, caretPosition - 1);
								}
								e.doit= false;
								return;
								
							} else if (e.keyCode == SWT.ARROW_RIGHT && e.stateMask == SWT.MOD2) {
								String text= fNavigable.getText();
								int caretPosition= fNavigable.getCaretPosition();
								if (caretPosition != text.length()) {
									Point selection= fNavigable.getSelection();
									if (caretPosition == selection.y)
										fNavigable.setSelection(selection.x, caretPosition + 1);
									else
										fNavigable.setSelection(selection.y, caretPosition + 1);
								}
								e.doit= false;
								return;
							}
						}
						int accelerator = SWTKeySupport.convertEventToUnmodifiedAccelerator(e);
						KeySequence keySequence = KeySequence.getInstance(SWTKeySupport.convertAcceleratorToKeyStroke(accelerator));
						getSubmissions();
						for (Iterator iter= getSubmissions().iterator(); iter.hasNext();) {
							Submission submission= (Submission) iter.next();
							TriggerSequence[] triggerSequences= submission.getTriggerSequences();
							for (int i= 0; i < triggerSequences.length; i++) {
								if (triggerSequences[i].equals(keySequence)) { // XXX does not work for multi-stroke bindings
									e.doit= false;
									submission.execute();
									return;
								}
							}
						}
					}
					
					private List/*<Submission>*/ getSubmissions() {
						if (fSubmissions != null)
							return fSubmissions;
						
						fSubmissions= new ArrayList();
						
						IContextService contextService= (IContextService) PlatformUI.getWorkbench().getAdapter(IContextService.class);
						ICommandService commandService= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class);
						IHandlerService handlerService= (IHandlerService) PlatformUI.getWorkbench().getAdapter(IHandlerService.class);
						IBindingService bindingService= (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class);
						if (contextService == null || commandService == null || handlerService == null || bindingService == null)
							return fSubmissions;
						
						IContextActivation[] contextActivations;
						contextActivations= new IContextActivation[] {
								contextService.activateContext(IContextService.CONTEXT_ID_WINDOW), // XXX relying on workbench feature https://bugs.eclipse.org/bugs/show_bug.cgi?id=115460#c11
								contextService.activateContext(TEXT_EDITOR_CONTEXT_ID)
						};
						
						fSubmissions.add(new Submission(bindingService.getActiveBindingsFor(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT)) {
							public void execute() {
								fIterator.setText(fNavigable.getText());
								int caretPosition= fNavigable.getCaretPosition();
								int newCaret= fIterator.following(caretPosition);
								if (newCaret != BreakIterator.DONE) {
									Point selection= fNavigable.getSelection();
									if (caretPosition == selection.y)
										fNavigable.setSelection(selection.x, newCaret);
									else
										fNavigable.setSelection(selection.y, newCaret);
								}
								fIterator.setText(EMPTY_TEXT);
							}
						});
						fSubmissions.add(new Submission(bindingService.getActiveBindingsFor(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS)) {
							public void execute() {
								fIterator.setText(fNavigable.getText());
								int caretPosition= fNavigable.getCaretPosition();
								int newCaret= fIterator.preceding(caretPosition);
								if (newCaret != BreakIterator.DONE) {
									Point selection= fNavigable.getSelection();
									if (caretPosition == selection.x)
										fNavigable.setSelection(selection.y, newCaret);
									else
										fNavigable.setSelection(selection.x, newCaret);
								}
								fIterator.setText(EMPTY_TEXT);
							}
						});
						fSubmissions.add(new Submission(bindingService.getActiveBindingsFor(ITextEditorActionDefinitionIds.WORD_NEXT)) {
							public void execute() {
								fIterator.setText(fNavigable.getText());
								int caretPosition= fNavigable.getCaretPosition();
								int newCaret= fIterator.following(caretPosition);
								if (newCaret != BreakIterator.DONE)
									fNavigable.setSelection(newCaret, newCaret);
								fIterator.setText(EMPTY_TEXT);
							}
						});
						fSubmissions.add(new Submission(bindingService.getActiveBindingsFor(ITextEditorActionDefinitionIds.WORD_PREVIOUS)) {
							public void execute() {
								fIterator.setText(fNavigable.getText());
								int caretPosition= fNavigable.getCaretPosition();
								int newCaret= fIterator.preceding(caretPosition);
								if (newCaret != BreakIterator.DONE)
									fNavigable.setSelection(newCaret, newCaret);
								fIterator.setText(EMPTY_TEXT);
							}
						});
						fSubmissions.add(new Submission(bindingService.getActiveBindingsFor(ITextEditorActionDefinitionIds.DELETE_NEXT_WORD)) {
							public void execute() {
								Point selection= fNavigable.getSelection();
								String text= fNavigable.getText();
								int start;
								int end;
								if (selection.x != selection.y) {
									start= selection.x;
									end= selection.y;
								} else {
									fIterator.setText(text);
									start= fNavigable.getCaretPosition();
									end= fIterator.following(start);
									fIterator.setText(EMPTY_TEXT);
									if (end == BreakIterator.DONE)
										return;
								}
								fNavigable.setText(text.substring(0, start) + text.substring(end));
								fNavigable.setSelection(start, start);
							}
						});
						fSubmissions.add(new Submission(bindingService.getActiveBindingsFor(ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD)) {
							public void execute() {
								Point selection= fNavigable.getSelection();
								String text= fNavigable.getText();
								int start;
								int end;
								if (selection.x != selection.y) {
									start= selection.x;
									end= selection.y;
								} else {
									fIterator.setText(text);
									end= fNavigable.getCaretPosition();
									start= fIterator.preceding(end);
									fIterator.setText(EMPTY_TEXT);
									if (start == BreakIterator.DONE)
										return;
								}
								fNavigable.setText(text.substring(0, start) + text.substring(end));
								fNavigable.setSelection(start, start);
							}
						});
						
						for (int i= 0; i < contextActivations.length; i++) {
							contextService.deactivateContext(contextActivations[i]);
						}
						
						return fSubmissions;
					}
					
				};
			}
			return fKeyListener;
		}
	}
	
	private abstract static class Submission {
		private TriggerSequence[] fTriggerSequences;
		
		public Submission(TriggerSequence[] triggerSequences) {
			fTriggerSequences= triggerSequences;
		}
		
		public TriggerSequence[] getTriggerSequences() {
			return fTriggerSequences;
		}
		
		public abstract void execute();
	}
	
}
