/*=============================================================================#
 # Copyright (c) 2012, 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.datafilterview;

import static org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem.NO_COMMAND_ID;

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.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
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.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.commands.IElementUpdater;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.menus.CommandContributionItem;
import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.ui.menus.UIElement;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.Page;

import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.DNDUtils;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;

import org.eclipse.statet.base.ui.contentfilter.IFilterPage;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.internal.r.ui.dataeditor.RDataEditor;
import org.eclipse.statet.internal.r.ui.dataeditor.RDataTableContentDescription;
import org.eclipse.statet.internal.r.ui.datafilter.FilterSet;
import org.eclipse.statet.internal.r.ui.datafilter.IFilterListener;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditorCommandIds;
import org.eclipse.statet.r.ui.dataeditor.IRDataTableInput;
import org.eclipse.statet.r.ui.dataeditor.IRDataTableListener;
import org.eclipse.statet.r.ui.dataeditor.RDataTableComposite;


public class RDataFilterPage extends Page implements IFilterPage {
	
	
	private static final String EXPAND_ALL_COMMAND_ID= IWorkbenchCommandConstants.NAVIGATE_EXPAND_ALL;
	private static final String COLLAPSE_ALL_COMMAND_ID= IWorkbenchCommandConstants.NAVIGATE_COLLAPSE_ALL;
	private static final String COPY_EXPR_COMMAND_ID= ISourceEditorCommandIds.COPY_ELEMENT_NAME;
	
	
	private class ExpandCollapseAllHandler extends AbstractHandler {
		
		
		private final boolean expanded;
		
		
		public ExpandCollapseAllHandler(final boolean expanded) {
			this.expanded= expanded;
		}
		
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			RDataFilterPage.this.scrollComposite.setRedraw(false);
			RDataFilterPage.this.scrollComposite.setDelayedReflow(true);
			try {
				final List<VariableComposite> variables= RDataFilterPage.this.container.getVariables();
				for (final VariableComposite variable : variables) {
					variable.setExpanded(this.expanded);
				}
			}
			finally {
				RDataFilterPage.this.scrollComposite.setDelayedReflow(false);
				RDataFilterPage.this.scrollComposite.reflow(true);
				RDataFilterPage.this.scrollComposite.setRedraw(true);
			}
			return null;
		}
		
	}
	
	private class DisableFiltersHandler extends AbstractHandler implements IElementUpdater {
		
		
		public DisableFiltersHandler() {
		}
		
		
		@Override
		public void updateElement(final UIElement element, final Map parameters) {
			WorkbenchUIUtils.aboutToUpdateCommandsElements(this, element);
			try {
				final FilterSet filterSet= RDataFilterPage.this.container.getFilterSet();
				element.setChecked(!filterSet.getEnabled());
			}
			finally {
				WorkbenchUIUtils.finalizeUpdateCommandsElements(this);
			}
		}
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			final FilterSet filterSet= RDataFilterPage.this.container.getFilterSet();
			filterSet.setEnabled(!filterSet.getEnabled());
			return null;
		}
		
	}
	
	private class CopyFilterExpr extends AbstractHandler {
		
		
		public CopyFilterExpr() {
		}
		
		
		@Override
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			final FilterSet filterSet= RDataFilterPage.this.container.getFilterSet();
			final String rExpression= filterSet.getFilterRExpression(null, 0);
			if (rExpression != null) {
				final Clipboard clipboard= new Clipboard(RDataFilterPage.this.composite.getDisplay());
				try {
					return DNDUtils.setContent(clipboard,
							new Object[] { rExpression },
							new Transfer[] { TextTransfer.getInstance() });
				}
				finally {
					clipboard.dispose();
				}
			}
			return null;
		}
		
	}
	
	
	private Composite composite;
	
	private ScrolledPageComposite scrollComposite;
	
	private Text filterText;
	
	private VariableContainer container;
	private IFilterListener filterPostListener;
	
	private final RDataEditor editor;
	private IRDataTableListener rDataTableListener;
	
	private HandlerContributionItem disableItem;
	
	
	public RDataFilterPage(final RDataEditor editor) {
		this.editor= editor;
	}
	
	
	public RDataEditor getDataEditor() {
		return this.editor;
	}
	
	protected IDialogSettings getDialogSettings() {
		return DialogUtils.getDialogSettings(RUIPlugin.getInstance(), "RDataFilterPage"); //$NON-NLS-1$
	}
	
	@Override
	public void init(final IPageSite pageSite) {
		super.init(pageSite);
		
		final IHandlerService handlerService= pageSite.getService(IHandlerService.class);
		final IToolBarManager toolBarManager= pageSite.getActionBars().getToolBarManager();
		final IMenuManager menuManager= pageSite.getActionBars().getMenuManager();
		
		{	final IHandler2 handler= new ExpandCollapseAllHandler(true);
			handlerService.activateHandler(EXPAND_ALL_COMMAND_ID, handler);
		}
		{	final IHandler2 handler= new ExpandCollapseAllHandler(false);
			handlerService.activateHandler(COLLAPSE_ALL_COMMAND_ID, handler);
			toolBarManager.add(new HandlerContributionItem(new CommandContributionItemParameter(pageSite,
							null, COLLAPSE_ALL_COMMAND_ID, null,
							null, null, null,
							null, null, null,
							HandlerContributionItem.STYLE_PUSH, null, false),
					handler));
		}
		{	final IHandler2 handler= new DisableFiltersHandler();
			this.disableItem= new HandlerContributionItem(new CommandContributionItemParameter(pageSite,
							null, NO_COMMAND_ID, null,
							SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_DISABLE_FILTER_IMAGE_ID), null, null,
							Messages.Variables_DisableFilters_label, null, null,
							HandlerContributionItem.STYLE_CHECK, null, false),
					handler);
			toolBarManager.add(this.disableItem);
		}
		{	final IHandler2 handler= new CopyFilterExpr();
			handlerService.activateHandler(COPY_EXPR_COMMAND_ID, handler);
			menuManager.add(new CommandContributionItem(new CommandContributionItemParameter(pageSite,
					null, COPY_EXPR_COMMAND_ID, null,
					null, null, null,
					Messages.Variables_CopyExpr_label, null, null,
					CommandContributionItem.STYLE_PUSH, null, false )));
		}
	}
	
	@Override
	public void createControl(final Composite parent) {
		this.composite= new Composite(parent, SWT.NONE);
		this.composite.setLayout(LayoutUtils.newCompositeGrid(1));
		
		this.scrollComposite= new ScrolledPageComposite(this.composite, SWT.V_SCROLL);
		this.scrollComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		
		this.container= new VariableContainer(getSite(), this.scrollComposite);
		
		this.filterText= new Text(this.composite, SWT.LEFT_TO_RIGHT | SWT.READ_ONLY);
		this.filterText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		
		this.container.getFilterSet().addListener(new IFilterListener() {
			@Override
			public void filterChanged() {
				if (!UIAccess.isOkToUse(RDataFilterPage.this.filterText)) {
					return;
				}
				RDataFilterPage.this.disableItem.update();
				
				final String rExpression= RDataFilterPage.this.container.getFilterSet().getFilterRExpression();
				RDataFilterPage.this.filterText.setText((rExpression != null) ? rExpression : ""); //$NON-NLS-1$
			}
		});
		this.disableItem.update();
		
		init();
	}
	
	protected void init() {
		this.rDataTableListener= new IRDataTableListener() {
			@Override
			public void inputChanged(final IRDataTableInput input, final RDataTableContentDescription description) {
				if (description != null) {
					RDataFilterPage.this.container.updateInput(description);
				}
			}
		};
		this.editor.getRDataTable().addTableListener(this.rDataTableListener);
		this.filterPostListener= new IFilterListener() {
			@Override
			public void filterChanged() {
				final RDataTableComposite rDataTable= RDataFilterPage.this.editor.getRDataTable();
				if (!UIAccess.isOkToUse(rDataTable)) {
					return;
				}
				if (rDataTable.getDescription() == RDataFilterPage.this.container.getDescription()) {
					final FilterSet filterSet= RDataFilterPage.this.container.getFilterSet();
					if (filterSet.getEnabled()) {
						rDataTable.setFilter(RDataFilterPage.this.container.getFilterSet().getFilterRExpression());
					}
					else {
						rDataTable.setFilter(null);
					}
				}
			}
		};
		this.container.getFilterSet().addPostListener(this.filterPostListener);
	}
	
	@Override
	public Control getControl() {
		return this.composite;
	}
	
	@Override
	public void setFocus() {
		this.scrollComposite.getContent().setFocus();
	}
	
	
	@Override
	public void dispose() {
		super.dispose();
		
		RDataTableComposite rDataTable= this.editor.getRDataTable();
		if (!UIAccess.isOkToUse(rDataTable)) {
			rDataTable= null;
		}
		if (this.rDataTableListener != null && rDataTable != null) {
			rDataTable.removeTableListener(this.rDataTableListener);
			this.rDataTableListener= null;
		}
		if (this.filterPostListener != null) {
			this.container.getFilterSet().removePostListener(this.filterPostListener);
			this.filterPostListener= null;
		}
		if (rDataTable != null) {
			rDataTable.setFilter(null);
		}
		this.container.dispose();
	}
	
}
