/*=============================================================================#
 # Copyright (c) 2012, 2020 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.rtm.base.ui.rexpr;

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

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.IObserving;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.databinding.IEMFObservable;
import org.eclipse.emf.databinding.edit.EMFEditProperties;
import org.eclipse.emf.databinding.edit.IEMFEditListProperty;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.MoveCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ecommons.emf.core.IContext;
import org.eclipse.statet.ecommons.emf.core.databinding.IEMFEditContext;
import org.eclipse.statet.ecommons.emf.core.databinding.IEMFEditPropertyContext;
import org.eclipse.statet.ecommons.emf.ui.forms.EFProperty;
import org.eclipse.statet.ecommons.emf.ui.forms.IEFFormPage;
import org.eclipse.statet.ecommons.ui.components.ButtonGroup;
import org.eclipse.statet.ecommons.ui.content.ElementSourceSelectionProvider;
import org.eclipse.statet.ecommons.ui.util.SelectionTransferDragAdapter;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils.TableComposite;

import org.eclipse.statet.rtm.base.ui.editors.RtFormToolkit;
import org.eclipse.statet.rtm.base.util.RExprTypes;
import org.eclipse.statet.rtm.rtdata.types.RTypedExpr;


public class RExprListProperty extends EFProperty implements ButtonGroup.IActions<RTypedExpr> {
	
	
	private class RExprEditing extends ObservableValueEditingSupport<RTypedExpr, RTypedExpr, String> {
		
		
		private CellEditor cellEditor;
		
		
		public RExprEditing() {
			super(RExprListProperty.this.widget.viewer, RExprListProperty.this.getDataBindingContext());
		}
		
		
		@Override
		protected CellEditor getCellEditor(final Object element) {
			if (element instanceof RTypedExpr) {
				if (this.cellEditor == null) {
					this.cellEditor= createRExprCellEditor();
				}
				return this.cellEditor;
			}
			return null;
		}
		
		protected CellEditor createRExprCellEditor() {
			final TextCellEditor editor= new TextCellEditor((Composite) getViewer().getControl());
//			editor.setValidator(new RIdentifierCellValidator());
			return editor;
		}
		
		@Override
		protected IObservableValue<String> doCreateCellEditorObservable(final CellEditor cellEditor) {
			return WidgetProperties.text(SWT.Modify)
					.observe(((TextCellEditor)this.cellEditor).getControl());
		}
		
		@Override
		protected Binding createBinding(final IObservableValue<String> target, final IObservableValue<RTypedExpr> model) {
			return getDataBindingContext().bindValue(
					target,
					model,
					new UpdateValueStrategy<String, @Nullable RTypedExpr>(UpdateValueStrategy.POLICY_CONVERT)
							.setConverter(new String2RTypedExprConverter(RExprListProperty.this.types.getDefaultTypeKey())),
					new UpdateValueStrategy<@Nullable RTypedExpr, String>()
							.setConverter(new RExpr2StringConverter()) );
		}
		
		@Override
		protected IObservableValue<RTypedExpr> doCreateElementObservable(final RTypedExpr element, final ViewerCell cell) {
			return new AbstractObservableValue<RTypedExpr>() {
				RTypedExpr value= element;
				@Override
				public Object getValueType() {
					return RTypedExpr.class;
				}
				@Override
				protected RTypedExpr doGetValue() {
					return this.value;
				}
				@Override
				protected void doSetValue(final @Nullable RTypedExpr value) {
					final int index= getIndex(value);
					final CommandStack commandStack= getEditingDomain().getCommandStack();
					final IEMFObservable emfObservable= (IEMFObservable) RExprListProperty.this.modelObservable;
					Command command;
					if (value == null) {
						if (index >= 0) {
							RExprListProperty.this.modelObservable.remove(index);
						}
						return;
					}
					else {
						if (index >= 0) {
							command= SetCommand.create(getEditingDomain(),
									emfObservable.getObserved(), getEFeature(),
									value, index );
	//						this.modelObservable.set(index, value);
						}
						else {
	//						command= AddCommand.create(this.context.getEditingDomain(),
	//								emfObservable.getObserved(), emfObservable.getStructuralFeature(),
	//								value );
							RExprListProperty.this.modelObservable.add(value);
							return;
						}
					}
					commandStack.execute(command);
				}
			};
		}
		
	}
	
	
	private final IRExprTypesUIProvider provider;
	private final RExprTypes types;
	private List<RExprTypeUIAdapter> typeUIAdapters;
	
	private TableComposite widget;
	private ButtonGroup<RTypedExpr> buttonGroup;
	
	private IObservableList<RTypedExpr> modelObservable;
	
	
	public RExprListProperty(final String label, final String tooltip,
			final EClass eClass, final EStructuralFeature eFeature,
			final IRExprTypesUIProvider provider) {
		super(label, tooltip, eClass, eFeature);
		
		this.provider= provider;
		this.types= provider.getTypes(getEClass(), getEFeature());
	}
	
	
	protected IRExprTypesUIProvider getProvider() {
		return this.provider;
	}
	
	@Override
	public void create(final Composite parent, final IEFFormPage page) {
		final IRExprTypesUIProvider provider= getProvider();
		this.typeUIAdapters= provider.getUIAdapters(this.types, getEClass(), getEFeature() );
		final RtFormToolkit toolkit= (RtFormToolkit) page.getToolkit();
		
		toolkit.createPropLabel(parent, getLabel(), getTooltip(), 3);
		
		this.widget= toolkit.createPropSingleColumnTable(parent, 6, 25);
		
		this.widget.viewer.setContentProvider(new ObservableListContentProvider());
		final ViewerColumn column= this.widget.getViewerColumn(0);
		column.setLabelProvider(new RExprLabelProvider(this.typeUIAdapters));
		
		this.buttonGroup= new ButtonGroup<>(parent, this, true);
		this.buttonGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
		
		customizeButtonGroup(this.buttonGroup);
	}
	
	protected void customizeButtonGroup(final ButtonGroup<RTypedExpr> buttonGroup) {
		buttonGroup.addAddButton(null);
		buttonGroup.addDeleteButton(null);
		buttonGroup.addSeparator();
		buttonGroup.addUpButton(null);
		buttonGroup.addDownButton(null);
	}
	
	@Override
	public Control getControl() {
		return this.widget;
	}
	
	public TableViewer getViewer() {
		return this.widget.viewer;
	}
	
	
	@Override
	public RTypedExpr edit(final int command, final RTypedExpr item, final Object parent) {
		switch(command) {
		case ButtonGroup.ADD_NEW:
			return new RTypedExpr(this.types.getDefaultTypeKey(), ""); //$NON-NLS-1$
		case ButtonGroup.EDIT:
			return item;
		default:
			return null;
		}
	}
	
	@Override
	public void updateState(final IStructuredSelection selection) {
	}
	
	@Override
	public void bind(final IEMFEditContext context) {
		super.bind(context);
		
		final IEMFEditListProperty emfProperty= EMFEditProperties.list(getEditingDomain(),
				getEFeature() );
		this.modelObservable= emfProperty.observeDetail(getBaseObservable());
		
		this.widget.viewer.setInput(this.modelObservable);
		this.buttonGroup.connectTo(this.widget.viewer, this.modelObservable, null);
		
		final ViewerColumn column= this.widget.getViewerColumn(0);
		column.setEditingSupport(new RExprEditing());
		ViewerUtils.installDefaultEditBehaviour2(this.widget.viewer);
		
		final ElementSourceSelectionProvider extSelectionProvider= new ElementSourceSelectionProvider(
				this.widget.viewer, this );
		{	final int operations= (DND.DROP_DEFAULT | DND.DROP_COPY | DND.DROP_MOVE);
			final Transfer[] transfers= new Transfer[] { LocalSelectionTransfer.getTransfer() };
			this.widget.viewer.addDragSupport(operations, transfers, new SelectionTransferDragAdapter(
					extSelectionProvider ));
			this.widget.viewer.addDropSupport(operations, transfers, new RExprViewerDropAdapter(
					this.widget.viewer, this.typeUIAdapters, this ) {
				@Override
				protected boolean canMove(final IContext source, final Object input) {
					final IEMFEditPropertyContext sourcePropertyContext= source.getAdapter(IEMFEditPropertyContext.class);
					return (sourcePropertyContext != null
							&& getEditingDomain() == sourcePropertyContext.getEditingDomain());
				}
				@Override
				protected int getIndex(final Object element) {
					return RExprListProperty.this.modelObservable.indexOf(element);
				}
				@Override
				protected void insertExprs(final List<RTypedExpr> exprs, final int index, final int time) {
					if (index >= 0) {
						RExprListProperty.this.modelObservable.addAll(index, exprs);
					}
					else {
						RExprListProperty.this.modelObservable.addAll(exprs);
					}
				}
				@Override
				protected void moveExprs(final IContext source, final List<RTypedExpr> exprs, final int index, final int time) {
					final IEMFEditPropertyContext sourceContext= (IEMFEditPropertyContext) source;
					
					final EObject owner= (EObject) ((IObserving) RExprListProperty.this.modelObservable).getObserved();
					final IObservable sourceObservable= sourceContext.getPropertyObservable();
					if (owner == null || sourceObservable == null) {
						return;
					}
					Command command;
					
					if (sourceObservable == RExprListProperty.this.modelObservable) {
						if (exprs.size() == 1) {
							final RTypedExpr expr= exprs.get(0);
							final int oldIndex= getIndex(expr);
							if (oldIndex < 0) {
								return;
							}
							command= MoveCommand.create(getEditingDomain(),
									owner, getEFeature(), expr, (oldIndex < index) ? index - 1 : index );
						}
						else {
							final CompoundCommand compound= new CompoundCommand();
							final List<RTypedExpr> after= new ArrayList<>(exprs.size());
							for (final RTypedExpr expr : exprs) {
								final int oldIndex= getIndex(expr);
								if (oldIndex < 0) {
									continue;
								}
								if (oldIndex < index) {
									compound.append(MoveCommand.create(getEditingDomain(),
											owner, getEFeature(), expr, index - 1 ));
								}
								else {
									after.add(expr);
								}
							}
							for (final RTypedExpr expr : after) {
								compound.append(MoveCommand.create(getEditingDomain(),
										owner, getEFeature(), expr, index ));
							}
							command= compound;
						}
					}
					else {
						final EObject oldOwner= (EObject) ((IObserving) sourceObservable).getObserved();
						final CompoundCommand compound= new CompoundCommand();
						compound.append(AddCommand.create(getEditingDomain(),
								owner, getEFeature(), exprs));
						compound.append(RemoveCommand.create(getEditingDomain(),
								oldOwner, sourceContext.getEFeature(), exprs));
						command= compound;
					}
					
					getEditingDomain().getCommandStack().execute(command);
				}
			});
		}
		
		if (!this.modelObservable.isEmpty()) {
			this.widget.viewer.setSelection(new StructuredSelection(this.modelObservable.get(0)));
		}
		else {
			this.buttonGroup.updateState();
		}
	}
	
	protected int getIndex(final Object element) {
		for (int i= 0; i < this.modelObservable.size(); i++) {
			if (this.modelObservable.get(i) == element) {
				return i;
			}
		}
		return this.modelObservable.indexOf(element);
	}
	
	@Override
	public IObservableList getPropertyObservable() {
		return this.modelObservable;
	}
	
}
