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

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import java.util.Iterator;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;

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

import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.actions.SimpleContributionItem;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.workbench.BasicEditorOutlinePage;
import org.eclipse.statet.ecommons.waltable.coordinate.LRangeList;

import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.r.ui.dataeditor.IRDataTableInput;
import org.eclipse.statet.r.ui.dataeditor.IRDataTableListener;
import org.eclipse.statet.r.ui.dataeditor.IRDataTableVariable;
import org.eclipse.statet.r.ui.dataeditor.RDataTableColumn;
import org.eclipse.statet.rj.data.RFactorStore;
import org.eclipse.statet.rj.data.RStore;


@NonNullByDefault
public class RDataEditorOutlinePage extends BasicEditorOutlinePage {
	
	
	private static final Object[] NO_CHILDREN= new @NonNull Object[0];
	
	
	static abstract class VariablePropertyItem {
		
		
		protected final IRDataTableVariable variable;
		
		
		public VariablePropertyItem(final IRDataTableVariable column) {
			this.variable= column;
		}
		
		
		public Object getParent() {
			return this.variable;
		}
		
		public boolean hasChildren() {
			return false;
		}
		
		public Object[] getChildren() {
			return NO_CHILDREN;
		}
		
		public abstract String getName();
		
		public int getCount() {
			return -1;
		}
		
		
		@Override
		public int hashCode() {
			return getName().hashCode() * this.variable.hashCode();
		}
		
		@Override
		public boolean equals(final @Nullable Object obj) {
			if (this == obj) {
				return true;
			}
			if (obj instanceof VariablePropertyItem) {
				final VariablePropertyItem other= (VariablePropertyItem)obj;
				return (getName() == other.getName()
						&& this.variable.equals(other.variable));
			}
			return false;
		}
		
	}
	
	private static class FactorLevels extends VariablePropertyItem {
		
		
		public FactorLevels(final RDataTableColumn column) {
			super(column);
		}
		
		
		@Override
		public boolean hasChildren() {
			return true;
		}
		
		@Override
		public Object[] getChildren() {
			final RFactorStore data= (RFactorStore)((RDataTableColumn)this.variable).getDataStore();
			return data.getLevels().toArray();
		}
		
		@Override
		public String getName() {
			return "Factor Levels";
		}
		
		@Override
		public int getCount() {
			final RFactorStore data= (RFactorStore)((RDataTableColumn)this.variable).getDataStore();
			return data.getLevelCount();
		}
		
	}
	
	private static class FTableFactorLevels extends VariablePropertyItem {
		
		
		public FTableFactorLevels(final FTableVariable variable) {
			super(variable);
		}
		
		
		@Override
		public boolean hasChildren() {
			return true;
		}
		
		@Override
		public Object[] getChildren() {
			final RStore data= ((FTableVariable)this.variable).getLevelStore();
			return data.toArray();
		}
		
		@Override
		public String getName() {
			return "Levels";
		}
		
		@Override
		public int getCount() {
			final RStore data= ((FTableVariable)this.variable).getLevelStore();
			return (int)data.getLength();
		}
		
	}
	
	
	private class RDataContentProvider implements ITreeContentProvider {
		
		@Override
		public void inputChanged(final Viewer viewer, final @Nullable Object oldInput, final @Nullable Object newInput) {
		}
		
		@Override
		public Object[] getElements(final Object inputElement) {
			final RDataTableContentDescription contentDescription= RDataEditorOutlinePage.this.contentDescription;
			if (contentDescription != null) {
				return new Object[] { contentDescription };
			}
			return NO_CHILDREN;
		}
		
		@Override
		public @Nullable Object getParent(final Object element) {
			if (element instanceof RDataTableColumn) {
				return RDataEditorOutlinePage.this.contentDescription;
			}
			if (element instanceof VariablePropertyItem) {
				return ((VariablePropertyItem)element).getParent();
			}
			return null;
		}
		
		@Override
		public boolean hasChildren(final Object element) {
			final RDataTableContentDescription contentDescription= RDataEditorOutlinePage.this.contentDescription;
			if (element == contentDescription) {
				return (contentDescription.getVariables().length > 0);
			}
			if (element instanceof RDataTableColumn) {
				final RDataTableColumn column= (RDataTableColumn)element;
				return (column.getVarType() == IRDataTableVariable.FACTOR);
			}
			else if (element instanceof FTableVariable) {
				return true;
			}
			else if (element instanceof VariablePropertyItem) {
				final VariablePropertyItem item= (VariablePropertyItem) element;
				return item.hasChildren();
			}
			return false;
		}
		
		@Override
		public Object[] getChildren(final Object parentElement) {
			final RDataTableContentDescription contentDescription= RDataEditorOutlinePage.this.contentDescription;
			{	final Object[] columns;
				if (parentElement == contentDescription
						&& (columns= contentDescription.getVariables()).length <= 2500 ) {
					return columns;
				}
			}
			if (parentElement instanceof RDataTableColumn) {
				final RDataTableColumn column= (RDataTableColumn) parentElement;
				if (column.getVarType() == IRDataTableVariable.FACTOR) {
					return new Object[] { new FactorLevels(column) };
				}
			}
			else if (parentElement instanceof FTableVariable) {
				return new Object[] { new FTableFactorLevels((FTableVariable) parentElement) };
			}
			else if (parentElement instanceof VariablePropertyItem) {
				final VariablePropertyItem item= (VariablePropertyItem) parentElement;
				return item.getChildren();
			}
			return new Object[0];
		}
		
		@Override
		public void dispose() {
		}
		
	}
	
	private final RDataEditor editor;
	
	private @Nullable RDataTableContentDescription contentDescription;
	
	
	public RDataEditorOutlinePage(final RDataEditor editor) {
		super("org.eclipse.statet.r.menu.RDataOutlineViewContextMenu"); //$NON-NLS-1$
		this.editor= editor;
	}
	
	
	public RDataEditor getDataEditor() {
		return this.editor;
	}
	
	@Override
	protected IDialogSettings getDialogSettings() {
		return DialogUtils.getDialogSettings(RUIPlugin.getInstance(), "RDataOutlineView");
	}
	
	@Override
	protected void configureViewer(final TreeViewer viewer) {
		viewer.setUseHashlookup(true);
		viewer.setContentProvider(new RDataContentProvider());
		viewer.setLabelProvider(new RDataLabelProvider());
		viewer.setInput(this);
	}
	
	@Override
	protected void init() {
		super.init();
		this.editor.getRDataTable().addTableListener(new IRDataTableListener() {
			@Override
			public void inputChanged(final IRDataTableInput input, final RDataTableContentDescription description) {
				final RDataTableContentDescription oldDescription= RDataEditorOutlinePage.this.contentDescription;
				final boolean isNew= (description != null
						&& (oldDescription == null
								|| oldDescription.getVariables().length != description.getVariables().length ));
				RDataEditorOutlinePage.this.contentDescription= description;
				
				final TreeViewer viewer= getViewer();
				if (viewer == null || !UIAccess.isOkToUse(viewer.getControl())) {
					return;
				}
				viewer.refresh();
				if (isNew && RDataEditorOutlinePage.this.contentDescription != null) {
//						viewer.setExpandedTreePaths(new TreePath[] { new TreePath(new Object[] { fDescription }) });
					viewer.expandToLevel(3);
				}
			}
		});
	}
	
	@Override
	protected @Nullable TreeViewer getViewer() {
		return (TreeViewer)super.getViewer();
	}
	
	@Override
	protected void selectInEditor(final ISelection selection) {
		if (selection.isEmpty()) {
			return;
		}
		if (selection instanceof IStructuredSelection) {
			final IStructuredSelection structuredSelection= (IStructuredSelection)selection;
			if (structuredSelection.size() == 1) {
				final Object element= structuredSelection.getFirstElement();
				if (element instanceof RDataTableColumn) {
					this.editor.getRDataTable().revealColumn(((RDataTableColumn) element).getIndex());
				}
			}
		}
	}
	
	@Override
	protected void contextMenuAboutToShow(final IMenuManager m) {
		final IStructuredSelection selection= (IStructuredSelection)nonNullAssert(getViewer())
				.getSelection();
		for (final Iterator<?> iterator= selection.iterator(); iterator.hasNext();) {
			final Object element= iterator.next();
			if (!(element instanceof RDataTableColumn)) {
				return;
			}
		}
		
		m.add(new SimpleContributionItem("Select Column", "S") {
			@Override
			protected void execute() throws ExecutionException {
				final TreeViewer viewer= getViewer();
				if (viewer == null || !UIAccess.isOkToUse(viewer.getControl())) {
					return;
				}
				final IStructuredSelection selection= (IStructuredSelection)viewer.getSelection();
				final LRangeList columnIndexes= new LRangeList();
				for (final Iterator<?> iterator= selection.iterator(); iterator.hasNext();) {
					final Object element= iterator.next();
					if (element instanceof RDataTableColumn) {
						columnIndexes.values().add(((RDataTableColumn) element).getIndex());
					}
					else {
						return;
					}
				}
				RDataEditorOutlinePage.this.editor.getRDataTable().selectColumns(columnIndexes);
			}
		});
		
		m.add(new Separator());
		if (selection.size() == 1) {
			m.add(new SimpleContributionItem(
					"Sort Increasing by Column", "I",
					SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_SORT_ALPHA_IMAGE_ID), null ) {
				@Override
				protected void execute() throws ExecutionException {
					final TreeViewer viewer= getViewer();
					if (viewer == null || !UIAccess.isOkToUse(viewer.getControl())) {
						return;
					}
					final IStructuredSelection selection= (IStructuredSelection)viewer.getSelection();
					final Object element= selection.getFirstElement();
					if (selection.size() == 1 && element instanceof RDataTableColumn) {
						final RDataTableColumn column= (RDataTableColumn) element;
						RDataEditorOutlinePage.this.editor.getRDataTable().sortByColumn(column.getIndex(), true);
					}
				}
			});
			m.add(new SimpleContributionItem(
					"Sort Decreasing by Column", "I") {
				@Override
				protected void execute() throws ExecutionException {
					final TreeViewer viewer= getViewer();
					if (viewer == null || !UIAccess.isOkToUse(viewer.getControl())) {
						return;
					}
					final IStructuredSelection selection= (IStructuredSelection)viewer.getSelection();
					final Object element= selection.getFirstElement();
					if (selection.size() == 1 && element instanceof RDataTableColumn) {
						final RDataTableColumn column= (RDataTableColumn) element;
						RDataEditorOutlinePage.this.editor.getRDataTable().sortByColumn(column.getIndex(), false);
					}
				}
			});
		}
		m.add(new SimpleContributionItem("Clear All Sorting", "O") {
			@Override
			protected void execute() throws ExecutionException {
				RDataEditorOutlinePage.this.editor.getRDataTable().clearSorting();
			}
		});
	}
	
}
