/*=============================================================================#
 # Copyright (c) 2000, 2018 IBM Corporation 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.
 # 
 # SPDX-License-Identifier: EPL-2.0
 # 
 # Contributors:
 #     IBM Corporation - org.eclipse.jdt: initial API and implementation
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.buildpaths.ui;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImIdentitySet;

import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.ui.components.ButtonGroup;
import org.eclipse.statet.ecommons.ui.components.DataAdapter;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.ltk.buildpaths.ui.Messages;
import org.eclipse.statet.ltk.buildpaths.core.BuildpathElementType;
import org.eclipse.statet.ltk.buildpaths.core.IBuildpathAttribute;
import org.eclipse.statet.ltk.buildpaths.core.IBuildpathElement;
import org.eclipse.statet.ltk.buildpaths.ui.wizards.EditFilterWizard;


public class SourceContainerComponent implements ButtonGroup.IActions<Object> {
	
	
	private static final ImIdentitySet<String> FILTER_NO= ImCollections.emptyIdentitySet();
	
	private static final ImIdentitySet<String> FILTER_OUTPUT= ImCollections.newIdentitySet(
			IBuildpathAttribute.OUTPUT );
	
	private static final Object[] NO_CHILDREN= new Object[0];
	
	
	private class TreeContentProvider implements ITreeContentProvider {
		
		
		public TreeContentProvider() {
		}
		
		@Override
		public void dispose() {
		}
		
		
		@Override
		public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
		}
		
		@Override
		public Object[] getElements(final Object inputElement) {
			return SourceContainerComponent.this.containerList.toArray();
		}
		
		@Override
		public Object getParent(final Object element) {
			if (element instanceof BuildpathListElementAttribute) {
				return ((BuildpathListElementAttribute) element).getParent();
			}
			return null;
		}
		
		@Override
		public boolean hasChildren(final Object element) {
			if (element instanceof BuildpathListElement) {
				return true;
			}
			return false;
		}
		
		private boolean isFilterOutputAttribute() {
			return (SourceContainerComponent.this.outputByContainerValue == null
					|| !((boolean) SourceContainerComponent.this.outputByContainerValue.getValue()) );
		}
		
		@Override
		public Object[] getChildren(final Object element) {
			if (element instanceof BuildpathListElement) {
				final ImIdentitySet<String> filter= (isFilterOutputAttribute()) ?
						FILTER_OUTPUT : FILTER_NO;
				return ((BuildpathListElement) element).getFilteredChildren(filter).toArray();
			}
			return NO_CHILDREN;
		}
		
	}
	
	private class ListElementDataAdapter extends DataAdapter.TreeAdapter<Object> {
		
		
		public ListElementDataAdapter(final ITreeContentProvider contentProvider) {
			super(contentProvider, null);
		}
		
		
		@Override
		public boolean isModifyAllowed(final Object element) {
			if (element instanceof BuildpathListElement) {
				final BuildpathListElement listElement= (BuildpathListElement) element;
				if (listElement.getType().getName() == IBuildpathElement.SOURCE) {
					if (listElement.getPath().equals(SourceContainerComponent.this.project.getFullPath())) {
						return false;
					}
				}
				return (SourceContainerComponent.this.uiDescription.getAllowEdit(listElement));
			}
			if (element instanceof BuildpathListElementAttribute) {
				final BuildpathListElementAttribute attribute= (BuildpathListElementAttribute) element;
				if (attribute.isBuiltin()) {
					return (SourceContainerComponent.this.uiDescription.getAllowEdit(attribute));
				}
				else {
					return false;
				}
			}
			return false;
		}
		
		@Override
		public boolean isDeleteAllowed(final Object element) {
			if (element instanceof BuildpathListElement) {
				final BuildpathListElement listElement= (BuildpathListElement) element;
				return (SourceContainerComponent.this.uiDescription.getAllowEdit(listElement));
			}
			if (element instanceof BuildpathListElementAttribute) {
				final BuildpathListElementAttribute attribute= (BuildpathListElementAttribute) element;
				if (SourceContainerComponent.this.uiDescription.getAllowEdit(attribute)) {
					if (attribute.isBuiltin()) {
						switch (attribute.getName()) {
						case IBuildpathAttribute.FILTER_INCLUSIONS:
						case IBuildpathAttribute.FILTER_EXCLUSIONS:
							return (!((List<?>) attribute.getValue()).isEmpty());
						default:
							return (attribute.getValue() != null);
						}
					}
					else {
						return true;
					}
				}
				return false;
			}
			return false;
		}
		
		@Override
		public void delete(final List<? extends Object> elements) {
			for (final Object object : elements) {
				if (object instanceof BuildpathListElement) {
					final BuildpathListElement element= (BuildpathListElement) object;
					SourceContainerComponent.this.containerList.remove(element);
					continue;
				}
				if (object instanceof BuildpathListElementAttribute) {
					final BuildpathListElementAttribute attribute= (BuildpathListElementAttribute) object;
					final String key= attribute.getName();
					if (attribute.isBuiltin()) {
						final Object value;
						switch (attribute.getName()) {
						case IBuildpathAttribute.FILTER_INCLUSIONS:
						case IBuildpathAttribute.FILTER_EXCLUSIONS:
							value= ImCollections.emptyList();
							break;
						default:
							value= null;
							break;
						}
						attribute.getParent().setAttribute(key, value);
						SourceContainerComponent.this.changedContainers.add(attribute.getParent());
						continue;
					}
					else {
						throw new UnsupportedOperationException("Not yet implemented");
//						continue;
					}
				}
			}
			updateBuildpathList();
		}
		
	}
	
	
	private final WritableList<BuildpathListElement> buildpathList;
	
	private final BuildpathElementType type;
	
	private final BuildpathsUIDescription uiDescription;
	
	private IProject project;
	
	private final WritableList<BuildpathListElement> containerList= new WritableList<>();
	
	private final Set<BuildpathListElement> changedContainers= new HashSet<>();
	
	private final IObservableValue<String> outputPathValue;
	private final IObservableValue<Boolean> outputByContainerValue;
	
	private Control control;
	
	private TreeViewer containerListViewer;
	private ButtonGroup<Object> containerListButtons;
	
	private Text outputPathControl;
	private Button outputByFolderControl;
	
	
	public SourceContainerComponent(final WritableList<BuildpathListElement> buildpathList,
			final BuildpathElementType sourceType, final BuildpathElementType outputType,
			final BuildpathsUIDescription uiDescription) {
		this.buildpathList= buildpathList;
		this.type= sourceType;
		
		this.uiDescription= uiDescription;
		
		this.outputPathValue= (outputType != null) ?
				new WritableValue<>(null, String.class) : null;
		this.outputByContainerValue= (outputType != null
						&& this.type.isAttributeBuiltin(IBuildpathAttribute.OUTPUT) ) ?
				new WritableValue<>(false, Boolean.TYPE) : null;
	}
	
	public void init(final IProject project) {
		this.project= project;
		if (Display.getCurrent() != null) {
			updateTargets(true);
		}
		else {
			Display.getDefault().asyncExec(new Runnable() {
				@Override
				public void run() {
					updateTargets(true);
				}
			});
		}
	}
	
	
	private Shell getShell() {
		if (this.control != null) {
			return this.control.getShell();
		}
		return UIAccess.getActiveWorkbenchShell(true);
	}
	
	public Control create(final Composite parent) {
		final Composite composite= new Composite(parent, SWT.NONE);
		composite.setLayout(LayoutUtils.newCompositeGrid(2));
		
		{	final Label label= new Label(composite, SWT.NONE);
			label.setText(Messages.SourceContainers_SourceFolders_label);
			
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
		}
		{	final TreeViewer viewer= new TreeViewer(composite,
					SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL );
			final TreeContentProvider contentProvider= new TreeContentProvider();
			viewer.setContentProvider(contentProvider);
			viewer.setComparator(this.uiDescription.createListElementComparator());
			viewer.setLabelProvider(this.uiDescription.createListLabelProvider());
			viewer.setInput(this.containerList);
			
			final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true);
			gd.heightHint= LayoutUtils.hintHeight(viewer.getTree(), 8);
			gd.widthHint= LayoutUtils.hintWidth(viewer.getTree(), 60);
			viewer.getControl().setLayoutData(gd);
			this.containerListViewer= viewer;
			
			final ButtonGroup<Object> buttonGroup= new ButtonGroup<>(composite, this, false);
			buttonGroup.addAddButton(new ButtonGroup.AddHandler() {
				@Override
				public void update(final IStructuredSelection selection) {
					setEnabled(SourceContainerComponent.this.uiDescription.getAllowAdd(
							SourceContainerComponent.this.project, SourceContainerComponent.this.type ));
				}
			});
			buttonGroup.addEditButton(null);
			buttonGroup.addDeleteButton(null);
			buttonGroup.connectTo(viewer, new ListElementDataAdapter(contentProvider));
			
			buttonGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
			this.containerListButtons= buttonGroup;
		}
		
		if (this.outputPathValue != null) {
			{	final Label label= new Label(composite, SWT.NONE);
				label.setText(Messages.SourceContainers_OutputFolder_label);
				
				label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
			}
			{	final Text text= new Text(composite, SWT.BORDER | SWT.SINGLE);
				
				text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
				this.outputPathControl= text;
				
				final Button button= new Button(composite, SWT.PUSH);
				button.setText(Messages.SourceContainers_OutputFolder_Choose_label);
			}
			if (this.outputByContainerValue != null) {
				final Button button= new Button(composite, SWT.CHECK);
				button.setText(Messages.SourceContainers_OutputBySourceFolders_label);
				button.setSelection(false);
				
				button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
				this.outputByFolderControl= button;
			}
		}
		
		this.control= composite;
		
		return this.control;
	}
	
	public void bind(final DataBindingSupport db) {
		if (this.outputPathValue != null) {
			db.getContext().bindValue(
					WidgetProperties.text(SWT.Modify).observe(this.outputPathValue),
					this.outputPathValue );
			
			if (this.outputByContainerValue != null) {
				db.getContext().bindValue(
						WidgetProperties.selection().observe(this.outputByFolderControl),
						this.outputByContainerValue );
				
				this.outputByContainerValue.addValueChangeListener(
						(final ValueChangeEvent<? extends Boolean> event) -> {
							if (!(event.diff.getNewValue())) {
								for (final Object object : SourceContainerComponent.this.containerList) {
									final BuildpathListElement element= (BuildpathListElement) object;
									final BuildpathListElementAttribute attribute= element
											.setAttribute(IBuildpathAttribute.OUTPUT, null);
									
									if (attribute != null) {
										SourceContainerComponent.this.changedContainers.add(element);
									}
								}
								SourceContainerComponent.this.containerListButtons.refresh();
							}
						} );
			}
		}
		
		updateExpandStates();
	}
	
	private void updateTargets(final boolean reset) {
		if (UIAccess.isOkToUse(this.control)) {
			if (reset) {
				this.containerListViewer.collapseAll();
			}
			this.containerList.clear();
			this.changedContainers.clear();
			
			final List<BuildpathListElement> folders= new ArrayList<>();
			boolean outputLocationByFolder= false;
			
			for (final BuildpathListElement element : this.buildpathList) {
				if (isElement(element)) {
					folders.add(element);
					outputLocationByFolder|= (element.getAttributeValue(IBuildpathAttribute.OUTPUT) != null);
				}
			}
			this.containerList.addAll(folders);
			this.containerListButtons.refresh();
			updateExpandStates();
			
			if (this.outputByContainerValue != null) {
				this.outputByContainerValue.setValue(outputLocationByFolder);
			}
		}
	}
	
	private void updateBuildpathList() {
		final List<BuildpathListElement> workingList= new ArrayList<>(this.containerList);
		
		for (int idx= 0; idx < this.buildpathList.size();) {
			final BuildpathListElement element= this.buildpathList.get(idx);
			if (isElement(element)) {
				if (workingList.remove(element)) {
					if (this.changedContainers.remove(element)) {
						this.buildpathList.set(idx, element);
					}
					idx++;
				}
				else {
					this.buildpathList.remove(idx);
				}
			}
			else {
				idx++;
			}
		}
		if (!workingList.isEmpty()) {
			this.buildpathList.addAll(workingList);
		}
		this.changedContainers.clear();
	}
	
	private void updateExpandStates() {
		for (int i= 0; i < this.containerList.size(); i++) {
			final BuildpathListElement element= this.containerList.get(i);
			final List<IPath> inclusionPatterns= (List<IPath>) element.getAttributeValue(IBuildpathAttribute.FILTER_INCLUSIONS);
			final List<IPath> exclusionPatterns= (List<IPath>) element.getAttributeValue(IBuildpathAttribute.FILTER_EXCLUSIONS);
			final IPath outputFolder= (IPath) element.getAttributeValue(IBuildpathAttribute.OUTPUT);
			if (!inclusionPatterns.isEmpty() || !exclusionPatterns.isEmpty() || outputFolder != null) {
				this.containerListViewer.expandToLevel(element, 1);
			}
		}
	}
	
	protected boolean isElement(final BuildpathListElement element) {
		return (element.getType() == this.type);
	}
	
	
	public void setFocus() {
		this.containerListViewer.getTree().setFocus();
	}
	
	
	public List<Object> getSelection() {
		return ImCollections.toList(
				((StructuredSelection) this.containerListViewer.getSelection()).toList() );
	}
	
	public void setSelection(final List<BuildpathListElement> elements, final boolean expand) {
		this.containerListViewer.setSelection(new StructuredSelection(elements));
		if (expand) {
			for (final BuildpathListElement element : elements) {
				this.containerListViewer.expandToLevel(element, 1);
			}
		}
	}
	
	
	@Override
	public Object edit(final int command, final Object item, final Object parent) {
		if (command == ButtonGroup.ADD_NEW) {
			throw new UnsupportedOperationException();
		}
		else {
			if (item instanceof BuildpathListElement) {
				return editElement((BuildpathListElement) item);
			}
			if (item instanceof BuildpathListElementAttribute) {
				return editAttribute((BuildpathListElementAttribute) item);
			}
			throw new IllegalStateException();
		}
	}
	
	@Override
	public void updateState(final IStructuredSelection selection) {
	}
	
	private BuildpathListElement editElement(final BuildpathListElement element) {
		throw new UnsupportedOperationException("Not yet implemented");
	}
	
	private BuildpathListElementAttribute editAttribute(final BuildpathListElementAttribute attribute) {
		switch (attribute.getName()) {
		case IBuildpathAttribute.FILTER_INCLUSIONS:
		case IBuildpathAttribute.FILTER_EXCLUSIONS: {
			final EditFilterWizard wizard= new EditFilterWizard(
					ImCollections.toList((List<BuildpathListElement>) this.containerList),
					attribute.getParent(), this.uiDescription );
			final WizardDialog dialog= new WizardDialog(getShell(), wizard);
			dialog.create();
			wizard.setFocus(attribute.getName());
			if (dialog.open() == Window.OK) {
				this.containerListButtons.refresh(null);
				this.changedContainers.add(attribute.getParent());
				updateBuildpathList();
			}
			return null;
		}
		default:
			throw new UnsupportedOperationException("Not yet implemented");
		}
	}
	
}
