/*=============================================================================#
 # Copyright (c) 2012, 2017 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.WritableSet;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.viewers.CheckboxTableViewer;
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.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.LayoutUtil;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils;

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) {
			element.setText(Messages.Items_Remove_label);
			element.setTooltip(Messages.Items_RemoveSelected_label);
		}
		
	}
	
	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 WritableSet 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); //$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(
				ViewersObservables.observeCheckedElements(this.valueListViewer, Object.class),
				this.selectedValueSet,
				new UpdateSetStrategy().setConverter(UI2RStoreConverter.INSTANCE),
				new UpdateSetStrategy().setConverter(RStore2UIConverter.INSTANCE) );
	}
	
	@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 * LayoutUtil.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;
		}
	}
	
}
