/*=============================================================================#
 # Copyright (c) 2007, 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.redocs.wikitext.r.ui.config;

import static org.eclipse.statet.redocs.wikitext.r.ui.sourceediting.WikitextRweaveEditingSettings.WIKIDOC_SPELLCHECK_ENABLED_PREF;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Link;

import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.preferences.core.Preference;
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.runtime.core.StatusChangeListener;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;

import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.redocs.wikitext.r.ui.sourceediting.WikitextRweaveEditingSettings;


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


class EditorConfigurationBlock extends ManagedConfigurationBlock {
	
	
	private Button spellEnableControl;
	
	
	public EditorConfigurationBlock(final StatusChangeListener statusListener) {
		super(null, statusListener);
	}
	
	
	@Override
	public void createBlockArea(final Composite pageComposite) {
		final Map<Preference<?>, String> prefs= new HashMap<>();
		
		prefs.put(WIKIDOC_SPELLCHECK_ENABLED_PREF, WikitextRweaveEditingSettings.WIKIDOC_EDITOR_NODE);
		
		setupPreferenceManager(prefs);
		
		// Controls
		{	final Link link= addLinkControl(pageComposite, NLS.bind(
					Messages.EditorOptions_WikitextAndRRef_note,
					RUI.SOURCE_EDITORS_PREF_PAGE_ID ));
			final GridData gd= new GridData(SWT.FILL, SWT.TOP, true, false);
			gd.widthHint= 300;
			link.setLayoutData(gd);
		}
		{	final Link link= addLinkControl(pageComposite, Messages.EditorOptions_SyntaxColoring_note);
			final GridData gd= new GridData(SWT.FILL, SWT.TOP, true, false);
			gd.widthHint= 300;
			gd.horizontalIndent= LayoutUtils.defaultIndent();
			link.setLayoutData(gd);
		}
		
		// Annotation
		LayoutUtils.addSmallFiller(pageComposite, false);
		
		{	this.spellEnableControl= new Button(pageComposite, SWT.CHECK);
			this.spellEnableControl.setText(Messages.EditorOptions_SpellChecking_Enable_label);
			this.spellEnableControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
			
			final Link link= addLinkControl(pageComposite, Messages.EditorOptions_SpellChecking_note);
			final GridData gd= new GridData(SWT.FILL, SWT.TOP, true, false);
			gd.widthHint= 300;
			gd.horizontalIndent= LayoutUtils.defaultIndent();
			link.setLayoutData(gd);
		}
		
		LayoutUtils.addSmallFiller(pageComposite, true);
		
		{	final Link link= addLinkControl(pageComposite, Messages.EditorOptions_AnnotationAppearance_info);
			final GridData gd= new GridData(SWT.FILL, SWT.TOP, true, false);
			gd.widthHint= 300;
			link.setLayoutData(gd);
		}
		
		LayoutUtils.addSmallFiller(pageComposite, false);
		
		// Binding
		initBindings();
		updateControls();
	}
	
	@Override
	protected void addBindings(final DataBindingSupport db) {
		db.getContext().bindValue(
				WidgetProperties.selection().observe(this.spellEnableControl),
				createObservable(WIKIDOC_SPELLCHECK_ENABLED_PREF) );
	}
	
}
