/*******************************************************************************
 * 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.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.osgi.service.prefs.BackingStoreException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.InstanceScope;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.ColorSelector;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;

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

import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;

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


/**
 * Configures the linked mode preferences. The preferences belong to
 * org.eclipse.ui.editors. However, as they are chiefly used in the java editor,
 * we keep the preferences here for the time being.
 *
 * @since 3.2 (in jdt.ui since 3.1)
 */
class LinkedModeConfigurationBlock implements IPreferenceConfigurationBlock {

	private static final String EXIT= "org.eclipse.ui.internal.workbench.texteditor.link.exit"; //$NON-NLS-1$
	private static final String TARGET= "org.eclipse.ui.internal.workbench.texteditor.link.target"; //$NON-NLS-1$
	private static final String MASTER= "org.eclipse.ui.internal.workbench.texteditor.link.master"; //$NON-NLS-1$
	private static final String SLAVE= "org.eclipse.ui.internal.workbench.texteditor.link.slave"; //$NON-NLS-1$

	private static final class ListItem {
		final String label;
		final String colorKey;
		final String highlightKey;
		final String textStyleKey;
		final String textKey;
		final List<String[]> validStyles;

		ListItem(String label, String colorKey, String textKey, String highlightKey, String textStyleKey, List<String[]> validStyles) {
			this.label= label;
			this.colorKey= colorKey;
			this.highlightKey= highlightKey;
			this.textKey= textKey;
			this.textStyleKey= textStyleKey;
			this.validStyles= validStyles;
		}
	}

	private static final class ItemContentProvider implements IStructuredContentProvider {

		@Override
		public Object[] getElements(Object inputElement) {
			return (ListItem[]) inputElement;
		}

		@Override
		public void dispose() {
		}

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

	private final class ItemLabelProvider extends LabelProvider {

		@Override
		public String getText(Object element) {
			return ((ListItem) element).label;
		}
	}

	private static class ArrayLabelProvider extends LabelProvider {
		@Override
		public String getText(Object element) {
			return ((String[]) element)[0].toString();
		}
	}

	final static String[] HIGHLIGHT= new String[] {TextEditorMessages.LinkedModeConfigurationBlock_HIGHLIGHT, "unused"};  //$NON-NLS-1$
	final static String[] UNDERLINE= new String[] {TextEditorMessages.LinkedModeConfigurationBlock_UNDERLINE, AnnotationPreference.STYLE_UNDERLINE};
	final static String[] BOX= new String[] {TextEditorMessages.LinkedModeConfigurationBlock_BOX, AnnotationPreference.STYLE_BOX};
	final static String[] DASHED_BOX= new String[] {TextEditorMessages.LinkedModeConfigurationBlock_DASHED_BOX, AnnotationPreference.STYLE_DASHED_BOX};
	final static String[] IBEAM= new String[] {TextEditorMessages.LinkedModeConfigurationBlock_IBEAM, AnnotationPreference.STYLE_IBEAM};
	final static String[] SQUIGGLES= new String[] {TextEditorMessages.LinkedModeConfigurationBlock_SQUIGGLES, AnnotationPreference.STYLE_SQUIGGLES};

	private ColorSelector fAnnotationForegroundColorEditor;

	private Button fShowInTextCheckBox;

	private StructuredViewer fAnnotationTypeViewer;
	private final ListItem[] fListModel;

	private ComboViewer fDecorationViewer;
	private FontMetrics fFontMetrics;
	protected static final int INDENT= 20;
	private OverlayPreferenceStore fStore;

	private ArrayList<SelectionListener> fMasterSlaveListeners= new ArrayList<>();

	private OverlayPreferenceStore getPreferenceStore() {
		return fStore;
	}

	public LinkedModeConfigurationBlock(OverlayPreferenceStore store) {
		fStore= store;
		final MarkerAnnotationPreferences prefs= EditorsPlugin.getDefault().getMarkerAnnotationPreferences();
		getPreferenceStore().addKeys(createOverlayStoreKeys(prefs));
		fListModel= createAnnotationTypeListModel(prefs);
	}

	private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys(MarkerAnnotationPreferences preferences) {
		ArrayList<OverlayKey> overlayKeys= new ArrayList<>();

		Iterator<AnnotationPreference> e= preferences.getAnnotationPreferences().iterator();
		while (e.hasNext()) {
			AnnotationPreference info= e.next();

			if (isLinkedModeAnnotation(info)) {
				overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, info.getColorPreferenceKey()));
				overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, info.getTextPreferenceKey()));
				overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, info.getTextStylePreferenceKey()));
				overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, info.getHighlightPreferenceKey()));
			}
		}

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

	private boolean isLinkedModeAnnotation(AnnotationPreference info) {
		final Object type= info.getAnnotationType();
		return type.equals(MASTER)
				|| (type.equals(SLAVE))
				|| (type.equals(TARGET))
				|| (type.equals(EXIT));
	}

	private ListItem[] createAnnotationTypeListModel(MarkerAnnotationPreferences preferences) {
		ArrayList<ListItem> listModelItems= new ArrayList<>();
		Iterator<AnnotationPreference> e= preferences.getAnnotationPreferences().iterator();

		while (e.hasNext()) {
			AnnotationPreference info= e.next();
			if (isLinkedModeAnnotation(info)) {
				String label= info.getPreferenceLabel();
				List<String[]> styles= getStyles(info.getAnnotationType());
				listModelItems.add(new ListItem(label, info.getColorPreferenceKey(), info.getTextPreferenceKey(), info.getHighlightPreferenceKey(), info.getTextStylePreferenceKey(), styles));
			}
		}

		ListItem[] items= new ListItem[listModelItems.size()];
		listModelItems.toArray(items);
		return items;
	}


	private List<String[]> getStyles(Object type) {
		if (type.equals(MASTER))
			return Arrays.asList(BOX, DASHED_BOX, HIGHLIGHT, UNDERLINE, SQUIGGLES);
		if (type.equals(SLAVE))
			return Arrays.asList(BOX, DASHED_BOX, HIGHLIGHT, UNDERLINE, SQUIGGLES);
		if (type.equals(TARGET))
			return Arrays.asList(BOX, DASHED_BOX, HIGHLIGHT, UNDERLINE, SQUIGGLES);
		if (type.equals(EXIT))
			return Arrays.asList(new String[][] { IBEAM });
		return new ArrayList<>();
	}

	/**
	 * Creates page for hover preferences.
	 *
	 * @param parent the parent composite
	 * @return the control for the preference page
	 */
	@Override
	public Control createControl(Composite parent) {
		OverlayPreferenceStore store= getPreferenceStore();
		store.load();
		store.start();

		initializeDialogUnits(parent);

		Composite composite= new Composite(parent, SWT.NONE);
		GridLayout layout= new GridLayout();
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		composite.setLayout(layout);

		Label label= new Label(composite, SWT.LEFT);
		label.setText(TextEditorMessages.LinkedModeConfigurationBlock_annotationPresentationOptions);
		GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		label.setLayoutData(gd);

		Composite editorComposite= new Composite(composite, SWT.NONE);
		layout= new GridLayout();
		layout.numColumns= 2;
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		editorComposite.setLayout(layout);
		gd= new GridData(SWT.FILL, SWT.FILL, true, true);
		editorComposite.setLayoutData(gd);

		fAnnotationTypeViewer= new TableViewer(editorComposite, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
		fAnnotationTypeViewer.setLabelProvider(new ItemLabelProvider());
		fAnnotationTypeViewer.setContentProvider(new ItemContentProvider());
		gd= new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false);
		gd.heightHint= convertHeightInCharsToPixels(5);
		fAnnotationTypeViewer.getControl().setLayoutData(gd);

		Composite optionsComposite= new Composite(editorComposite, SWT.NONE);
		layout= new GridLayout();
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		layout.numColumns= 2;
		optionsComposite.setLayout(layout);
		optionsComposite.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));

		// we only allow to set either "show in text" or "highlight in text", but not both

		fShowInTextCheckBox= new Button(optionsComposite, SWT.CHECK);
		fShowInTextCheckBox.setText(TextEditorMessages.LinkedModeConfigurationBlock_labels_showIn);
		gd= new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalAlignment= GridData.BEGINNING;
		fShowInTextCheckBox.setLayoutData(gd);

		fDecorationViewer= new ComboViewer(optionsComposite, SWT.READ_ONLY);
		fDecorationViewer.setContentProvider(ArrayContentProvider.getInstance());
		fDecorationViewer.setLabelProvider(new ArrayLabelProvider());
		fDecorationViewer.setComparator(new ViewerComparator(Collator.getInstance()));

		gd= new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalAlignment= GridData.BEGINNING;
		fDecorationViewer.getControl().setLayoutData(gd);
		fDecorationViewer.setInput(new Object[] {HIGHLIGHT, SQUIGGLES, BOX, DASHED_BOX, UNDERLINE, IBEAM});

		label= new Label(optionsComposite, SWT.LEFT);
		label.setText(TextEditorMessages.LinkedModeConfigurationBlock_color);
		gd= new GridData();
		gd.horizontalAlignment= GridData.BEGINNING;
		label.setLayoutData(gd);

		fAnnotationForegroundColorEditor= new ColorSelector(optionsComposite);
		Button foregroundColorButton= fAnnotationForegroundColorEditor.getButton();
		gd= new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalAlignment= GridData.BEGINNING;
		foregroundColorButton.setLayoutData(gd);

		createDependency(fShowInTextCheckBox, new Control[] {label, foregroundColorButton});

		fAnnotationTypeViewer.addSelectionChangedListener(event -> handleAnnotationListSelection());

		fShowInTextCheckBox.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// do nothing
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				ListItem item= getSelectedItem();
				final boolean value= fShowInTextCheckBox.getSelection();
				if (value) {
					// enable whatever is in the combo
					String[] decoration= (String[]) fDecorationViewer.getStructuredSelection().getFirstElement();
					if (HIGHLIGHT.equals(decoration))
						getPreferenceStore().setValue(item.highlightKey, true);
					else
						getPreferenceStore().setValue(item.textKey, true);
				} else {
					// disable both
					getPreferenceStore().setValue(item.textKey, false);
					getPreferenceStore().setValue(item.highlightKey, false);
				}
				getPreferenceStore().setValue(item.textKey, value);
				updateDecorationViewer(item, false);
			}
		});

		foregroundColorButton.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				// do nothing
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				ListItem item= getSelectedItem();
				PreferenceConverter.setValue(getPreferenceStore(), item.colorKey, fAnnotationForegroundColorEditor.getColorValue());
			}
		});

		fDecorationViewer.addSelectionChangedListener(event -> {
			String[] decoration= (String[]) fDecorationViewer.getStructuredSelection().getFirstElement();
			ListItem item= getSelectedItem();

			if (fShowInTextCheckBox.getSelection()) {
				if (HIGHLIGHT.equals(decoration)) {
					getPreferenceStore().setValue(item.highlightKey, true);
					getPreferenceStore().setValue(item.textKey, false);
					getPreferenceStore().setValue(item.textStyleKey, AnnotationPreference.STYLE_NONE);
				} else {
					getPreferenceStore().setValue(item.highlightKey, false);
					getPreferenceStore().setValue(item.textKey, true);
					getPreferenceStore().setValue(item.textStyleKey, decoration[1]);
				}
			}
		});

		return composite;

	}

	@Override
	public void applyData(Object data) {
	}

	/**
	 * Returns the number of pixels corresponding to the width of the given number of characters.
	 * <p>
	 * This method may only be called after <code>initializeDialogUnits</code> has been called.
	 * </p>
	 * <p>
	 * Clients may call this framework method, but should not override it.
	 * </p>
	 *
	 * @param chars the number of characters
	 * @return the number of pixels
	 */
	protected int convertWidthInCharsToPixels(int chars) {
		// test for failure to initialize for backward compatibility
		if (fFontMetrics == null)
			return 0;
		return Dialog.convertWidthInCharsToPixels(fFontMetrics, chars);
	}

	/**
	 * Returns the number of pixels corresponding to the height of the given number of characters.
	 * <p>
	 * This method may only be called after <code>initializeDialogUnits</code> has been called.
	 * </p>
	 * <p>
	 * Clients may call this framework method, but should not override it.
	 * </p>
	 *
	 * @param chars the number of characters
	 * @return the number of pixels
	 */
	protected int convertHeightInCharsToPixels(int chars) {
		// test for failure to initialize for backward compatibility
		if (fFontMetrics == null)
			return 0;
		return Dialog.convertHeightInCharsToPixels(fFontMetrics, chars);
	}

	/**
	 * Initializes the computation of horizontal and vertical dialog units based on the size of
	 * current font.
	 * <p>
	 * This method must be called before any of the dialog unit based conversion methods are called.
	 * </p>
	 *
	 * @param testControl a control from which to obtain the current font
	 */
	protected void initializeDialogUnits(Control testControl) {
		// Compute and store a font metric
		GC gc = new GC(testControl);
		gc.setFont(JFaceResources.getDialogFont());
		fFontMetrics = gc.getFontMetrics();
		gc.dispose();
	}

	private void handleAnnotationListSelection() {
		ListItem item= getSelectedItem();

		RGB rgb= PreferenceConverter.getColor(getPreferenceStore(), item.colorKey);
		fAnnotationForegroundColorEditor.setColorValue(rgb);

		boolean highlight= item.highlightKey == null ? false : getPreferenceStore().getBoolean(item.highlightKey);
		boolean showInText = item.textKey == null ? false : getPreferenceStore().getBoolean(item.textKey);
		fShowInTextCheckBox.setSelection(showInText || highlight);

		updateDecorationViewer(item, true);
	}

	@Override
	public void initialize() {
		initializeFields();

		fAnnotationTypeViewer.setInput(fListModel);
		fAnnotationTypeViewer.getControl().getDisplay().asyncExec(() -> {
			if (fAnnotationTypeViewer != null && !fAnnotationTypeViewer.getControl().isDisposed()) {
				fAnnotationTypeViewer.setSelection(new StructuredSelection(fListModel[0]));
				initializeFields();
			}
		});
	}

	private ListItem getSelectedItem() {
		return (ListItem) fAnnotationTypeViewer.getStructuredSelection().getFirstElement();
	}

	private void updateDecorationViewer(ListItem item, boolean changed) {
		// decoration selection: if the checkbox is enabled, there is
		// only one case where the combo is not enabled: if both the highlight and textStyle keys are null
		final boolean enabled= fShowInTextCheckBox.getSelection() && !(item.highlightKey == null && item.textStyleKey == null);
		fDecorationViewer.getControl().setEnabled(enabled);

		if (changed) {
			String[] selection= null;
			ArrayList<String[]> list= new ArrayList<>();

			list.addAll(item.validStyles);

			if (getPreferenceStore().getBoolean(item.highlightKey))
				selection= HIGHLIGHT;

			// set selection
			if (selection == null) {
				String val= getPreferenceStore().getString(item.textStyleKey);
				for (String[] elem : list) {
					if (elem[1].equals(val)) {
						selection= elem;
						break;
					}
				}
			}

			fDecorationViewer.setInput(list.toArray(new Object[list.size()]));
			if (selection == null)
				selection= list.get(0);
			fDecorationViewer.setSelection(new StructuredSelection((Object) selection), true);
		}
	}


	@Override
	public void performOk() {
		getPreferenceStore().propagate();

		try {
			Platform.getPreferencesService().getRootNode().node(InstanceScope.SCOPE).node(EditorsUI.PLUGIN_ID).flush();
		} catch (BackingStoreException e) {
			EditorsPlugin.log(e);
		}
	}


	@Override
	public void performDefaults() {
		getPreferenceStore().loadDefaults();

		/*
		 * Only call super after updating fShowInTextCheckBox, so that
		 * the master-slave dependencies get properly updated.
		 */
		handleAnnotationListSelection();

		initializeFields();
	}

	@Override
	public void dispose() {
		OverlayPreferenceStore store= getPreferenceStore();
		if (store != null) {
			store.stop();
		}
	}

	protected void createDependency(final Button master, final Control slave) {
		createDependency(master, new Control[] {slave});
	}

	protected void createDependency(final Button master, final Control[] slaves) {
		Assert.isTrue(slaves.length > 0);
		indent(slaves[0]);
		SelectionListener listener= new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				boolean state= master.getSelection();
				for (Control slave : slaves) {
					slave.setEnabled(state);
				}
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		};
		master.addSelectionListener(listener);
		fMasterSlaveListeners.add(listener);
	}

	protected static void indent(Control control) {
		((GridData) control.getLayoutData()).horizontalIndent+= INDENT;
	}

	private void initializeFields() {

		// Update slaves
		Iterator<SelectionListener> iter= fMasterSlaveListeners.iterator();
		while (iter.hasNext()) {
			SelectionListener listener= iter.next();
			listener.widgetSelected(null);
		}
	}

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

}
