/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.help.ui.internal.views;

import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.help.IContext;
import org.eclipse.help.IHelpResource;
import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.base.HelpBasePlugin;
import org.eclipse.help.internal.search.SearchHit;
import org.eclipse.help.internal.search.SearchQuery;
import org.eclipse.help.internal.search.SearchResults;
import org.eclipse.help.internal.search.federated.IndexerJob;
import org.eclipse.help.ui.internal.HelpUIResources;
import org.eclipse.help.ui.internal.IHelpUIConstants;
import org.eclipse.help.ui.internal.Messages;
import org.eclipse.help.ui.internal.util.EscapeUtils;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

public class DynamicHelpPart extends SectionPart implements IHelpPart {
	private static final String CANCEL_HREF = "__cancel__"; //$NON-NLS-1$

	private static final String MORE_HREF = "__more__"; //$NON-NLS-1$

	private ReusableHelpPart parent;

	private FormText searchResults;

	private SorterByScore resultSorter;

	private String id;

	private String phrase;

	private Job runningJob;
	private IContext context;

	private JobListener jobListener;
	public static final int SHORT_COUNT = 8;

	class JobListener extends JobChangeAdapter {

		@Override
		public void done(IJobChangeEvent event) {
			if (event.getJob() == runningJob) {
				runningJob = null;
			}
		}
	}

	/**
	 * @param parent
	 * @param toolkit
	 * @param style
	 */
	public DynamicHelpPart(Composite parent, FormToolkit toolkit) {
		super(parent, toolkit, Section.EXPANDED | Section.TWISTIE
				| Section.TITLE_BAR);
		// configure section
		Section section = getSection();
		section.setText(Messages.SearchPart_title);
		section.marginWidth = 5;
		section.addExpansionListener(new ExpansionAdapter() {

			@Override
			public void expansionStateChanged(ExpansionEvent e) {
				if (e.getState()) {
					refilter();
				}
			}
		});
		// create 'clear' hyperlink on the section tool bar
		//ImageHyperlink clearLink = new ImageHyperlink(section, SWT.NULL);
		//toolkit.adapt(clearLink, true, true);
		/*
		clearLink.setToolTipText(HelpUIResources
				.getString("SearchPart.clearResults")); //$NON-NLS-1$
		clearLink.setImage(HelpUIResources
				.getImage(IHelpUIConstants.IMAGE_CLEAR));
		clearLink.setBackground(section.getTitleBarGradientBackground());
		clearLink.addHyperlinkListener(new HyperlinkAdapter() {
			public void linkActivated(HyperlinkEvent e) {
				clearResults();
			}
		});
		section.setTextClient(clearLink);
		*/
		resultSorter = new SorterByScore();
		searchResults = toolkit.createFormText(section, false);
		section.setClient(searchResults);
		searchResults.setColor(IFormColors.TITLE, toolkit.getColors().getColor(
				IFormColors.TITLE));
		String topicKey = IHelpUIConstants.IMAGE_FILE_F1TOPIC;
		String nwKey = IHelpUIConstants.IMAGE_NW;
		String searchKey = IHelpUIConstants.IMAGE_HELP_SEARCH;
		searchResults.setImage(topicKey, HelpUIResources.getImage(topicKey));
		searchResults.setImage(nwKey, HelpUIResources.getImage(nwKey));
		searchResults.setImage(searchKey, HelpUIResources.getImage(searchKey));
		searchResults.addHyperlinkListener(new IHyperlinkListener() {

			@Override
			public void linkActivated(HyperlinkEvent e) {
				Object href = e.getHref();
				if (href.equals(CANCEL_HREF)) {
					if (runningJob != null) {
						runningJob.cancel();
						runningJob = null;
					}
					clearResults();
				} else if (href.equals(MORE_HREF)) {
					doMore();
				} else
					doOpenLink(e.getHref());
			}

			@Override
			public void linkEntered(HyperlinkEvent e) {
				DynamicHelpPart.this.parent.handleLinkEntered(e);
			}

			@Override
			public void linkExited(HyperlinkEvent e) {
				DynamicHelpPart.this.parent.handleLinkExited(e);
			}
		});
		searchResults.setText("", false, false); //$NON-NLS-1$
		jobListener = new JobListener();
		Job.getJobManager().addJobChangeListener(jobListener);
	}

	@Override
	public void dispose() {
		Job.getJobManager().removeJobChangeListener(jobListener);
		stop();
		super.dispose();
	}

	@Override
	public void setFocus() {
		if (searchResults!=null)
			searchResults.setFocus();
	}

	@Override
	public void stop () {
		if (runningJob!=null) {
			runningJob.cancel();
			runningJob=null;
		}
	}

	@Override
	public Control getControl() {
		return getSection();
	}

	@Override
	public void init(ReusableHelpPart parent, String id, IMemento memento) {
		this.parent = parent;
		this.id = id;
		parent.hookFormText(searchResults);
	}

	@Override
	public String getId() {
		return id;
	}

	@Override
	public void setVisible(boolean visible) {
		getSection().setVisible(visible);
	}

	void clearResults() {
		if (runningJob != null) {
			runningJob.cancel();
			runningJob = null;
		}
		searchResults.setText("", false, false); //$NON-NLS-1$
		getManagedForm().reflow(true);
	}

	public void startSearch(String newPhrase, IContext excludeContext) {
		if (phrase!=null && phrase.equals(newPhrase))
			return;
		this.phrase = newPhrase;
		this.context = excludeContext;
		if (getSection().isExpanded())
			startInPlaceSearch(phrase, excludeContext);
	}

	private void startInPlaceSearch(final String phrase,
			final IContext excludeContext) {
		Job job = new Job(Messages.SearchPart_dynamicJob) {

			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					try {
						Job.getJobManager().join(IndexerJob.FAMILY,
								monitor);
					} catch (InterruptedException e) {
						// TODO should we do someting here?
					}
					performSearch(phrase, excludeContext, monitor);
					return Status.OK_STATUS;
				} catch (OperationCanceledException e) {
					// it is ok to cancel the search
					return Status.OK_STATUS;
				}
			}
		};
		job.setSystem(true);
		scheduleSearch(job);
	}

	private void performSearch(String phrase, IContext excludeContext,
			IProgressMonitor monitor) {
		SearchQuery searchQuery = new SearchQuery();
		searchQuery.setSearchWord(phrase);
		SearchResults localResults = new SearchResults(null,
				DynamicHelpPart.SHORT_COUNT * 2, Platform.getNL()) {

			@Override
			public void addHits(List<SearchHit> hits, String highlightTerms) {
				// don't highlight any terms for dynamic help part
				super.addHits(hits, ""); //$NON-NLS-1$
			}
		};
		BaseHelpSystem.getSearchManager().search(searchQuery, localResults,
				monitor);
		SearchHit[] hits = localResults.getSearchHits();
		updateResults(phrase, excludeContext, new StringBuffer(), hits);
	}

	void scheduleSearch(Job job) {
		if (runningJob != null) {
			runningJob.cancel();
		}
		StringBuffer buff = new StringBuffer();
		buff.append("<form>"); //$NON-NLS-1$
		buff.append("<p><span color=\""); //$NON-NLS-1$
		buff.append(IFormColors.TITLE);
		buff.append("\">"); //$NON-NLS-1$
		buff.append(Messages.SearchResultsPart_progress);
		buff.append("</span>"); //$NON-NLS-1$
		buff.append("<a href=\""); //$NON-NLS-1$
		buff.append(CANCEL_HREF);
		buff.append("\">"); //$NON-NLS-1$
		buff.append(Messages.SearchResultsPart_cancel);
		buff.append("</a></p>"); //$NON-NLS-1$
		buff.append("</form>"); //$NON-NLS-1$
		searchResults.setText(buff.toString(), true, false);
		getManagedForm().reflow(true);
		runningJob = job;
		job.schedule();
	}

	private void updateResults(final String phrase,
			final IContext excludeContext, final StringBuffer buffer,
			final SearchHit[] hits) {
		if (getSection().isDisposed())
			return;
		getSection().getDisplay().asyncExec(() -> doUpdateResults(phrase, excludeContext, buffer, hits));
	}

	private void doUpdateResults(String phrase, IContext excludeContext, StringBuffer buff, SearchHit[] hits) {
		if (runningJob != null) {
			runningJob.cancel();
		}
		this.phrase = phrase;
		buff.delete(0, buff.length());
		if (hits.length > 0) {
			buff.append("<form>"); //$NON-NLS-1$
			buff.append("<p><span color=\""); //$NON-NLS-1$
			buff.append(IFormColors.TITLE);
			buff.append("\">"); //$NON-NLS-1$
			buff.append(NLS.bind(Messages.SearchResultsPart_label, phrase));
			buff.append("</span></p>"); //$NON-NLS-1$
			resultSorter.sort(null, hits);
			IHelpResource [] excludedTopics = excludeContext!=null?excludeContext.getRelatedTopics():null;

			for (int i = 0; i < hits.length; i++) {
				SearchHit hit = hits[i];
				if (hit.canOpen()) // Do not list Welcome/Cheatsheets etc.
					continue;
				if (isExcluded(hit.getHref(), excludedTopics))
					continue;
				if (i==SHORT_COUNT)
					break;
				buff.append("<li indent=\"21\" style=\"image\" value=\""); //$NON-NLS-1$
				buff.append(IHelpUIConstants.IMAGE_FILE_F1TOPIC);
				buff.append("\">"); //$NON-NLS-1$
				buff.append("<a href=\""); //$NON-NLS-1$
				String href = hit.getHref();
				buff.append(href);
				buff.append("\""); //$NON-NLS-1$
				if (hit.getToc()!=null && !Platform.getWS().equals(Platform.WS_GTK)) {
					buff.append(" alt=\""); //$NON-NLS-1$
					buff.append(EscapeUtils.escapeSpecialChars(hit.getToc().getLabel()));
					buff.append("\""); //$NON-NLS-1$
				}
				buff.append(">"); //$NON-NLS-1$
				buff.append(EscapeUtils.escapeSpecialChars(hit.getLabel()));
				buff.append("</a>"); //$NON-NLS-1$
				buff.append("</li>"); //$NON-NLS-1$
			}
			if (hits.length > 0) {
				buff.append("<p><img href=\""); //$NON-NLS-1$
				buff.append(IHelpUIConstants.IMAGE_HELP_SEARCH);
				buff.append("\"/>"); //$NON-NLS-1$
				buff.append(" <a href=\""); //$NON-NLS-1$
				buff.append(MORE_HREF);
				buff.append("\">"); //$NON-NLS-1$
				buff.append(Messages.SearchResultsPart_moreResults);
				buff.append("</a></p>"); //$NON-NLS-1$
			}
			buff.append("</form>"); //$NON-NLS-1$
			if (!searchResults.isDisposed())
				searchResults.setText(buff.toString(), true, false);
		} else
			if (!searchResults.isDisposed())
				searchResults.setText(NLS.bind(Messages.SearchResultsPart_noHits, phrase) , false, false);
		if (!searchResults.isDisposed())
			getManagedForm().reflow(true);
	}

	private boolean isExcluded(String href, IHelpResource [] excludedTopics) {
		if (excludedTopics==null) return false;
		for (int i=0; i<excludedTopics.length; i++) {
			if (href.startsWith(excludedTopics[i].getHref()))
				return true;
			if (parent.isFilteredByRoles()) {
				if (!HelpBasePlugin.getActivitySupport().isEnabled(href))
					return true;
			}
		}
		return false;
	}

	private void doMore() {
		parent.startSearch(phrase);
	}

	private void doOpenLink(Object href) {
		String url = (String) href;

		if (url.startsWith("nw:")) { //$NON-NLS-1$
			PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(url.substring(3));
		} else
			parent.showURL(url);
	}

	@Override
	public boolean fillContextMenu(IMenuManager manager) {
		return parent.fillFormContextMenu(searchResults, manager);
	}

	@Override
	public boolean hasFocusControl(Control control) {
		return searchResults.equals(control);
	}

	@Override
	public IAction getGlobalAction(String id) {
		if (id.equals(ActionFactory.COPY.getId()))
			return parent.getCopyAction();
		return null;
	}

	@Override
	public void toggleRoleFilter() {
		refilter();
	}

	@Override
	public void refilter() {
		if (phrase!=null && phrase.length() > 0)
			startInPlaceSearch(phrase, context);
	}

	@Override
	public void saveState(IMemento memento) {
	}
}
