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

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

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler2;
import org.eclipse.core.databinding.UpdateSetStrategy;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.databinding.viewers.typed.ViewerProperties;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckable;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.commands.IElementUpdater;
import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.ui.menus.UIElement;
import org.eclipse.ui.services.IServiceLocator;

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

import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.ui.actions.ControlServicesUtil;
import org.eclipse.statet.ecommons.ui.actions.HandlerCollection;
import org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem;
import org.eclipse.statet.ecommons.ui.components.DropDownButton;
import org.eclipse.statet.ecommons.ui.components.SearchText;
import org.eclipse.statet.ecommons.ui.util.AutoCheckController;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils;
import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;

import org.eclipse.statet.internal.r.ui.datafilter.TextSearchType;
import org.eclipse.statet.internal.r.ui.datafilter.TextVariableFilter;
import org.eclipse.statet.rj.data.RCharacterStore;


public class TextClient extends FilterClient {
	
	
	private class RemoveHandler extends AbstractHandler implements IElementUpdater {
		
		@Override
		public void setEnabled(final Object evaluationContext) {
			setBaseEnabled(!TextClient.this.valueListViewer.getSelection().isEmpty());
		}
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			final IStructuredSelection selection= (IStructuredSelection) TextClient.this.valueListViewer.getSelection();
			TextClient.this.filter.removeValues(selection.toList());
			updateInput();
			return null;
		}
		
		@Override
		public void updateElement(final UIElement element, final Map parameters) {
			WorkbenchUIUtils.aboutToUpdateCommandsElements(this, element);
			try {
				element.setText(Messages.Items_Remove_label);
				element.setTooltip(Messages.Items_RemoveSelected_label);
			}
			finally {
				WorkbenchUIUtils.finalizeUpdateCommandsElements(this);
			}
		}
		
	}
	
	private class RemoveUncheckedHandler extends AbstractHandler {
		
		@Override
		public void setEnabled(final Object evaluationContext) {
			setBaseEnabled(TextClient.this.availableValues.getLength() > TextClient.this.selectedValueSet.size());
		}
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			final List<String> values= new ArrayList<>((int) TextClient.this.availableValues.getLength() - TextClient.this.selectedValueSet.size());
			for (int i= 0; i < TextClient.this.availableValues.getLength(); i++) {
				final String value= TextClient.this.availableValues.get(i);
				if (!TextClient.this.selectedValueSet.contains(value)) {
					values.add(value);
				}
			}
			TextClient.this.filter.removeValues(values);
			updateInput();
			return null;
		}
		
	}
	
	private class RemoveAllHandler extends AbstractHandler {
		
		@Override
		public void setEnabled(final Object evaluationContext) {
			setBaseEnabled(TextClient.this.availableValues.getLength() > 0);
		}
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			TextClient.this.filter.removeAllValues();
			updateInput();
			return null;
		}
		
	}
	
	
	private SearchText searchTextControl;
	private DropDownButton searchButtonControl;
	private MenuItem[] searchMenuItems;
	
	private TextSearchType searchType;
	
	private CheckboxTableViewer valueListViewer;
	
	private RCharacterStore availableValues;
	
	private final IObservableSet<@Nullable String> selectedValueSet;
	
	private final HandlerCollection valueListHandlers= new HandlerCollection();
	private MenuManager valueListMenuManager;
	
	private final TextVariableFilter filter;
	
	
	public TextClient(final VariableComposite parent, final TextVariableFilter filter) {
		super(parent);
		
		this.filter= filter;
		filter.setListener(this);
		
		this.availableValues= filter.getAvailableValues();
		this.selectedValueSet= filter.getSelectedValues();
		this.searchType= TextSearchType.ECLIPSE;
		init(2);
	}
	
	
	@Override
	public TextVariableFilter getFilter() {
		return this.filter;
	}
	
	@Override
	protected void addWidgets() {
		this.searchTextControl= new SearchText(this, "", SWT.FLAT | SWT.BORDER); //$NON-NLS-1$
		this.searchTextControl.addListener(new SearchText.Listener() {
			@Override
			public void textChanged(final boolean user) {
			}
			@Override
			public void okPressed() {
				search(null);
			}
			@Override
			public void downPressed() {
			}
		});
		this.searchTextControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		
		this.searchButtonControl= new DropDownButton(this, SWT.FLAT);
		this.searchButtonControl.setText(Messages.Items_Search_label);
		{	final GridData gd= new GridData(SWT.FILL, SWT.CENTER, false, false);
			gd.heightHint= this.searchButtonControl.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
			final int textHeight= this.searchTextControl.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
			if (gd.heightHint - textHeight > 2) {
				gd.heightHint= textHeight + 2;
			}
			this.searchButtonControl.setLayoutData(gd);
		}
		this.searchButtonControl.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(final SelectionEvent e) {
				search(null);
			}
		});
		{	final Menu searchMenu= this.searchButtonControl.getDropDownMenu();
			final List<TextSearchType> searchTypes= TextSearchType.TYPES;
			this.searchMenuItems= new MenuItem[searchTypes.size()];
			final Listener searchTypeListener= new Listener() {
				@Override
				public void handleEvent(final Event event) {
					search((TextSearchType) event.widget.getData());
				}
			};
			for (int id= 0; id < searchTypes.size(); id++) {
				final TextSearchType type= searchTypes.get(id);
				final MenuItem item= new MenuItem(searchMenu, SWT.RADIO);
				item.setText(type.getLabel());
				item.setData(type);
				item.addListener(SWT.Selection, searchTypeListener);
				this.searchMenuItems[id]= item;
			}
		}
		setSearchType(this.searchType);
		
		this.valueListViewer= CheckboxTableViewer.newCheckList(this, SWT.MULTI | SWT.FLAT | SWT.FULL_SELECTION);
		this.valueListViewer.setContentProvider(new RStoreContentProvider());
		this.valueListViewer.setLabelProvider(new ColumnLabelProvider(this.filter.getColumn()));
	}
	
	@Override
	protected void initActions(final IServiceLocator serviceLocator) {
		final ControlServicesUtil servicesUtil= new ControlServicesUtil(serviceLocator,
				getClass().getName()+"/ValueList#"+hashCode(), this ); //$NON-NLS-1$
		servicesUtil.addControl(this.valueListViewer.getTable());
		
		final AutoCheckController<?> autoCheckController= new AutoCheckController<>(
				this.valueListViewer, this.selectedValueSet );
		{	final IHandler2 handler= autoCheckController.createSelectAllHandler();
			this.valueListHandlers.add(SELECT_ALL_COMMAND_ID, handler);
			servicesUtil.activateHandler(SELECT_ALL_COMMAND_ID, handler);
		}
		{	final IHandler2 handler= new RemoveHandler();
			this.valueListHandlers.add(REMOVE_COMMAND_ID, handler);
			servicesUtil.activateHandler(IWorkbenchCommandConstants.EDIT_DELETE, handler);
		}
		{	final IHandler2 handler= new RemoveUncheckedHandler();
			this.valueListHandlers.add(REMOVE_UNCHECKED_HANDLER_ID, handler);
		}
		{	final IHandler2 handler= new RemoveAllHandler();
			this.valueListHandlers.add(REMOVE_ALL_HANDLER_COMMAND_ID, handler);
		}
		
		ViewerUtils.installSearchTextNavigation(this.valueListViewer, this.searchTextControl, true);
		
		this.valueListMenuManager= new MenuManager();
		this.valueListMenuManager.add(new HandlerContributionItem(new CommandContributionItemParameter(serviceLocator,
						null, SELECT_ALL_COMMAND_ID, HandlerContributionItem.STYLE_PUSH),
				this.valueListHandlers.get(SELECT_ALL_COMMAND_ID) ));
		this.valueListMenuManager.add(new Separator());
		this.valueListMenuManager.add(new HandlerContributionItem(new CommandContributionItemParameter(serviceLocator,
						null, REMOVE_COMMAND_ID, HandlerContributionItem.STYLE_PUSH),
				this.valueListHandlers.get(REMOVE_COMMAND_ID) ));
		this.valueListMenuManager.add(new HandlerContributionItem(new CommandContributionItemParameter(serviceLocator,
						null, HandlerContributionItem.NO_COMMAND_ID, null,
						null, null, null,
						Messages.Items_RemoveUnchecked_label, null, "Remove unchecked items",
						HandlerContributionItem.STYLE_PUSH, null, false),
				this.valueListHandlers.get(REMOVE_UNCHECKED_HANDLER_ID) ));
		this.valueListMenuManager.add(new HandlerContributionItem(new CommandContributionItemParameter(serviceLocator,
						null, HandlerContributionItem.NO_COMMAND_ID, null,
						null, null, null,
						Messages.Items_RemoveAll_label, null, "Remove all items",
						HandlerContributionItem.STYLE_PUSH, null, false),
				this.valueListHandlers.get(REMOVE_ALL_HANDLER_COMMAND_ID) ));
		this.valueListViewer.getTable().setMenu(this.valueListMenuManager.createContextMenu(this.valueListViewer.getControl()));
		
		this.valueListViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(final SelectionChangedEvent event) {
				updateActions();
			}
		});
		updateActions();
	}
	
	@Override
	protected void addBindings(final DataBindingSupport db) {
		db.getContext().bindSet(
				ViewerProperties.checkedElements(Object.class)
						.observe((ICheckable)this.valueListViewer),
				this.selectedValueSet,
				new UpdateSetStrategy<Object, @Nullable String>()
						.setConverter(new UI2RStoreConverter<String>()),
				new UpdateSetStrategy<@Nullable String, Object>()
						.setConverter(new RStore2UIConverter<String>()) );
	}
	
	@Override
	protected void updateInput() {
		this.availableValues= this.filter.getAvailableValues();
		this.valueListViewer.setInput(this.availableValues);
		
		updateActions();
		if (updateLayout()) {
			getParent().layout(new Control[] { this });
		}
	}
	
	protected void updateActions() {
		this.valueListHandlers.get(REMOVE_COMMAND_ID).setEnabled(null);
	}
	
	@Override
	protected boolean updateLayout() {
		return updateLayout(this.valueListViewer, (int) this.availableValues.getLength());
	}
	
	@Override
	protected int getMinHeightPadding() {
		return this.searchTextControl.getSize().y + 20 + 10 * LayoutUtils.defaultVSpacing();
	}
	
	protected void setSearchType(final TextSearchType type) {
		this.searchType= type;
		for (int id= 0; id < this.searchMenuItems.length; id++) {
			this.searchMenuItems[id].setSelection(type.getId() == id);
		}
		this.searchButtonControl.setToolTipText(type.getLabel());
	}
	
	private void search(TextSearchType type) {
		if (type != null) {
			if (this.searchType != type) {
				setSearchType(type);
			}
		}
		else {
			type= this.searchType;
		}
		final String text= this.searchTextControl.getText();
		this.filter.search(type, text);
	}
	
	@Override
	protected void onDispose() {
		if (this.valueListMenuManager != null) {
			this.valueListMenuManager.dispose();
			this.valueListMenuManager= null;
		}
	}
	
}
