/*******************************************************************************
 *
 * Copyright (c) 2010, 2017 BestSolution.at and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
 * Steven Spungin <steven@spungin.tv> - Bug 404136, Bug 424730, Bug 436281
 ******************************************************************************/
package org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.tools.emf.ui.common.IClassContributionProvider.ContributionData;
import org.eclipse.e4.tools.emf.ui.common.IClassContributionProvider.Filter;
import org.eclipse.e4.tools.emf.ui.common.ResourceSearchScope;
import org.eclipse.e4.tools.emf.ui.internal.Messages;
import org.eclipse.e4.tools.emf.ui.internal.StringMatcher;
import org.eclipse.e4.tools.emf.ui.internal.common.ClassContributionCollector;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.E;
import org.eclipse.e4.tools.emf.ui.internal.common.resourcelocator.TargetPlatformIconContributionCollector;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

/**
 * A FilteredContributionDialog with additional options for icon resources.
 * Features in include
 * <ul>
 * <li>Rebuilding the viewer when row height decreases. (Workaround for an SWT limitation)
 * <li>Icon previews are displace in the first column.
 * <li>Limited the maximum image size.
 * </ul>
 *
 * @author "Steven Spungin"
 *
 * @see FilteredContributionDialog
 */
public abstract class AbstractIconDialogWithScopeAndFilter extends FilteredContributionDialog {
	private final IProject project;
	private final Map<IFile, Image> icons = Collections.synchronizedMap(new HashMap<IFile, Image>());

	static public class Entry {
		IFile file;
		String installLocation;
	}

	protected Integer maxDisplayedImageSize;
	protected int maxImageHeight;
	public static TargetPlatformIconContributionCollector collector;

	public AbstractIconDialogWithScopeAndFilter(Shell parentShell, IEclipseContext context) {
		super(parentShell, context);
		project = context.get(IProject.class);
	}

	@Override
	protected String getFilterTextMessage() {
		return Messages.AbstractIconDialogWithScopeAndFilter_typeToStartSearch;
	}

	@Override
	protected String getResourceNameText() {
		return Messages.AbstractIconDialogWithScopeAndFilter_iconName;
	}

	@Override
	protected ClassContributionCollector getCollector() {
		if (collector == null) {
			collector = TargetPlatformIconContributionCollector.getInstance();
		}
		return collector;
	}

	@Override
	protected void createOptions(Composite compOptions) {
		super.createOptions(compOptions);

		final Label lblMaxSize = new Label(compOptions, SWT.NONE);
		lblMaxSize.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
		lblMaxSize.setText(Messages.AbstractIconDialogWithScopeAndFilter_maxDisplayedImageSize);

		final ComboViewer cv = new ComboViewer(compOptions);
		cv.getCombo().setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1));
		cv.add(10);
		cv.add(20);
		cv.add(30);
		cv.add(50);
		cv.add(100);
		cv.add(150);
		cv.add(200);
		maxDisplayedImageSize = 30;
		cv.setSelection(new StructuredSelection(maxDisplayedImageSize));

		cv.addSelectionChangedListener(new ISelectionChangedListener() {

			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				maxDisplayedImageSize = (Integer) ((IStructuredSelection) cv.getSelection()).getFirstElement();
				rebuildViewer();
				refreshSearch();
				// combo viewer cannot make rows smaller, so we will need to
				// rebuild it in that case.
			}
		});
	}

	@Override
	protected void rebuildViewer() {
		super.rebuildViewer();
		getViewer().getTable().setHeaderVisible(true);

		((GridData) getViewer().getTable().getLayoutData()).minimumHeight = 100;

		final TableViewerColumn colIcon = new TableViewerColumn(getViewer(), SWT.NONE);
		colIcon.getColumn().setText(Messages.AbstractIconDialogWithScopeAndFilter_icon);
		final TableViewerColumn colText = new TableViewerColumn(getViewer(), SWT.NONE);
		colText.getColumn().setText(Messages.AbstractIconDialogWithScopeAndFilter_details);

		// resize the row height using a MeasureItem listener
		getViewer().getTable().addListener(SWT.MeasureItem, new Listener() {
			@Override
			public void handleEvent(Event event) {
				// height cannot be per row so simply set
				event.height = maxDisplayedImageSize;
			}
		});

		colIcon.setLabelProvider(new StyledCellLabelProvider() {
			@Override
			public void update(ViewerCell cell) {
				IFile file;
				if (cell.getElement() instanceof ContributionData) {
					file = new ContributionDataFile((ContributionData) cell.getElement());
				} else if (cell.getElement() instanceof Entry) {
					file = ((Entry) cell.getElement()).file;
				} else {
					file = (IFile) cell.getElement();
				}

				Image img = icons.get(file);
				if (img == null) {
					try (InputStream in = file.getContents()) {
						img = new Image(cell.getControl().getDisplay(), in);
						icons.put(file, img);
					} catch (final Exception e) {
						// e.printStackTrace();
						return;
					}
				}

				// scale image if larger then max height
				// also remember max width for column resizing

				double scale1 = (double) maxDisplayedImageSize / img.getImageData().height;
				final double scale2 = (double) maxDisplayedImageSize / img.getImageData().width;
				if (scale2 < scale1) {
					scale1 = scale2;
				}
				if (scale1 < 1) {
					int width = (int) (img.getImageData().width * scale1);
					if (width == 0) {
						width = 1;
					}
					int height = (int) (img.getImageData().height * scale1);
					if (height == 0) {
						height = 1;
					}
					final Image img2 = new Image(img.getDevice(), img.getImageData().scaledTo(width, height));
					img.dispose();
					img = img2;
					icons.put(file, img);
				}
				final int width = AbstractIconDialogWithScopeAndFilter.this.getViewer().getTable().getColumn(0)
						.getWidth();
				if (img.getImageData().width > width) {
					AbstractIconDialogWithScopeAndFilter.this.getViewer().getTable().getColumn(0)
					.setWidth(img.getImageData().width);
				}
				final int height = img.getImageData().height;
				if (height > maxImageHeight) {
					maxImageHeight = height;
				}

				cell.setImage(img);
			}
		});
		colIcon.getColumn().setWidth(30);

		colText.setLabelProvider(new StyledCellLabelProvider() {
			@Override
			public void update(ViewerCell cell) {
				IFile file;
				String installLocation = null;
				if (cell.getElement() instanceof ContributionData) {
					final ContributionData contributionData = (ContributionData) cell.getElement();
					file = new ContributionDataFile(contributionData);
					installLocation = contributionData.installLocation;
				} else if (cell.getElement() instanceof Entry) {
					file = ((Entry) cell.getElement()).file;
					installLocation = ((Entry) cell.getElement()).installLocation;
				} else {
					file = (IFile) cell.getElement();
				}
				final StyledString styledString = new StyledString(file.getProjectRelativePath().toString(), null);
				final String bundle = FilteredContributionDialog.getBundle(file);
				if (bundle != null) {
					styledString.append(" - " + bundle, StyledString.DECORATIONS_STYLER); //$NON-NLS-1$
				} else if (installLocation != null) {
					styledString.append(" - " + installLocation, StyledString.DECORATIONS_STYLER); //$NON-NLS-1$
				}

				cell.setText(styledString.getString());
				cell.setStyleRanges(styledString.getStyleRanges());
			}
		});
		colText.getColumn().setWidth(400);

		getShell().addDisposeListener(new DisposeListener() {

			@Override
			public void widgetDisposed(DisposeEvent e) {
				clearImages();
			}
		});
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		final Composite comp = (Composite) super.createDialogArea(parent);
		maxDisplayedImageSize = 20;
		rebuildViewer();

		return comp;
	}

	private IconMatchCallback callback;
	private String returnValue;
	private SearchThread task;

	@Override
	protected boolean doSearch() {

		// if (getSearchScopes().contains(SearchScope.TARGET_PLATFORM) ||
		// getSearchScopes().contains(SearchScope.WORKSPACE)) {
		if (getSearchScopes().contains(ResourceSearchScope.TARGET_PLATFORM)) {
			return false;
		}
		final Timer timer = new Timer(true);

		if (callback != null) {
			callback.cancel = true;
		}
		if (task != null) {
			task.cancel();
		}
		task = null;

		clearImages();

		callback = new IconMatchCallback((IObservableList) getViewer().getInput());
		final Filter filter = new Filter(project, getFilterTextBox().getText());
		filter.setSearchScope(getSearchScopes());
		filter.setBundles(getFilterBundles());
		filter.setLocations(getFilterLocations());
		filter.setPackages(getFilterPackages());
		filter.setIncludeNonBundles(includeNonBundles);
		task = new SearchThread(callback, filter);
		timer.schedule(task, 500);
		// }
		return true;
	}

	private void clearImages() {
		for (final Image img : icons.values()) {
			img.dispose();
		}
		icons.clear();
	}

	@Override
	protected void okPressed() {
		returnValue = null;
		IFile file = getSelectedIfile();
		if (file != null) {
			String installLocation = null;
			if (file instanceof ContributionDataFile) {
				final ContributionDataFile cdf = (ContributionDataFile) file;
				installLocation = cdf.getContributionData().installLocation;

			}
			file = checkResourceAccessible(file, installLocation);
			if (file != null) {
				final String bundle = getBundle(file);
				String uri;
				uri = "platform:/plugin/" + bundle + "/" + file.getProjectRelativePath().toString(); //$NON-NLS-1$ //$NON-NLS-2$
				returnValue = uri;
				super.okPressed();
			}
		}
	}

	private class IconMatchCallback {
		private volatile boolean cancel;
		private final IObservableList list;

		private IconMatchCallback(IObservableList list) {
			this.list = list;
		}

		public void match(final IFile file, final String installLocation) {
			if (!cancel) {
				list.getRealm().exec(new Runnable() {

					@Override
					public void run() {
						final Entry entry = new Entry();
						entry.file = file;
						entry.installLocation = installLocation;
						list.add(entry);
					}
				});
			}
		}
	}

	private static class SearchThread extends TimerTask {
		private final IconMatchCallback callback;
		private final StringMatcher matcherGif;
		private final StringMatcher matcherJpg;
		private final StringMatcher matcherPng;
		private final Filter filter;
		private boolean includeNonBundles;

		public SearchThread(IconMatchCallback callback, Filter filter) {
			matcherGif = new StringMatcher("*" + filter.namePattern + "*.gif", true, false); //$NON-NLS-1$//$NON-NLS-2$
			matcherJpg = new StringMatcher("*" + filter.namePattern + "*.jpg", true, false); //$NON-NLS-1$//$NON-NLS-2$
			matcherPng = new StringMatcher("*" + filter.namePattern + "*.png", true, false); //$NON-NLS-1$//$NON-NLS-2$
			this.callback = callback;
			this.filter = filter;
		}

		@Override
		public void run() {
			List<IProject> projects;
			if (filter.getSearchScope().contains(ResourceSearchScope.TARGET_PLATFORM)) {
				// never should be here because it is cached and not run as
				// thread
				return;
			} else if (filter.getSearchScope().contains(ResourceSearchScope.WORKSPACE)) {
				projects = Arrays.asList(filter.project.getWorkspace().getRoot().getProjects());
			} else if (filter.getSearchScope().contains(ResourceSearchScope.PROJECT)) {
				if (filter.getSearchScope().contains(ResourceSearchScope.REFERENCES)) {
					projects = new ArrayList<>();
					projects.add(filter.project);
					try {
						for (final IProject ref : filter.project.getReferencedProjects()) {
							projects.add(ref);
						}
					} catch (final CoreException e) {
						e.printStackTrace();
					}
				} else {
					projects = Arrays.asList(filter.project);
				}
			} else {
				return;
			}

			try {
				for (final IProject project : projects) {
					// Only search bundles unless requested
					if (includeNonBundles == false && filter.project.getFile("/META-INF/MANIFEST.MF").exists() == false) { //$NON-NLS-1$
						continue;
					}
					project.accept(new IResourceVisitor() {

						@Override
						public boolean visit(IResource resource) throws CoreException {
							if (callback.cancel) {
								return false;
							}

							if (resource.getType() == IResource.FOLDER || resource.getType() == IResource.PROJECT) {
								return true;
							} else if (resource.getType() == IResource.FILE && !resource.isLinked()) {
								final String path = resource.getProjectRelativePath().toString();
								if (matcherGif.match(path) || matcherPng.match(path) || matcherJpg.match(path)) {
									if (E.notEmpty(filter.getPackages())) {
										if (!filter.getPackages().contains(
												resource.getProjectRelativePath().removeLastSegments(1).toOSString())) {
											return false;
										}
									}
									if (E.notEmpty(filter.getLocations())) {
										if (!filter.getLocations().contains(project.getLocation().toOSString())) {
											return false;
										}
									}
									if (E.notEmpty(filter.getBundles())) {
										final String bundle = getBundle(project);
										if (bundle == null || !filter.getBundles().contains(bundle)) {
											return false;
										}
									}
									if (!filter.isIncludeNonBundles()) {
										final String bundle = getBundle(project);
										if (bundle == null) {
											return false;
										}

									}
									callback.match((IFile) resource, project.getLocation().toOSString());
								}
							}
							return false;
						}

					});
				}
			} catch (final CoreException e) {
				e.printStackTrace();
			}
		}
	}

	public String getValue() {
		return returnValue;
	}
}
