/*******************************************************************************
 * 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 static 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;
	}

}
