/*******************************************************************************
 * 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, 424730
 *     Andrej ten Brummelhuis <andrejbrummelhuis@gmail.com> - Bug 395283
 ******************************************************************************/
package org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.e4.core.contexts.IEclipseContext;
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.component.tabs.empty.E;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
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.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * Based of of AbstractIconDialog, but passively returns selection instead of
 * modifying model.
 *
 * @author Steven Spungin
 *
 */
public abstract class AbstractIconDialogWithHardcodedScope extends SaveDialogBoundsSettingsDialog {
	private TableViewer viewer;
	private IProject project;
	private Map<IFile, Image> icons = Collections.synchronizedMap(new HashMap<IFile, Image>());
	private ResourceSearchScope searchScope = ResourceSearchScope.PROJECT;

	protected Messages Messages;
	private Text textSearch;
	private String value;
	private IEclipseContext context;

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

	protected IEclipseContext getContext() {
		return context;
	}

	protected abstract String getShellTitle();

	protected abstract String getDialogTitle();

	protected abstract String getDialogMessage();

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite comp = (Composite) super.createDialogArea(parent);

		getShell().setText(getShellTitle());
		setTitle(getDialogTitle());
		setMessage(getDialogMessage());
		String bundleFilter = (String) context.get("bundle"); //$NON-NLS-1$
		if (E.notEmpty(bundleFilter)) {
			setMessage("Filtering by bundle " + bundleFilter); //$NON-NLS-1$
		}

		Composite container = new Composite(comp, SWT.NONE);
		container.setLayoutData(new GridData(GridData.FILL_BOTH));
		container.setLayout(new GridLayout(2, false));

		Composite compOptions = new Composite(container, SWT.NONE);
		compOptions.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
		compOptions.setLayout(new RowLayout());

		if (E.isEmpty(bundleFilter)) {
			Button btnProject = new Button(compOptions, SWT.RADIO);
			btnProject.setText(Messages.AbstractIconDialogWithHardcodedScope_Project);
			btnProject.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					searchScope = ResourceSearchScope.PROJECT;
					textSearch.notifyListeners(SWT.Modify, new Event());

				}
			});
			btnProject.setSelection(true);

			Button btnWorkspace = new Button(compOptions, SWT.RADIO);
			btnWorkspace.setText(Messages.AbstractIconDialogWithHardcodedScope_Workspace);
			btnWorkspace.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					searchScope = ResourceSearchScope.WORKSPACE;
					textSearch.notifyListeners(SWT.Modify, new Event());
				}
			});

			btnWorkspace.setSelection(searchScope == ResourceSearchScope.WORKSPACE);
			btnProject.setSelection(searchScope == ResourceSearchScope.PROJECT);
		} else {
			searchScope = ResourceSearchScope.WORKSPACE;
		}

		Label l = new Label(container, SWT.NONE);
		l.setText(Messages.AbstractIconDialog_IconName);

		textSearch = new Text(container, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH);
		textSearch.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		new Label(container, SWT.NONE);

		viewer = new TableViewer(container, SWT.FULL_SELECTION | SWT.BORDER);
		GridData gd = new GridData(GridData.FILL_BOTH);
		viewer.getControl().setLayoutData(gd);
		viewer.setContentProvider(new ObservableListContentProvider());
		viewer.setLabelProvider(new StyledCellLabelProvider() {
			@Override
			public void update(ViewerCell cell) {
				IFile file = (IFile) cell.getElement();
				StyledString styledString = new StyledString(file.getProjectRelativePath().toString(), null);

				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 (CoreException | IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

				String bundle = getBundle(file);
				if (bundle != null) {
					styledString.append(" - " + bundle, StyledString.DECORATIONS_STYLER); //$NON-NLS-1$
				}

				cell.setImage(img);
				cell.setText(styledString.getString());
				cell.setStyleRanges(styledString.getStyleRanges());
			}
		});

		final WritableList list = new WritableList();
		viewer.setInput(list);
		viewer.addDoubleClickListener(event -> okPressed());

		textSearch.addModifyListener(new ModifyListener() {
			private IconMatchCallback callback;
			private Timer timer = new Timer(true);
			private TimerTask task;

			@Override
			public void modifyText(ModifyEvent e) {
				if (callback != null) {
					callback.cancel = true;
				}
				if (task != null) {
					task.cancel();
				}
				list.clear();

				clearImages();

				callback = new IconMatchCallback(list);
				task = new SearchThread(callback, textSearch.getText(), project, context, searchScope);
				timer.schedule(task, 500);
			}
		});

		getShell().addDisposeListener(e -> clearImages());

		textSearch.notifyListeners(SWT.Modify, new Event());

		return comp;
	}

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

	@Override
	protected boolean isResizable() {
		return true;
	}

	@Override
	protected void okPressed() {
		value = null;
		IStructuredSelection s = (IStructuredSelection) viewer.getSelection();
		if (!s.isEmpty()) {
			IFile file = (IFile) s.getFirstElement();
			String bundle = getBundle(file);
			value = "platform:/plugin/" + bundle + "/" + file.getProjectRelativePath().toString(); //$NON-NLS-1$//$NON-NLS-2$

		}
		super.okPressed();
	}

	private String getBundle(IFile file) {
		IProject project = file.getProject();
		IFile f = project.getFile("/META-INF/MANIFEST.MF"); //$NON-NLS-1$

		if (f != null && f.exists()) {
			try (InputStream s = f.getContents(); BufferedReader r = new BufferedReader(new InputStreamReader(s));) {
				String line;
				while ((line = r.readLine()) != null) {
					if (line.startsWith("Bundle-SymbolicName:")) { //$NON-NLS-1$
						int start = line.indexOf(':');
						int end = line.indexOf(';');
						if (end == -1) {
							end = line.length();
						}
						return line.substring(start + 1, end).trim();
					}
				}
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return null;
	}

	public String getValue() {
		return value;
	}

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

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

		public void match(final IFile file) {
			if (!cancel) {
				list.getRealm().exec(() -> list.add(file));
			}
		}
	}

	private static class SearchThread extends TimerTask {
		private final IconMatchCallback callback;
		private final IProject project;
		private final StringMatcher matcherGif;
		private final StringMatcher matcherJpg;
		private final StringMatcher matcherPng;
		private IEclipseContext context;
		private ResourceSearchScope searchScope;

		public SearchThread(IconMatchCallback callback, String pattern, IProject project, IEclipseContext context, ResourceSearchScope searchScope) {
			this.context = context;
			this.matcherGif = new StringMatcher("*" + pattern + "*.gif", true, false); //$NON-NLS-1$//$NON-NLS-2$
			this.matcherJpg = new StringMatcher("*" + pattern + "*.jpg", true, false); //$NON-NLS-1$//$NON-NLS-2$
			this.matcherPng = new StringMatcher("*" + pattern + "*.png", true, false); //$NON-NLS-1$//$NON-NLS-2$
			this.callback = callback;
			this.project = project;
			this.searchScope = searchScope;
		}

		@Override
		public void run() {
			List<IProject> projects;
			switch (searchScope) {
			case WORKSPACE:
				projects = Arrays.asList(project.getWorkspace().getRoot().getProjects());
				break;
			case PROJECT:
			default:
				projects = Arrays.asList(project);
				break;
			}
			try {
				for (IProject project : projects) {
					// Only search bundles
					IFile iFile = project.getFile("/META-INF/MANIFEST.MF"); //$NON-NLS-1$
					if (iFile.exists() == false) {
						continue;
					}
					// Only search target bundle if specified
					String bundle = (String) context.get("bundle"); //$NON-NLS-1$
					if (E.notEmpty(bundle)) {
						try (InputStream inputStream = iFile.getContents();) {
							Properties props = new Properties();
							props.load(inputStream);
							String name = props.getProperty("Bundle-SymbolicName"); //$NON-NLS-1$
							String[] parts = name.split(";"); //$NON-NLS-1$
							if (parts[0].equals(bundle) == false) {
								continue;
							}
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					project.accept(resource -> {
						if (callback.cancel) {
							return false;
						}

						if (resource.getType() == IResource.FOLDER || resource.getType() == IResource.PROJECT) {
							return true;
						} else if (resource.getType() == IResource.FILE && !resource.isLinked()) {
							String path = resource.getProjectRelativePath().toString();
							if (matcherGif.match(path) || matcherPng.match(path) || matcherJpg.match(path)) {
								callback.match((IFile) resource);
							}
						}
						return false;
					});
				}
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
