/*=============================================================================#
 # Copyright (c) 2005, 2019 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.internal.ltk.ui.config;

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

import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.preference.ColorSelector;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import org.eclipse.statet.ecommons.databinding.IntegerValidator;
import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.preferences.core.Preference;
import org.eclipse.statet.ecommons.preferences.core.Preference.BooleanPref;
import org.eclipse.statet.ecommons.preferences.core.Preference.IntPref;
import org.eclipse.statet.ecommons.preferences.ui.ColorSelectorObservableValue;
import org.eclipse.statet.ecommons.preferences.ui.ConfigurationBlock;
import org.eclipse.statet.ecommons.preferences.ui.ConfigurationBlockPreferencePage;
import org.eclipse.statet.ecommons.preferences.ui.ManagedConfigurationBlock;
import org.eclipse.statet.ecommons.preferences.ui.RGBPref;
import org.eclipse.statet.ecommons.runtime.core.StatusChangeListener;
import org.eclipse.statet.ecommons.text.ui.settings.AssistPreferences;
import org.eclipse.statet.ecommons.text.ui.settings.DecorationPreferences;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;

import org.eclipse.statet.ltk.ui.LTKUIPreferences;


public class EditorsPreferencePage extends ConfigurationBlockPreferencePage {
	
	
	public EditorsPreferencePage() {
	}
	
	
	@Override
	protected ConfigurationBlock createConfigurationBlock() {
		return new EditorsConfigurationBlock(createStatusChangedListener());
	}
	
}


class EditorsConfigurationBlock extends ManagedConfigurationBlock {
	
	private static class AppearanceColorsItem {
		
		final String name;
		final RGBPref pref;
		
		AppearanceColorsItem(final String label, final RGBPref pref) {
			this.name= label;
			this.pref= pref;
		}
		
	}
	
	
	private ListViewer colorList;
	private ColorSelector colorEditor;
	
	private BooleanPref matchingBracketsPref;
	private Button matchingBracketsControl;
	
	private Button contentAssistSingleControl;
	private BooleanPref contentAssistAutoSinglePref;
	private Button contentAssistAutoCommonControl;
	private BooleanPref contentAssistAutoCommonPref;
	private IntPref contentAssistDelayPref;
	private Text contentAssistDelayControl;
	
	
	public EditorsConfigurationBlock(final StatusChangeListener statusListener) {
		super(null, Messages.Editors_title, statusListener);
	}
	
	
	@Override
	protected void createBlockArea(final Composite pageComposite) {
		final Map<Preference<?>, String> prefs= new HashMap<>();
		
		final List<AppearanceColorsItem> colors= new ArrayList<>();
		
		// Matching Bracket
		final DecorationPreferences decoPrefs= LTKUIPreferences.getEditorDecorationPreferences();
		this.matchingBracketsPref= decoPrefs.getMatchingBracketsEnabled();
		prefs.put(this.matchingBracketsPref, null);
		{	final AppearanceColorsItem color= new AppearanceColorsItem(
					Messages.Editors_MatchingBracketsHighlightColor,
					decoPrefs.getMatchingBracketsColor() );
			colors.add(color);
			prefs.put(color.pref, null);
		}
		
		// Assist
		{	final AppearanceColorsItem color= new AppearanceColorsItem(
					Messages.Editors_CodeAssistParametersForegrondColor,
					LTKUIPreferences.CONTEXT_INFO_FOREGROUND_COLOR_PREF );
			colors.add(color);
			prefs.put(color.pref, LTKUIPreferences.ASSIST_GROUP_ID);
		}
		{	final AppearanceColorsItem color= new AppearanceColorsItem(
					Messages.Editors_CodeAssistParametersBackgroundColor,
					LTKUIPreferences.CONTEXT_INFO_BACKGROUND_COLOR_PREF );
			colors.add(color);
			prefs.put(color.pref, LTKUIPreferences.ASSIST_GROUP_ID);
		}
		
		final AssistPreferences assistPreferences= LTKUIPreferences.getAssistPreferences();
		this.contentAssistAutoSinglePref= assistPreferences.getAutoInsertSinglePref();
		prefs.put(this.contentAssistAutoSinglePref, LTKUIPreferences.ASSIST_GROUP_ID);
		this.contentAssistAutoCommonPref= assistPreferences.getAutoInsertPrefixPref();
		prefs.put(this.contentAssistAutoCommonPref, LTKUIPreferences.ASSIST_GROUP_ID);
		this.contentAssistDelayPref= LTKUIPreferences.CONTENT_ASSIST_DELAY_PREF;
		prefs.put(this.contentAssistDelayPref, LTKUIPreferences.ASSIST_GROUP_ID);

		// Register preferences
		setupPreferenceManager(prefs);
		
		// Controls
		addLinkHeader(pageComposite, Messages.Editors_link);
		{	final Composite group= createAppearanceSection(pageComposite);
			group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		}
		LayoutUtils.addSmallFiller(pageComposite, false);
		{	final Composite group= createAssistSection(pageComposite);
			group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		}
		
		// Binding
		this.colorList.setInput(colors.toArray(new AppearanceColorsItem[colors.size()]));
		this.colorList.setSelection(new StructuredSelection(colors.get(0)));
		initBindings();
		updateControls();
	}
	
	private Composite createAppearanceSection(final Composite parent) {
		final Group group= new Group(parent, SWT.NONE);
		group.setText(Messages.Editors_Appearance);
		group.setLayout(LayoutUtils.newGroupGrid(2));
		
		this.matchingBracketsControl= new Button(group, SWT.CHECK | SWT.LEFT);
		this.matchingBracketsControl.setText(Messages.Editors_HighlightMatchingBrackets);
		this.matchingBracketsControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
		
		LayoutUtils.addSmallFiller(group, false);
		final Composite colorComposite;
		{	colorComposite= new Composite(group, SWT.NONE);
			final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
			colorComposite.setLayoutData(gd);
			colorComposite.setLayout(LayoutUtils.newCompositeGrid(2));
			final Label label= new Label(colorComposite, SWT.LEFT);
			label.setText(Messages.Editors_AppearanceColors);
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
		}
		{	this.colorList= new ListViewer(colorComposite, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
			this.colorList.setContentProvider(new ArrayContentProvider());
			this.colorList.setLabelProvider(new LabelProvider() {
				@Override
				public String getText(final Object element) {
					final AppearanceColorsItem item= (AppearanceColorsItem) element;
					return item.name;
				}
			});
			this.colorList.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
		}
		{	final Composite colorOptions= new Composite(colorComposite, SWT.NONE);
			colorOptions.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
			colorOptions.setLayout(LayoutUtils.newCompositeGrid(2));
			
			final Label label= new Label(colorOptions, SWT.LEFT);
			label.setText(Messages.Editors_Color);
			label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
			this.colorEditor= new ColorSelector(colorOptions);
			this.colorEditor.getButton().setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
		}
		
		return group;
	}
	
	private Composite createAssistSection(final Composite parent) {
		final Group composite= new Group(parent, SWT.NONE);
		composite.setText(Messages.Editors_ContentAssist);
		composite.setLayout(LayoutUtils.newGroupGrid(2));
		
		{	final Button button= new Button(composite, SWT.CHECK);
			button.setText(Messages.Editors_ContentAssist_AutoInsertSingle);
			button.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
			this.contentAssistSingleControl= button;
		}
		{	final Button button= new Button(composite, SWT.CHECK);
			button.setText(Messages.Editors_ContentAssist_AutoInsertCommon);
			button.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
			this.contentAssistAutoCommonControl= button;
		}
		LayoutUtils.addSmallFiller(composite, false);
		{	final Label label= new Label(composite, SWT.LEFT);
			label.setText(Messages.Editors_ContentAssist_AutoTriggerDelay_label);
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
			
			final Text text= new Text(composite, SWT.SINGLE | SWT.BORDER);
			final GridData gd= new GridData(SWT.LEFT, SWT.CENTER, true, false);
			gd.widthHint= LayoutUtils.hintWidth(text, 4);
			text.setLayoutData(gd);
			this.contentAssistDelayControl= text;
		}
		return composite;
	}
	
	@Override
	protected void addBindings(final DataBindingSupport db) {
		db.getContext().bindValue(
				WidgetProperties.selection().observe(this.matchingBracketsControl),
				createObservable(this.matchingBracketsPref) );
		final IObservableValue<AppearanceColorsItem> colorItem= ViewersObservables
				.observeSingleSelection(this.colorList);
		db.getContext().bindValue(new ColorSelectorObservableValue(this.colorEditor),
				MasterDetailObservables.detailValue(colorItem, new IObservableFactory() {
					@Override
					public IObservable createObservable(final Object target) {
						final AppearanceColorsItem item= (AppearanceColorsItem) target;
						return EditorsConfigurationBlock.this.createObservable(item.pref);
					}
				}, RGB.class) );
		
		db.getContext().bindValue(
				WidgetProperties.selection().observe(this.contentAssistSingleControl),
				createObservable(this.contentAssistAutoSinglePref) );
		db.getContext().bindValue(
				WidgetProperties.selection().observe(this.contentAssistAutoCommonControl),
				createObservable(this.contentAssistAutoCommonPref) );
		db.getContext().bindValue(
				WidgetProperties.text(SWT.Modify).observe(this.contentAssistDelayControl),
				createObservable(this.contentAssistDelayPref),
				new UpdateValueStrategy().setAfterGetValidator(
						new IntegerValidator(10, 2000, Messages.Editors_ContentAssist_AutoTriggerDelay_error_message) ),
				null );
	}
	
}
