/*=============================================================================#
 # 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.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.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.LayoutUtil;


/**
 * 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(LayoutUtil.applyCompositeDefaults(new GridLayout(), 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(LayoutUtil.applyGroupDefaults(new GridLayout(), 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= LayoutUtil.defaultIndent();
			this.customDpiComposite.setLayoutData(gd);
			this.customDpiComposite.setLayout(LayoutUtil.applyCompositeDefaults(new GridLayout(), 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= LayoutUtil.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= LayoutUtil.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(LayoutUtil.applyGroupDefaults(new GridLayout(), 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'):");
		
		LayoutUtil.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:",
				LayoutUtil.defaultIndent(), symbolControls );
		{	final Label label= new Label(group, SWT.NONE);
			final GridData gd= new GridData(SWT.FILL, SWT.CENTER, false, false);
			gd.horizontalIndent= LayoutUtil.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= LayoutUtil.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();
	}
	
}
