/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.editors.text;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;

import org.eclipse.ui.internal.editors.text.OverlayPreferenceStore.OverlayKey;

import org.eclipse.ui.texteditor.spelling.IPreferenceStatusMonitor;
import org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock;
import org.eclipse.ui.texteditor.spelling.SpellingEngineDescriptor;
import org.eclipse.ui.texteditor.spelling.SpellingService;

import org.eclipse.ui.editors.text.EditorsUI;


/**
 * Configures spelling preferences.
 *
 * @since 3.1
 */
class SpellingConfigurationBlock implements IPreferenceConfigurationBlock {

	/**
	 * Error preferences block.
	 */
	private static class ErrorPreferences implements ISpellingPreferenceBlock {

		/** Error message */
		private String fMessage;

		/** Error label */
		private Label fLabel;

		/**
		 * Initialize with the given error message.
		 *
		 * @param message the error message
		 */
		protected ErrorPreferences(String message) {
			fMessage= message;
		}

		@Override
		public Control createControl(Composite composite) {
			Composite inner= new Composite(composite, SWT.NONE);
			inner.setLayout(new FillLayout(SWT.VERTICAL));

			fLabel= new Label(inner, SWT.CENTER);
			fLabel.setText(fMessage);

			return inner;
		}

		@Override
		public void initialize(IPreferenceStatusMonitor statusMonitor) {
		}

		@Override
		public boolean canPerformOk() {
			return true;
		}

		@Override
		public void performOk() {
		}

		@Override
		public void performDefaults() {
		}

		@Override
		public void performRevert() {
		}

		@Override
		public void dispose() {
		}

		@Override
		public void setEnabled(boolean enabled) {
			fLabel.setEnabled(enabled);
		}
	}

	/**
	 * Forwarding status monitor for accessing the current status.
	 */
	private static class ForwardingStatusMonitor implements IPreferenceStatusMonitor {

		/** Status monitor to which status changes are forwarded */
		private IPreferenceStatusMonitor fForwardedMonitor;

		/** Latest reported status */
		private IStatus fStatus;

		/**
		 * Initializes with the given status monitor to which status changes are forwarded.
		 *
		 * @param forwardedMonitor the status monitor to which changes are forwarded
		 */
		public ForwardingStatusMonitor(IPreferenceStatusMonitor forwardedMonitor) {
			fForwardedMonitor= forwardedMonitor;
		}

		@Override
		public void statusChanged(IStatus status) {
			fStatus= status;
			fForwardedMonitor.statusChanged(status);
		}

		/**
		 * Returns the latest reported status.
		 *
		 * @return the latest reported status, can be <code>null</code>
		 */
		public IStatus getStatus() {
			return fStatus;
		}
	}

	/** The overlay preference store. */
	private final OverlayPreferenceStore fStore;

	/* The controls */
	private Combo fProviderCombo;
	private Button fEnablementCheckbox;
	private ComboViewer fProviderViewer;
	private Composite fComboGroup;
	private Composite fGroup;
	private StackLayout fStackLayout;

	/* the model */
	private final Map<String, SpellingEngineDescriptor> fProviderDescriptors;
	private final Map<String, ISpellingPreferenceBlock> fProviderPreferences;
	private final Map<String, Control> fProviderControls;

	private ForwardingStatusMonitor fStatusMonitor;

	private ISpellingPreferenceBlock fCurrentBlock;


	public SpellingConfigurationBlock(OverlayPreferenceStore store, IPreferenceStatusMonitor statusMonitor) {
		Assert.isNotNull(store);
		fStore= store;
		fStore.addKeys(createOverlayStoreKeys());
		fStatusMonitor= new ForwardingStatusMonitor(statusMonitor);
		fProviderDescriptors= createListModel();
		fProviderPreferences= new HashMap<>();
		fProviderControls= new HashMap<>();
	}

	private Map<String, SpellingEngineDescriptor> createListModel() {
		SpellingEngineDescriptor[] descs= EditorsUI.getSpellingService().getSpellingEngineDescriptors();
		Map<String, SpellingEngineDescriptor> map= new HashMap<>();
		for (SpellingEngineDescriptor desc : descs) {
			map.put(desc.getId(), desc);
		}
		return map;
	}

	private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() {

		ArrayList<OverlayKey> overlayKeys= new ArrayList<>();

		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, SpellingService.PREFERENCE_SPELLING_ENABLED));
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, SpellingService.PREFERENCE_SPELLING_ENGINE));

		OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
		overlayKeys.toArray(keys);
		return keys;
	}

	/**
	 * Creates page for spelling preferences.
	 *
	 * @param parent the parent composite
	 * @return the control for the preference page
	 */
	@Override
	public Control createControl(Composite parent) {

		Composite composite= new Composite(parent, SWT.NULL);
		// assume parent page uses grid-data
		GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL);
		composite.setLayoutData(gd);
		GridLayout layout= new GridLayout();
		layout.numColumns= 2;
		layout.marginHeight= 0;
		layout.marginWidth= 0;

		PixelConverter pc= new PixelConverter(composite);
		layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2;
		composite.setLayout(layout);

		if (EditorsUI.getSpellingService().getSpellingEngineDescriptors().length == 0) {
			Label label= new Label(composite, SWT.NONE);
			label.setText(TextEditorMessages.SpellingConfigurationBlock_error_not_installed);
			return composite;
		}

		/* check box for new editors */
		fEnablementCheckbox= new Button(composite, SWT.CHECK);
		fEnablementCheckbox.setText(TextEditorMessages.SpellingConfigurationBlock_enable);
		gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
		fEnablementCheckbox.setLayoutData(gd);
		fEnablementCheckbox.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				boolean enabled= fEnablementCheckbox.getSelection();
				fStore.setValue(SpellingService.PREFERENCE_SPELLING_ENABLED, enabled);
				updateCheckboxDependencies();
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		Label label= new Label(composite, SWT.CENTER);
		gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
		label.setLayoutData(gd);

		if (fProviderDescriptors.size() > 1) {
			fComboGroup= new Composite(composite, SWT.NONE);
			gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
			gd.horizontalIndent= 10;
			fComboGroup.setLayoutData(gd);
			GridLayout gridLayout= new GridLayout(2, false);
			gridLayout.marginWidth= 0;
			fComboGroup.setLayout(gridLayout);

			Label comboLabel= new Label(fComboGroup, SWT.CENTER);
			gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER);
			comboLabel.setLayoutData(gd);
			comboLabel.setText(TextEditorMessages.SpellingConfigurationBlock_combo_caption);

			label= new Label(composite, SWT.CENTER);
			gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
			label.setLayoutData(gd);

			fProviderCombo= new Combo(fComboGroup, SWT.READ_ONLY | SWT.DROP_DOWN);
			gd= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER);
			fProviderCombo.setLayoutData(gd);

			fProviderViewer= createProviderViewer();
		}

		Composite groupComp= new Composite(composite, SWT.NONE);
		gd= new GridData(GridData.FILL_BOTH);
		gd.horizontalSpan= 2;
		groupComp.setLayoutData(gd);
		GridLayout gridLayout= new GridLayout(1, false);
		gridLayout.marginWidth= 0;
		groupComp.setLayout(gridLayout);

		/* contributed provider preferences. */
		fGroup= new Composite(groupComp, SWT.NONE);
		gd= new GridData(SWT.FILL, SWT.FILL, true, true);
		gd.horizontalIndent= 10;
		fGroup.setLayoutData(gd);
		fStackLayout= new StackLayout();
		fGroup.setLayout(fStackLayout);

		return composite;
	}

	@Override
	public void applyData(Object data) {
	}

	private ComboViewer createProviderViewer() {
		/* list viewer */
		final ComboViewer viewer= new ComboViewer(fProviderCombo);
		viewer.setContentProvider(new IStructuredContentProvider() {

			@Override
			public void dispose() {
			}

			@Override
			public void inputChanged(Viewer v, Object oldInput, Object newInput) {
			}

			@Override
			public Object[] getElements(Object inputElement) {
				return fProviderDescriptors.values().toArray();
			}
		});
		viewer.setLabelProvider(new LabelProvider() {
			@Override
			public Image getImage(Object element) {
				return null;
			}

			@Override
			public String getText(Object element) {
				return ((SpellingEngineDescriptor) element).getLabel();
			}
		});
		viewer.addSelectionChangedListener(new ISelectionChangedListener() {

			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				IStructuredSelection sel= event.getStructuredSelection();
				if (sel.isEmpty())
					return;
				if (fCurrentBlock != null && fStatusMonitor.getStatus() != null && fStatusMonitor.getStatus().matches(IStatus.ERROR))
					if (isPerformRevert()) {
						ISafeRunnable runnable= new ISafeRunnable() {
							@Override
							public void run() throws Exception {
								fCurrentBlock.performRevert();
							}
							@Override
							public void handleException(Throwable x) {
							}
						};
						SafeRunner.run(runnable);
					} else {
						revertSelection();
						return;
					}
				fStore.setValue(SpellingService.PREFERENCE_SPELLING_ENGINE, ((SpellingEngineDescriptor) sel.getFirstElement()).getId());
				updateListDependencies();
			}

			private boolean isPerformRevert() {
				Shell shell= viewer.getControl().getShell();
				MessageDialog dialog= new MessageDialog(shell, TextEditorMessages.SpellingConfigurationBlock_error_title, null, TextEditorMessages.SpellingConfigurationBlock_error_message, MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 1);
				return dialog.open() == 0;
			}

			private void revertSelection() {
				try {
					viewer.removeSelectionChangedListener(this);
					SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore);
					if (desc != null)
						viewer.setSelection(new StructuredSelection(desc), true);
				} finally {
					viewer.addSelectionChangedListener(this);
				}
			}
		});
		viewer.setInput(fProviderDescriptors);
		viewer.refresh();

		return viewer;
	}

	private void updateCheckboxDependencies() {
		final boolean enabled= fEnablementCheckbox.getSelection();
		if (fComboGroup != null)
			setEnabled(fComboGroup, enabled);
		SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore);
		String id= desc != null ? desc.getId() : ""; //$NON-NLS-1$
		final ISpellingPreferenceBlock preferenceBlock= fProviderPreferences.get(id);
		if (preferenceBlock != null) {
			ISafeRunnable runnable= new ISafeRunnable() {
				@Override
				public void run() throws Exception {
					preferenceBlock.setEnabled(enabled);
				}
				@Override
				public void handleException(Throwable x) {
				}
			};
			SafeRunner.run(runnable);
		}
	}

	private void setEnabled(Control control, boolean enabled) {
		if (control instanceof Composite) {
			Control[] children= ((Composite) control).getChildren();
			for (Control c : children) {
				setEnabled(c, enabled);
			}
		}
		control.setEnabled(enabled);
	}

	void updateListDependencies() {
		SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore);
		String id;
		if (desc == null) {
			// safety in case there is no such descriptor
			id= ""; //$NON-NLS-1$
			String message= TextEditorMessages.SpellingConfigurationBlock_error_not_exist;
			EditorsPlugin.log(new Status(IStatus.WARNING, EditorsUI.PLUGIN_ID, IStatus.OK, message, null));
			fCurrentBlock= new ErrorPreferences(message);
		} else {
			id= desc.getId();
			fCurrentBlock= fProviderPreferences.get(id);
			if (fCurrentBlock == null) {
				try {
					fCurrentBlock= desc.createPreferences();
					fProviderPreferences.put(id, fCurrentBlock);
				} catch (CoreException e) {
					EditorsPlugin.log(e);
					fCurrentBlock= new ErrorPreferences(e.getLocalizedMessage());
				}
			}
		}

		Control control= fProviderControls.get(id);
		if (control == null) {
			final Control[] result= new Control[1];
			ISafeRunnable runnable= new ISafeRunnable() {
				@Override
				public void run() throws Exception {
					result[0]= fCurrentBlock.createControl(fGroup);
				}
				@Override
				public void handleException(Throwable x) {
				}
			};
			SafeRunner.run(runnable);
			control= result[0];
			if (control == null) {
				String message= TextEditorMessages.SpellingConfigurationBlock_info_no_preferences;
				EditorsPlugin.log(new Status(IStatus.WARNING, EditorsUI.PLUGIN_ID, IStatus.OK, message, null));
				control= new ErrorPreferences(message).createControl(fGroup);
			} else {
				fProviderControls.put(id, control);
			}
		}
		Dialog.applyDialogFont(control);
		fStackLayout.topControl= control;
		control.pack();
		fGroup.layout();
		fGroup.getParent().layout();

		fStatusMonitor.statusChanged(new StatusInfo());
		ISafeRunnable runnable= new ISafeRunnable() {
			@Override
			public void run() throws Exception {
				fCurrentBlock.initialize(fStatusMonitor);
			}
			@Override
			public void handleException(Throwable x) {
			}
		};
		SafeRunner.run(runnable);
	}

	@Override
	public void initialize() {
		restoreFromPreferences();
	}

	@Override
	public boolean canPerformOk() {
		SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore);
		String id= desc != null ? desc.getId() : ""; //$NON-NLS-1$
		final ISpellingPreferenceBlock block= fProviderPreferences.get(id);
		if (block == null)
			return true;

		final Boolean[] result= new Boolean[] { Boolean.TRUE };
		ISafeRunnable runnable= new ISafeRunnable() {
			@Override
			public void run() throws Exception {
				result[0]= Boolean.valueOf(block.canPerformOk());
			}
			@Override
			public void handleException(Throwable x) {
			}
		};
		SafeRunner.run(runnable);
		return result[0].booleanValue();
	}

	@Override
	public void performOk() {
		for (ISpellingPreferenceBlock block : fProviderPreferences.values()) {
			ISafeRunnable runnable= new ISafeRunnable() {
				@Override
				public void run() throws Exception {
					block.performOk();
				}
				@Override
				public void handleException(Throwable x) {
				}
			};
			SafeRunner.run(runnable);
		}
	}

	@Override
	public void performDefaults() {
		restoreFromPreferences();
		for (ISpellingPreferenceBlock block : fProviderPreferences.values()) {
			ISafeRunnable runnable= new ISafeRunnable() {
				@Override
				public void run() throws Exception {
					block.performDefaults();
				}
				@Override
				public void handleException(Throwable x) {
				}
			};
			SafeRunner.run(runnable);
		}
	}

	@Override
	public void dispose() {
		for (ISpellingPreferenceBlock block : fProviderPreferences.values()) {
			ISafeRunnable runnable= new ISafeRunnable() {
				@Override
				public void run() throws Exception {
					block.dispose();
				}
				@Override
				public void handleException(Throwable x) {
				}
			};
			SafeRunner.run(runnable);
		}
	}

	private void restoreFromPreferences() {
		if (fEnablementCheckbox == null)
			return;

		boolean enabled= fStore.getBoolean(SpellingService.PREFERENCE_SPELLING_ENABLED);
		fEnablementCheckbox.setSelection(enabled);

		if (fProviderViewer == null)
			updateListDependencies();
		else {
			SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore);
			if (desc != null)
				fProviderViewer.setSelection(new StructuredSelection(desc), true);
		}

		updateCheckboxDependencies();
	}
}
