/*******************************************************************************
 *
 * Copyright (c) 2010 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.IOException;
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) {
					InputStream in = null;
					try {
						in = file.getContents();
						img = new Image(cell.getControl().getDisplay(), in);
						icons.put(file, img);
					} catch (final Exception e) {
						// e.printStackTrace();
						return;
					} finally {
						if (in != null) {
							try {
								in.close();
							} catch (final IOException e) {
								// TODO Auto-generated catch block
								// e.printStackTrace();
							}
						}
					}
				}

				// 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;
	}
}
