/*=============================================================================#
 # Copyright (c) 2009, 2018 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rj.eclient.graphics;

import java.util.ArrayList;
import java.util.List;

import org.osgi.service.prefs.BackingStoreException;

import org.eclipse.core.databinding.AggregateValidationStatus;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FontDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.ecommons.databinding.DecimalValidator;
import org.eclipse.statet.ecommons.ui.components.StatusInfo;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;


/**
 * Preference page with options to configure R graphic options:
 * <ul>
 *    <li>Default font families ('serif', 'sans', 'mono')</li>
 * </ul>
 * 
 * The page is not registered by this plug-in.
 */
public class RGraphicsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
	
	
	public static double[] parseDPI(final String prefValue) {
		if (prefValue != null) {
			final String[] strings= prefValue.split(",");
			if (strings.length == 2) {
				try {
					return new double[] {
							Double.parseDouble(strings[0]),
							Double.parseDouble(strings[1]),
					};
				}
				catch (final Exception e) {}
			}
		}
		return null;
	}
	
	
	private static class FontPref {
		
		final String prefKey;
		
		String defaultName;
		String currentName;
		
		Font currentFont;
		
		Label valueLabel;
		
		
		public FontPref(final String key) {
			this.prefKey= key;
		}
		
		
		@Override
		public int hashCode() {
			return this.prefKey.hashCode();
		}
		
		@Override
		public boolean equals(final Object obj) {
			return (this == obj
					|| (obj instanceof FontPref
							&& this.prefKey.equals(((FontPref) obj).prefKey) ));
		}
		
	}
	
	private static class Encoding {
		
		final String label;
		final String prefValue;
		
		
		public Encoding(final String label, final String prefValue) {
			this.label= label;
			this.prefValue= prefValue;
		}
		
		
		@Override
		public int hashCode() {
			return this.prefValue.hashCode();
		}
		
		@Override
		public boolean equals(final Object obj) {
			return (this == obj
					|| (obj instanceof Encoding
							&& this.prefValue.equals(((Encoding) obj).prefValue) ));
		}
		
		@Override
		public String toString() {
			return this.label.toString();
		};
		
	}
	
	private static final Encoding[] SYMBOL_ENCODINGS= new Encoding[] {
			new Encoding("Unicode", "Unicode"),
			new Encoding("Adobe Symbol", "AdobeSymbol"),
	};
	
	private static final Encoding SYMBOL_ENCODING_DEFAULT= SYMBOL_ENCODINGS[1];
	
	
	private DataBindingContext dbc;
	
	private FontPref serifPref;
	private FontPref sansPref;
	private FontPref monoPref;
	private FontPref symbolFontPref;
	private FontPref[] fontPrefs;
	private Button symbolUseControl;
	private ComboViewer symbolEncodingControl;
	private Control[] symbolChildControls;
	
	private final int size= 10;
	
	private Button customDpiControl;
	private Composite customDpiComposite;
	private Text customHDpiControl;
	private Text customVDpiControl;
	
	private boolean customEnabled;
	private IObservableValue<Double> customHDpiVisibleValue;
	private IObservableValue<Double> customVDpiVisibleValue;
	private double customHDpiUserValue;
	private double customVDpiUserValue;
	
	
	/**
	 * Created via extension point
	 */
	public RGraphicsPreferencePage() {
	}
	
	
	@Override
	public void init(final IWorkbench workbench) {
		this.serifPref= new FontPref(RGraphics.PREF_FONTS_SERIF_FONTNAME_KEY);
		this.sansPref= new FontPref(RGraphics.PREF_FONTS_SANS_FONTNAME_KEY);
		this.monoPref= new FontPref(RGraphics.PREF_FONTS_MONO_FONTNAME_KEY);
		this.symbolFontPref= new FontPref(RGraphics.PREF_FONTS_SYMBOL_FONTNAME_KEY);
		this.fontPrefs= new FontPref[] { this.serifPref, this.sansPref, this.monoPref, this.symbolFontPref };
		
		final IEclipsePreferences node= DefaultScope.INSTANCE.getNode(RGraphics.FONTS_PREF_QUALIFIER);
		for (final FontPref pref : this.fontPrefs) {
			pref.defaultName= (node != null) ? node.get(pref.prefKey, "") : "";
		}
	}
	
	@Override
	protected Control createContents(final Composite parent) {
		final Composite pageComposite= new Composite(parent, SWT.NONE);
		pageComposite.setLayout(LayoutUtils.newCompositeGrid(1));
		
		final Group displayGroup= createDisplayGroup(pageComposite);
		displayGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		
		final Group fontGroup= createFontGroup(pageComposite);
		fontGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		
		initBindings();
		loadDisplayOptions();
		loadFontOptions();
		
		applyDialogFont(pageComposite);
		
		return pageComposite;
	}
	
	protected Group createDisplayGroup(final Composite parent) {
		final Group group= new Group(parent, SWT.NONE);
		group.setText("Display:");
		group.setLayout(LayoutUtils.newGroupGrid(2));
		
		this.customDpiControl= new Button(group, SWT.CHECK);
		this.customDpiControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
		this.customDpiControl.setText("Use custom DPI (instead of system setting):");
		
		this.customDpiComposite= new Composite(group, SWT.NONE);
		
		{	final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, false);
			gd.horizontalIndent= LayoutUtils.defaultIndent();
			this.customDpiComposite.setLayoutData(gd);
			this.customDpiComposite.setLayout(LayoutUtils.newCompositeGrid(2));
		}
		
		{	final Label label= new Label(this.customDpiComposite, SWT.LEFT);
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			label.setText("&Horizontal (x):");
		}
		{	final Text text= new Text(this.customDpiComposite, SWT.BORDER | SWT.RIGHT);
			final GridData gd= new GridData(SWT.LEFT, SWT.CENTER, false, false);
			gd.widthHint= LayoutUtils.hintWidth(text, 8);
			text.setLayoutData(gd);
			this.customHDpiControl= text;
		}
		{	final Label label= new Label(this.customDpiComposite, SWT.LEFT);
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			label.setText("&Vertical (y):");
		}
		{	final Text text= new Text(this.customDpiComposite, SWT.BORDER | SWT.RIGHT);
			final GridData gd= new GridData(SWT.LEFT, SWT.CENTER, false, false);
			gd.widthHint= LayoutUtils.hintWidth(text, 8);
			text.setLayoutData(gd);
			this.customVDpiControl= text;
		}
		
		this.customDpiControl.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(final SelectionEvent e) {
				updateDisplayGroup();
			}
		});
		
		return group;
	}
	
	private void updateDisplayGroup() {
		this.customEnabled= this.customDpiControl.getSelection();
		DialogUtils.setEnabled(this.customDpiComposite, null, this.customEnabled);
		
		final double hvalue;
		final double vvalue;
		if (!this.customEnabled || this.customHDpiUserValue <= 0 || this.customVDpiUserValue <= 0) {
			final Point dpi= Display.getDefault().getDPI();
			hvalue= dpi.x;
			vvalue= dpi.y;
			if (this.customEnabled) {
				this.customHDpiUserValue= hvalue;
				this.customVDpiUserValue= vvalue;
			}
		}
		else {
			hvalue= this.customHDpiUserValue;
			vvalue= this.customVDpiUserValue;
		}
		this.customHDpiVisibleValue.setValue(hvalue);
		this.customVDpiVisibleValue.setValue(vvalue);
	}
	
	protected Group createFontGroup(final Composite parent) {
		final Group group= new Group(parent, SWT.NONE);
		group.setText("Fonts:");
		group.setLayout(LayoutUtils.newGroupGrid(3));
		
		addFont(group, this.serifPref, "Default &Serif Font ('serif'):");
		addFont(group, this.sansPref, "Default S&ansserif Font ('sans'):");
		addFont(group, this.monoPref, "Default &Monospace Font ('mono'):");
		
		LayoutUtils.addSmallFiller(group, false);
		
		this.symbolUseControl= new Button(group, SWT.CHECK);
		this.symbolUseControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));
		this.symbolUseControl.setText("Use special S&ymbol Font");
		final List<Control> symbolControls= new ArrayList<>();
		addFont(group, this.symbolFontPref, "Symbol &Font:",
				LayoutUtils.defaultIndent(), symbolControls );
		{	final Label label= new Label(group, SWT.NONE);
			final GridData gd= new GridData(SWT.FILL, SWT.CENTER, false, false);
			gd.horizontalIndent= LayoutUtils.defaultIndent();
			label.setLayoutData(gd);
			label.setText("Encoding:");
			symbolControls.add(label);
		}
		{	this.symbolEncodingControl= new ComboViewer(group, SWT.DROP_DOWN | SWT.READ_ONLY);
			final GridData gd= new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1);
			gd.widthHint= LayoutUtils.hintWidth(this.symbolEncodingControl.getCombo(), 15);
			this.symbolEncodingControl.getControl().setLayoutData(gd);
			this.symbolEncodingControl.setContentProvider(new ArrayContentProvider());
			this.symbolEncodingControl.setInput(SYMBOL_ENCODINGS);
			symbolControls.add(this.symbolEncodingControl.getControl());
		}
		this.symbolChildControls= symbolControls.toArray(new Control[symbolControls.size()]);
		this.symbolUseControl.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(final SelectionEvent e) {
				updateSymbolControls();
			}
		});
		
		return group;
	}
	
	private void addFont(final Group group, final FontPref pref, final String text) {
		addFont(group, pref, text, 0, null);
	}
	
	private void addFont(final Group group, final FontPref pref, final String text,
			final int indent, final List<Control> controls) {
		final Label label= new Label(group, SWT.NONE);
		final GridData gd= new GridData(SWT.FILL, SWT.CENTER, false, false);
		gd.horizontalIndent= indent;
		label.setLayoutData(gd);
		label.setText(text);
		
		pref.valueLabel= new Label(group, SWT.BORDER);
		pref.valueLabel.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_WHITE));
		pref.valueLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		
		final Button button= new Button(group, SWT.PUSH);
		button.setText("Edit...");
		button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
		button.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(final SelectionEvent e) {
				final FontDialog dialog= new FontDialog(button.getShell(), SWT.NONE);
				dialog.setFontList((pref.currentFont != null) ? pref.currentFont.getFontData() : null);
				final FontData result= dialog.open();
				if (result != null) {
					set(pref, result.getName());
				}
			}
			@Override
			public void widgetDefaultSelected(final SelectionEvent e) {
			}
		});
		
		if (controls != null) {
			controls.add(label);
			controls.add(pref.valueLabel);
			controls.add(button);
		}
	}
	
	protected void initBindings() {
		final Realm realm= Realm.getDefault();
		this.dbc= new DataBindingContext(realm);
		addBindings(this.dbc, realm);
		
		final AggregateValidationStatus validationStatus= new AggregateValidationStatus(this.dbc, AggregateValidationStatus.MAX_SEVERITY);
		validationStatus.addValueChangeListener(
				(final ValueChangeEvent<? extends IStatus> event) -> {
					final IStatus currentStatus= event.diff.getNewValue();
					updateStatus(currentStatus);
				} );
	}
	
	protected void addBindings(final DataBindingContext dbc, final Realm realm) {
		this.customHDpiVisibleValue= new WritableValue<>(realm, 96.0, Double.class);
		this.customVDpiVisibleValue= new WritableValue<>(realm, 96.0, Double.class);
		
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify).observe(this.customHDpiControl),
				this.customHDpiVisibleValue,
				new UpdateValueStrategy().setAfterGetValidator(new DecimalValidator(10.0, 10000.0,
						"The value for Horizontal (x) DPI is invalid (10-10000)." )),
				null );
		dbc.bindValue(
				WidgetProperties.text(SWT.Modify).observe(this.customVDpiControl),
				this.customVDpiVisibleValue,
				new UpdateValueStrategy().setAfterGetValidator(new DecimalValidator(10.0, 10000.0,
						"The value for Vertical (x) DPI is invalid (10-10000)." )),
				null );
		
		this.customHDpiVisibleValue.addValueChangeListener(
				(final ValueChangeEvent<? extends Double> event) -> {
					if (RGraphicsPreferencePage.this.customEnabled) {
						RGraphicsPreferencePage.this.customHDpiUserValue= RGraphicsPreferencePage.this.customHDpiVisibleValue.getValue();
					}
				} );
		this.customVDpiVisibleValue.addValueChangeListener(
				(final ValueChangeEvent<? extends Double> event) -> {
					if (RGraphicsPreferencePage.this.customEnabled) {
						RGraphicsPreferencePage.this.customVDpiUserValue= RGraphicsPreferencePage.this.customVDpiVisibleValue.getValue();
					}
				} );
	}
	
	protected void updateStatus(final IStatus status) {
		setValid(!status.matches(IStatus.ERROR));
		StatusInfo.applyToStatusLine(this, status);
	}
	
	protected void setCustomDpi(final String prefValue) {
		final double[] dpi= parseDPI(prefValue);
		if (dpi != null) {
			this.customHDpiUserValue= dpi[0];
			this.customVDpiUserValue= dpi[1];
			this.customDpiControl.setSelection(true);
		}
		else {
			this.customDpiControl.setSelection(false);
		}
		updateDisplayGroup();
	}
	
	protected void updateSymbolControls() {
		DialogUtils.setEnabled(this.symbolChildControls, null, this.symbolUseControl.getSelection());
	}
	
	protected void set(final FontPref pref, final String value) {
		if (value.equals(pref.currentName)) {
			return;
		}
		pref.valueLabel.setText("");
		Font font;
		try {
			font= new Font(pref.valueLabel.getDisplay(), value, this.size, SWT.NONE);
			if (pref != this.symbolFontPref) {
				pref.valueLabel.setFont(font);
			}
			pref.valueLabel.setText(value);
		}
		catch (final SWTError e) {
			font= JFaceResources.getDialogFont();
			pref.valueLabel.setFont(font);
			pref.valueLabel.setText(value + " (not available)");
		}
		if (pref.currentFont != null && !pref.currentFont.isDisposed()) {
			pref.currentFont.dispose();
		}
		pref.currentName= value;
		pref.currentFont= font;
	}
	
	@Override
	protected void performDefaults() {
		setCustomDpi(null);
		this.symbolUseControl.setSelection(true);
		this.symbolEncodingControl.setSelection(new StructuredSelection(SYMBOL_ENCODING_DEFAULT));
		for (final FontPref pref : this.fontPrefs) {
			set(pref, pref.defaultName);
		}
		updateSymbolControls();
		super.performDefaults();
	}
	
	@Override
	protected void performApply() {
		saveDisplayOptions(true);
		saveFontOptions(true);
	}
	
	@Override
	public boolean performOk() {
		saveDisplayOptions(false);
		saveFontOptions(false);
		return true;
	}
	
	
	protected IScopeContext getScope() {
		return InstanceScope.INSTANCE;
	}
	
	protected void loadDisplayOptions() {
		final IEclipsePreferences node= getScope().getNode(RGraphics.PREF_DISPLAY_QUALIFIER);
		setCustomDpi(node.get(RGraphics.PREF_DISPLAY_CUSTOM_DPI_KEY, null));
	}
	
	protected void saveDisplayOptions(final boolean flush) {
		final IEclipsePreferences node= getScope().getNode(RGraphics.PREF_DISPLAY_QUALIFIER);
		if (this.customEnabled) {
			node.put(RGraphics.PREF_DISPLAY_CUSTOM_DPI_KEY,
					Double.toString(this.customHDpiUserValue) + "," + Double.toString(this.customVDpiUserValue));
		}
		else {
			node.remove(RGraphics.PREF_DISPLAY_CUSTOM_DPI_KEY);
		}
		if (flush) {
			try {
				node.flush();
			}
			catch (final BackingStoreException e) {
				StatusManager.getManager().handle(new Status(IStatus.ERROR, RGraphics.BUNDLE_ID, -1,
						"An error occurred when storing R graphics display preferences.", e));
			}
		}
	}
	
	protected void loadFontOptions() {
		if (this.fontPrefs != null) {
			final IEclipsePreferences node= getScope().getNode(RGraphics.FONTS_PREF_QUALIFIER);
			this.symbolUseControl.setSelection(node.getBoolean(RGraphics.PREF_FONTS_SYMBOL_USE_KEY, true));
			final String s= node.get(RGraphics.PREF_FONTS_SYMBOL_ENCODING_KEY, (String) null);
			this.symbolEncodingControl.setSelection(new StructuredSelection((s != null) ?
					new Encoding(null, s) : SYMBOL_ENCODING_DEFAULT ));
			for (final FontPref pref : this.fontPrefs) {
				final String value= node.get(pref.prefKey, ""); //$NON-NLS-1$
				set(pref, (value.length() > 0) ? value : pref.defaultName);
			}
			updateSymbolControls();
		}
	}
	
	protected void saveFontOptions(final boolean flush) {
		if (this.fontPrefs != null) {
			final IEclipsePreferences node= getScope().getNode(RGraphics.FONTS_PREF_QUALIFIER);
			node.putBoolean(RGraphics.PREF_FONTS_SYMBOL_USE_KEY, this.symbolUseControl.getSelection());
			final IStructuredSelection selection= (IStructuredSelection) this.symbolEncodingControl.getSelection();
			if (selection.getFirstElement() instanceof Encoding
					&& !SYMBOL_ENCODING_DEFAULT.equals(selection.getFirstElement())) {
				node.put(RGraphics.PREF_FONTS_SYMBOL_ENCODING_KEY,
						((Encoding) selection.getFirstElement()).prefValue );
			}
			else {
				node.remove(RGraphics.PREF_FONTS_SYMBOL_ENCODING_KEY);
			}
			for (final FontPref pref : this.fontPrefs) {
				if (pref.currentName == null || pref.currentName.equals(pref.defaultName)) {
					node.remove(pref.prefKey);
				}
				else {
					node.put(pref.prefKey, pref.currentName);
				}
			}
			updateSymbolControls();
			if (flush) {
				try {
					node.flush();
				}
				catch (final BackingStoreException e) {
					StatusManager.getManager().handle(new Status(IStatus.ERROR, RGraphics.BUNDLE_ID, -1,
							"An error occurred when storing R graphics font preferences.", e));
				}
			}
		}
	}
	
	@Override
	public void dispose() {
		if (this.dbc != null) {
			this.dbc.dispose();
			this.dbc= null;
		}
		if (this.fontPrefs != null) {
			for (final FontPref pref : this.fontPrefs) {
				if (pref.currentFont != null && !pref.currentFont.isDisposed()) {
					pref.currentFont.dispose();
					pref.currentFont= null;
				}
			}
		}
		super.dispose();
	}
	
}
