/*=============================================================================#
 # Copyright (c) 2009, 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.redocs.wikitext.r.ui.editors;

import static org.eclipse.ui.IWorkbenchCommandConstants.NAVIGATE_EXPAND_ALL;

import static org.eclipse.statet.ecommons.ui.actions.UIActions.ADDITIONS_GROUP_ID;
import static org.eclipse.statet.ecommons.ui.actions.UIActions.VIEW_EXPAND_GROUP_ID;
import static org.eclipse.statet.ecommons.ui.actions.UIActions.VIEW_FILTER_GROUP_ID;

import java.util.Collections;
import java.util.Map;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.IHandler2;
import org.eclipse.jface.action.IMenuListener2;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.menus.CommandContributionItem;
import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.services.IServiceLocator;

import org.eclipse.statet.ecommons.ui.actions.HandlerCollection;
import org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.viewers.ViewerUtils;

import org.eclipse.statet.base.ui.IStatetUIMenuIds;
import org.eclipse.statet.docmlet.base.ui.DocmlBaseUIResources;
import org.eclipse.statet.docmlet.wikitext.core.model.IWikidocModelInfo;
import org.eclipse.statet.docmlet.wikitext.core.model.IWikitextSourceElement;
import org.eclipse.statet.docmlet.wikitext.core.model.WikitextModel;
import org.eclipse.statet.internal.redocs.wikitext.r.RedocsWikitextRPlugin;
import org.eclipse.statet.internal.redocs.wikitext.r.ui.sourceediting.DocROutlineContentProvider;
import org.eclipse.statet.ltk.model.core.elements.IEmbeddedForeignElement;
import org.eclipse.statet.ltk.model.core.elements.IModelElement;
import org.eclipse.statet.ltk.model.core.elements.IModelElement.Filter;
import org.eclipse.statet.ltk.model.core.elements.ISourceStructElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnitModelInfo;
import org.eclipse.statet.ltk.ui.sourceediting.OutlineContentProvider;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor1;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor2OutlinePage;
import org.eclipse.statet.ltk.ui.util.ViewerDragSupport;
import org.eclipse.statet.ltk.ui.util.ViewerDropSupport;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.launching.RCodeLaunching;
import org.eclipse.statet.redocs.r.ui.RedocsRUIResources;
import org.eclipse.statet.redocs.wikitext.r.ui.WikitextRweaveLabelProvider;


public class WikidocRweaveOutlinePage extends SourceEditor2OutlinePage {
	
	
	private static final String EXPAND_ELEMENTS_COMMAND_ID= "org.eclipse.statet.workbench.commands.ExpandElements"; //$NON-NLS-1$
	
	
	private static boolean isRChunk(final IModelElement element) {
		if (element instanceof IEmbeddedForeignElement) {
			final ISourceStructElement foreignElement= ((IEmbeddedForeignElement) element).getForeignElement();
			if (foreignElement != null && foreignElement.getModelTypeId() == RModel.R_TYPE_ID) {
				return true;
			}
		}
		return false;
	}
	
	
	private static Map<String, String> H2_PARAMETERS= Collections.singletonMap("type", "h2"); //$NON-NLS-1$ //$NON-NLS-2$
	private static Map<String, String> H3_PARAMETERS= Collections.singletonMap("type", "h3"); //$NON-NLS-1$ //$NON-NLS-2$
	private static Map<String, String> H4_PARAMETERS= Collections.singletonMap("type", "h4"); //$NON-NLS-1$ //$NON-NLS-2$
	private static Map<String, String> RCHUNK_PARAMETERS= Collections.singletonMap("type", "rchunks"); //$NON-NLS-1$ //$NON-NLS-2$
	
	
	private class FilterRChunks extends AbstractToggleHandler {
		
		public FilterRChunks() {
			super("filter.r_chunks.enabled", false, null, 0); //$NON-NLS-1$
		}
		
		@Override
		protected void apply(final boolean on) {
			final TreeViewer viewer= getViewer();
			WikidocRweaveOutlinePage.this.filter.hideRChunks= on;
			if (UIAccess.isOkToUse(viewer)) {
				viewer.refresh(false);
			}
		}
		
	}
	
	public class ExpandElementsContributionItem extends HandlerContributionItem {
		
		private final IHandler2 expandElementsHandler;
		
		public ExpandElementsContributionItem(
				final IServiceLocator serviceLocator, final HandlerCollection handlers) {
			super(new CommandContributionItemParameter(serviceLocator,
					".ExpandElements", NAVIGATE_EXPAND_ALL, null, //$NON-NLS-1$
					null, null, null,
					"Expand All", "E", null,
					HandlerContributionItem.STYLE_PULLDOWN, null, false ),
					handlers.get(NAVIGATE_EXPAND_ALL) );
			this.expandElementsHandler= handlers.get(EXPAND_ELEMENTS_COMMAND_ID);
		}
		
		
		@Override
		protected void initDropDownMenu(final MenuManager menuManager) {
			menuManager.addMenuListener(new IMenuListener2() {
				@Override
				public void menuAboutToShow(final IMenuManager manager) {
					final TreeViewer viewer= getViewer();
					if (viewer == null) {
						return;
					}
					
					final IWikidocModelInfo modelInfo= getCurrentInputModel();
					final DocmlBaseUIResources baseResources= DocmlBaseUIResources.INSTANCE;
					final RedocsRUIResources redocsResources= RedocsRUIResources.INSTANCE;
					if (modelInfo.getMinSectionLevel() > 0) {
						if (modelInfo.getMinSectionLevel() < 2
								&& modelInfo.getMaxSectionLevel() >= 2) {
							manager.add(new HandlerContributionItem(new CommandContributionItemParameter(
									getSite(), null, EXPAND_ELEMENTS_COMMAND_ID, H2_PARAMETERS,
									baseResources.getImageDescriptor(DocmlBaseUIResources.OBJ_HEADING2_IMAGE_ID), null, null,
									"Show all H2 sections", "C", null,
									HandlerContributionItem.STYLE_PUSH, null, false ),
									ExpandElementsContributionItem.this.expandElementsHandler ));
						}
						if (modelInfo.getMinSectionLevel() < 3
								&& modelInfo.getMaxSectionLevel() >= 3) {
							manager.add(new HandlerContributionItem(new CommandContributionItemParameter(
									getSite(), null, EXPAND_ELEMENTS_COMMAND_ID, H3_PARAMETERS,
									baseResources.getImageDescriptor(DocmlBaseUIResources.OBJ_HEADING3_IMAGE_ID), null, null,
									"Show all H3 sections", "S", null,
									HandlerContributionItem.STYLE_PUSH, null, false ),
									ExpandElementsContributionItem.this.expandElementsHandler ));
						}
						if (modelInfo.getMinSectionLevel() < 4
								&& modelInfo.getMaxSectionLevel() >= 4) {
							manager.add(new HandlerContributionItem(new CommandContributionItemParameter(
									getSite(), null, EXPAND_ELEMENTS_COMMAND_ID, H4_PARAMETERS,
									baseResources.getImageDescriptor(DocmlBaseUIResources.OBJ_HEADING4_IMAGE_ID), null, null,
									"Show all H4 sections", "u", null,
									HandlerContributionItem.STYLE_PUSH, null, false ),
									ExpandElementsContributionItem.this.expandElementsHandler ));
							manager.add(new Separator());
						}
					}
					if (!WikidocRweaveOutlinePage.this.filter.hideRChunks) {
						manager.add(new HandlerContributionItem(new CommandContributionItemParameter(
								getSite(), null, EXPAND_ELEMENTS_COMMAND_ID, RCHUNK_PARAMETERS,
								redocsResources.getImageDescriptor(RedocsRUIResources.OBJ_RCHUNK_IMAGE_ID), null, null,
								"Show all R Chunks", "R", null,
								HandlerContributionItem.STYLE_PUSH, null, false ),
								ExpandElementsContributionItem.this.expandElementsHandler ));
					}
				}
				@Override
				public void menuAboutToHide(final IMenuManager manager) {
					ExpandElementsContributionItem.this.display.asyncExec(new Runnable() {
						@Override
						public void run() {
							menuManager.dispose();
						}
					});
				}
			});
		}
		
	}
	
	public class ExpandElementsHandler extends AbstractHandler {
		
		public ExpandElementsHandler() {
		}
		
		@Override
		public Object execute(final ExecutionEvent event) {
			final TreeViewer viewer= getViewer();
			final String type= event.getParameter("type");
			if (UIAccess.isOkToUse(viewer) && type != null) {
				final ISourceUnitModelInfo modelInfo= getModelInfo(viewer.getInput());
				if (modelInfo == null) {
					return null;
				}
				final Filter contentFilter= getContentFilter();
				final Filter expandFilter;
				if (type.equals("rchunks")) {
					expandFilter= new Filter() {
						@Override
						public boolean include(final IModelElement element) {
							if (contentFilter.include(element)) {
								if ((element.getElementType() & IModelElement.MASK_C1) == IWikitextSourceElement.C1_EMBEDDED
										&& isRChunk(element)) {
									ViewerUtils.expandToLevel(viewer, element, 0);
									return false;
								}
								((ISourceStructElement) element).hasSourceChildren(this);
								return false;
							}
							return false;
						}
					};
				}
				else {
					final int sectionLevel;
					if (type.equals("h2")) { //$NON-NLS-1$
						sectionLevel= 2;
					}
					else if (type.equals("h3")) { //$NON-NLS-1$
						sectionLevel= 3;
					}
					else if (type.equals("h4")) { //$NON-NLS-1$
						sectionLevel= 4;
					}
					else if (type.equals("h5")) { //$NON-NLS-1$
						sectionLevel= 5;
					}
					else if (type.equals("h6")) { //$NON-NLS-1$
						sectionLevel= 6;
					}
					else {
						sectionLevel= 0;
					}
					if (sectionLevel < 1 || sectionLevel > 6) {
						return null;
					}
					expandFilter= new Filter() {
						private boolean childExpand;
						@Override
						public boolean include(final IModelElement element) {
							if (contentFilter.include(element)
									&& (element.getElementType() & IModelElement.MASK_C2) == IWikitextSourceElement.C2_SECTIONING) {
								final int currentLevel= (element.getElementType() & 0xf);
								if (currentLevel < 1 || currentLevel > sectionLevel) {
									return false; // nothing to do
								}
								if (currentLevel < sectionLevel) {
									this.childExpand= false;
									((ISourceStructElement) element).hasSourceChildren(this);
									if (this.childExpand) {
										return false; // done
									}
								}
								// expand
								ViewerUtils.expandToLevel(viewer, element, 0);
								this.childExpand= true;
								return false;
							}
							return false;
						}
					};
				}
				modelInfo.getSourceElement().hasSourceChildren(expandFilter);
			}
			return null;
		}
	}
	
	
	private class ContentFilter implements IModelElement.Filter {
		
		private boolean hideRChunks;
		
		@Override
		public boolean include(final IModelElement element) {
			switch ((element.getElementType() & IModelElement.MASK_C1)) {
			case IWikitextSourceElement.C1_EMBEDDED:
				if (isRChunk(element)) {
					return !this.hideRChunks;
				}
			}
			return true;
		}
		
	}
	
	
	private final ContentFilter filter= new ContentFilter();
	
	
	public WikidocRweaveOutlinePage(final SourceEditor1 editor) {
		super(editor, WikitextModel.WIKIDOC_TYPE_ID, WikidocRweaveRefactoringFactory.getInstance(),
				"org.eclipse.statet.docmlet.menus.WikidocOutlineViewContextMenu"); //$NON-NLS-1$
	}
	
	
	@Override
	protected IDialogSettings getDialogSettings() {
		return DialogUtils.getDialogSettings(RedocsWikitextRPlugin.getInstance(), "WikidocRweaveOutlineView"); //$NON-NLS-1$
	}
	
	@Override
	protected OutlineContentProvider createContentProvider() {
		return new DocROutlineContentProvider(new OutlineContent());
	}
	
	@Override
	protected IModelElement.Filter getContentFilter() {
		return this.filter;
	}
	
	@Override
	protected void configureViewer(final TreeViewer viewer) {
		super.configureViewer(viewer);
		
		viewer.setLabelProvider(new WikitextRweaveLabelProvider(0));
		
		final ViewerDropSupport drop= new ViewerDropSupport(viewer, this,
				getRefactoringFactory() );
		drop.init();
		final ViewerDragSupport drag= new ViewerDragSupport(viewer);
		drag.init();
	}
	
	@Override
	protected void initActions(final IServiceLocator serviceLocator,
			final HandlerCollection handlers) {
		super.initActions(serviceLocator, handlers);
		
		final IHandlerService handlerService= serviceLocator.getService(IHandlerService.class);
		
		handlers.add(".FilterRChunks", new FilterRChunks()); //$NON-NLS-1$
		
		{	final IHandler2 handler= new ExpandElementsHandler();
			handlers.add(EXPAND_ELEMENTS_COMMAND_ID, handler);
//			handlerService.activateHandler(EXPAND_ELEMENTS_COMMAND_ID, handler); //$NON-NLS-1$
		}
	}
	
	@Override
	protected void contributeToActionBars(final IServiceLocator serviceLocator,
			final IActionBars actionBars, final HandlerCollection handlers) {
		super.contributeToActionBars(serviceLocator, actionBars, handlers);
		
		final IToolBarManager toolBarManager= actionBars.getToolBarManager();
		final RedocsRUIResources redocsResources= RedocsRUIResources.INSTANCE;
		
		toolBarManager.appendToGroup(VIEW_EXPAND_GROUP_ID,
				new ExpandElementsContributionItem(serviceLocator, handlers));
		
//		toolBarManager.appendToGroup(ECommonsUI.VIEW_SORT_MENU_ID,
//				new AlphaSortAction());
		toolBarManager.appendToGroup(VIEW_FILTER_GROUP_ID,
				new HandlerContributionItem(new CommandContributionItemParameter(serviceLocator,
						null, HandlerContributionItem.NO_COMMAND_ID, null,
						redocsResources.getImageDescriptor(RedocsRUIResources.LOCTOOL_FILTERCHUNKS_IMAGE_ID), null, null,
						"Hide R Chunks", "R", null,
						HandlerContributionItem.STYLE_CHECK, null, false ),
						handlers.get(".FilterRChunks") ) ); //$NON-NLS-1$
//		toolBarManager.appendToGroup(ECommonsUI.VIEW_FILTER_MENU_ID,
//				new FilterLocalDefinitions());
	}
	
	@Override
	protected void contextMenuAboutToShow(final IMenuManager m) {
		super.contextMenuAboutToShow(m);
		final IPageSite site= getSite();
		
		if (m.find(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID) == null) {
			m.insertBefore(ADDITIONS_GROUP_ID,
					new Separator(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID) );
		}
		
		m.appendToGroup(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID, 
				new CommandContributionItem(new CommandContributionItemParameter(
						site, null, RCodeLaunching.SUBMIT_SELECTION_COMMAND_ID, null,
						null, null, null,
						null, "R", null, //$NON-NLS-1$
						CommandContributionItem.STYLE_PUSH, null, false) ));
		m.appendToGroup(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID, 
				new CommandContributionItem(new CommandContributionItemParameter(
						site, null, RCodeLaunching.SUBMIT_UPTO_SELECTION_COMMAND_ID, null,
						null, null, null,
						null, "U", null, //$NON-NLS-1$
						CommandContributionItem.STYLE_PUSH, null, false) ));
		
		m.add(new Separator(IStatetUIMenuIds.GROUP_ADD_MORE_ID));
	}
	
	protected IWikidocModelInfo getCurrentInputModel() {
		final TreeViewer viewer= getViewer();
		if (viewer == null) {
			return null;
		}
		return (IWikidocModelInfo) getModelInfo(viewer.getInput());
	}
	
}
