/*=============================================================================#
 # 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.r.ui.preferences;

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

import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.core.databinding.observable.set.WritableSet;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;

import org.eclipse.statet.jcommons.collections.ImCollections;

import org.eclipse.statet.ecommons.preferences.core.Preference;
import org.eclipse.statet.ecommons.preferences.core.Preference.StringArrayPref;
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.components.EditableTextList;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.viewers.ComparatorViewerComparator;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils.TableComposite;

import org.eclipse.statet.internal.r.ui.RIdentifierCellValidator;
import org.eclipse.statet.internal.r.ui.RIdentifierGroups;
import org.eclipse.statet.r.core.RSymbolComparator;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.r.ui.RUIPreferenceConstants;


/**
 * Preference page for 'R Editor Options'
 */
public class RIdentifiersPreferencePage extends ConfigurationBlockPreferencePage {
	
	
	public RIdentifiersPreferencePage() {
	}
	
	
	@Override
	protected ConfigurationBlock createConfigurationBlock() {
		return new RIdentifiersBlock(createStatusChangedListener());
	}
	
}


class RIdentifiersBlock extends ManagedConfigurationBlock {
	
	
	private class Category {
		
		private final String label;
		
		private final StringArrayPref pref;
		
		private final IObservableSet<String> set= new WritableSet<>();
		
		public Category(final String label, final String prefKey) {
			this.label= label;
			this.pref= new StringArrayPref(RUI.BUNDLE_ID, prefKey);
		}
		
		void load() {
			this.set.clear();
			final String[] words= getPreferenceValue(this.pref);
			if (words != null) {
				this.set.addAll(ImCollections.newList(words));
			}
		}
		
		void save() {
			setPrefValue(this.pref, this.set.toArray(new String[this.set.size()]));
		}
		
		@Override
		public String toString() {
			return this.label;
		}
		
	}
	
	private class WordEditing extends EditingSupport {
		
		private final TextCellEditor cellEditor;
		
		private final EditableTextList list;
		
		private Object last;
		
		public WordEditing(final EditableTextList list) {
			super(list.getViewer());
			this.list= list;
			this.cellEditor= new TextCellEditor(list.getViewer().getTable());
			this.cellEditor.addListener(new ICellEditorListener() {
				@Override
				public void editorValueChanged(final boolean oldValidState, final boolean newValidState) {
					if (!newValidState) {
						RIdentifiersBlock.this.statusListener.statusChanged(new Status(Status.ERROR, RUI.BUNDLE_ID, WordEditing.this.cellEditor.getErrorMessage()));
					}
					else {
						RIdentifiersBlock.this.statusListener.statusChanged(Status.OK_STATUS);
					}
				}
				@Override
				public void applyEditorValue() {
					WordEditing.this.last= null;
					RIdentifiersBlock.this.statusListener.statusChanged(Status.OK_STATUS);
				}
				@Override
				public void cancelEditor() {
					if (WordEditing.this.last == "") { //$NON-NLS-1$
						WordEditing.this.list.applyChange("", null); //$NON-NLS-1$
					}
					RIdentifiersBlock.this.statusListener.statusChanged(Status.OK_STATUS);
				}
			});
			this.cellEditor.setValidator(new RIdentifierCellValidator() {
				@Override
				public String isValid(final Object value) {
					final String valid= super.isValid(value);
					if (valid == null) {
						if (!value.equals(WordEditing.this.last) && RIdentifiersBlock.this.activeCategory.set.contains(value)) {
							return Messages.RIdentifiers_Identifier_error_AlreadyExistingInSameGroup_message;
						}
						for (int i= 0; i < RIdentifiersBlock.this.categories.length; i++) {
							if (RIdentifiersBlock.this.categories[i] != RIdentifiersBlock.this.activeCategory && RIdentifiersBlock.this.categories[i].set.contains(value)) {
								return NLS.bind(Messages.RIdentifiers_Identifier_error_AlreadyExistingInOtherGroup_message, RIdentifiersBlock.this.categories[i].label);
							}
						}
					}
					return valid;
				}
			});
		}
		
		@Override
		protected boolean canEdit(final Object element) {
			return true;
		}
		
		@Override
		protected CellEditor getCellEditor(final Object element) {
			return this.cellEditor;
		}
		
		@Override
		protected Object getValue(final Object element) {
			this.last= element;
			return element;
		}
		
		@Override
		protected void setValue(final Object element, final Object value) {
			if (value != null) {
				this.list.applyChange(element, (value != "") ? value : null); //$NON-NLS-1$
			}
		}
		
	}
	
	private TableViewer categoryList;
	private EditableTextList wordList;
	
	private Category[] categories;
	private Category activeCategory;
	
	private final StatusChangeListener statusListener;
	
	
	public RIdentifiersBlock(final StatusChangeListener statusListener) {
		super(null, null);
		this.statusListener= statusListener;
	}
	
	
	@Override
	protected void createBlockArea(final Composite pageComposite) {
		this.categories= new Category[] {
				new Category(Messages.RSyntaxColoring_Identifier_Assignment_label, RUIPreferenceConstants.R.TS_IDENTIFIER_SUB_ASSIGNMENT_ITEMS),
				new Category(Messages.RSyntaxColoring_Identifier_Flowcontrol_label, RUIPreferenceConstants.R.TS_IDENTIFIER_SUB_FLOWCONTROL_ITEMS),
				new Category(Messages.RSyntaxColoring_Identifier_Logical_label, RUIPreferenceConstants.R.TS_IDENTIFIER_SUB_LOGICAL_ITEMS),
				new Category(Messages.RSyntaxColoring_Identifier_Custom1_label, RUIPreferenceConstants.R.TS_IDENTIFIER_SUB_CUSTOM1_ITEMS),
				new Category(Messages.RSyntaxColoring_Identifier_Custom2_label, RUIPreferenceConstants.R.TS_IDENTIFIER_SUB_CUSTOM2_ITEMS),
		};
		
		final Map<Preference<?>, String> prefs= new HashMap<>();
		
		for (int i= 0; i < this.categories.length; i++) {
			prefs.put(this.categories[i].pref, RIdentifierGroups.GROUP_ID);
		}
		
		setupPreferenceManager(prefs);
		
		// Controls
		GridData gd;
		Label label;
		TableViewerColumn column;
		
		label= new Label(pageComposite, SWT.NONE);
		label.setText(Messages.RIdentifiers_GroupsList_label);
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		
		final TableComposite categoryComposite= new ViewerUtils.TableComposite(pageComposite, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION);
		gd= new GridData(SWT.FILL, SWT.FILL, true, false);
		gd.heightHint= LayoutUtils.hintHeight(categoryComposite.table, 4);
		categoryComposite.setLayoutData(gd);
		this.categoryList= categoryComposite.viewer;
		this.categoryList.setContentProvider(new ArrayContentProvider());
		
		column= new TableViewerColumn(this.categoryList, SWT.NONE);
		column.setLabelProvider(new ColumnLabelProvider());
		categoryComposite.layout.setColumnData(column.getColumn(), new ColumnWeightData(100));
		
		label= new Label(pageComposite, SWT.NONE);
		label.setText(Messages.RIdentifiers_IdentifiersList_label);
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		
		this.wordList= new EditableTextList();
		{	final Control control= this.wordList.create(pageComposite,
					new ComparatorViewerComparator(new RSymbolComparator()) );
			control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		}
		this.wordList.getColumn().setEditingSupport(new WordEditing(this.wordList));
		
		// Binding
		this.categoryList.setInput(this.categories);
		this.categoryList.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(final SelectionChangedEvent event) {
				final Category cat= (Category) ((IStructuredSelection) event.getSelection()).getFirstElement();
				RIdentifiersBlock.this.wordList.setInput(cat.set);
				RIdentifiersBlock.this.activeCategory= cat;
			}
		});
		
		// Init
		this.activeCategory= this.categories[0];
		updateControls();
		Display.getCurrent().asyncExec(new Runnable() {
			@Override
			public void run() {
				if (UIAccess.isOkToUse(RIdentifiersBlock.this.categoryList)) {
					RIdentifiersBlock.this.categoryList.setSelection(new StructuredSelection(RIdentifiersBlock.this.activeCategory));
				}
			}
		});
	}
	
	
	@Override
	public void updatePreferences() {
		for (int i= 0; i < this.categories.length; i++) {
			this.categories[i].save();
		}
		super.updatePreferences();
	}
	
	@Override
	protected void updateControls() {
		for (int i= 0; i < this.categories.length; i++) {
			this.categories[i].load();
		}
		this.wordList.refresh();
	}
	
}
