/*******************************************************************************
 * Copyright (c) 2005, 2009 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 java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.ibm.icu.text.BreakIterator;

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.core.commands.Command;
import org.eclipse.core.commands.CommandManager;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.commands.contexts.ContextManager;

import org.eclipse.jface.bindings.BindingManager;
import org.eclipse.jface.bindings.Scheme;
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.jface.util.Util;

import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
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
				|| Util.isMac();

		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() {
					@Override
					public void keyReleased(KeyEvent e) {
						selectionChanged();
					}
				});
				fText.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseUp(MouseEvent e) {
						selectionChanged();
					}
				});
			}
		}

		@Override
		public Control getControl() {
			return fText;
		}

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

		@Override
		public void setText(String text) {
			fText.setText(text);
		}

		@Override
		public Point getSelection() {
			return fText.getSelection();
		}

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

		@Override
		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;
		}

		@Override
		public Control getControl() {
			return fStyledText;
		}

		@Override
		public String getText() {
			return fStyledText.getText();
		}

		@Override
		public void setText(String text) {
			fStyledText.setText(text);
		}

		@Override
		public Point getSelection() {
			return fStyledText.getSelection();
		}

		@Override
		public int getCaretPosition() {
			return fStyledText.getCaretOffset();
		}

		@Override
		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() {
				@Override
				public void keyReleased(KeyEvent e) {
					selectionChanged();
				}
			});
			fCombo.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseUp(MouseEvent e) {
					selectionChanged();
				}
			});
		}

		@Override
		public Control getControl() {
			return fCombo;
		}

		@Override
		public String getText() {
			return fCombo.getText();
		}

		@Override
		public void setText(String text) {
			fCombo.setText(text);
		}

		@Override
		public Point getSelection() {
			return fCombo.getSelection();
		}

		@Override
		public int getCaretPosition() {
			selectionChanged();
			return fCaretPosition;
//			return fCombo.getCaretPosition(); // not available: bug 103630
		}

		@Override
		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 final boolean IS_WORKAROUND= (fNavigable instanceof ComboNavigable)
							|| (fNavigable instanceof TextNavigable && TextNavigable.BUG_106024_TEXT_SELECTION);
					private List<Submission> fSubmissions;

					@Override
					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<Submission> iter= getSubmissions().iterator(); iter.hasNext();) {
							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<Submission>();

						ICommandService commandService= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class);
						IBindingService bindingService= (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class);
						if (commandService == null || bindingService == null)
							return fSubmissions;

						// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=184502 ,
						// similar to CodeAssistAdvancedConfigurationBlock.getKeyboardShortcut(..):
						BindingManager localBindingManager= new BindingManager(new ContextManager(), new CommandManager());
						final Scheme[] definedSchemes= bindingService.getDefinedSchemes();
						if (definedSchemes != null) {
							try {
								for (int i = 0; i < definedSchemes.length; i++) {
									Scheme scheme= definedSchemes[i];
									Scheme localSchemeCopy= localBindingManager.getScheme(scheme.getId());
									localSchemeCopy.define(scheme.getName(), scheme.getDescription(), scheme.getParentId());
								}
							} catch (final NotDefinedException e) {
								JavaPlugin.log(e);
							}
						}
						localBindingManager.setLocale(bindingService.getLocale());
						localBindingManager.setPlatform(bindingService.getPlatform());

						localBindingManager.setBindings(bindingService.getBindings());
						try {
							Scheme activeScheme= bindingService.getActiveScheme();
							if (activeScheme != null)
								localBindingManager.setActiveScheme(activeScheme);
						} catch (NotDefinedException e) {
							JavaPlugin.log(e);
						}

						fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.SELECT_WORD_NEXT)) {
							@Override
							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(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS)) {
							@Override
							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(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.WORD_NEXT)) {
							@Override
							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(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.WORD_PREVIOUS)) {
							@Override
							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(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.DELETE_NEXT_WORD)) {
							@Override
							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(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD)) {
							@Override
							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);
							}
						});

						return fSubmissions;
					}

					private TriggerSequence[] getKeyBindings(BindingManager localBindingManager, ICommandService commandService, String commandID) {
						Command command= commandService.getCommand(commandID);
						ParameterizedCommand pCmd= new ParameterizedCommand(command, null);
						return localBindingManager.getActiveBindingsDisregardingContextFor(pCmd);
					}

				};
			}
			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();
	}

}
