/*******************************************************************************
 * 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.Observable;
import java.util.Observer;

import org.eclipse.help.IHelpResource;
import org.eclipse.help.IIndexEntry;
import org.eclipse.help.IIndexSee;
import org.eclipse.help.IToc;
import org.eclipse.help.ITopic;
import org.eclipse.help.base.AbstractHelpScope;
import org.eclipse.help.internal.base.scope.ScopeUtils;
import org.eclipse.help.internal.base.scope.WorkingSetScope;
import org.eclipse.help.internal.search.federated.LocalHelpScope;
import org.eclipse.help.internal.workingset.WorkingSet;
import org.eclipse.help.search.ISearchScope;
import org.eclipse.help.ui.internal.HelpUIResources;
import org.eclipse.help.ui.internal.IHelpUIConstants;
import org.eclipse.help.ui.internal.Messages;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.forms.AbstractFormPart;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.FormToolkit;

public abstract class HyperlinkTreePart extends AbstractFormPart implements
		IHelpPart {

	public class ScopeObserver implements Observer {

		@Override
		public void update(Observable o, Object arg) {
			if (o instanceof ScopeSetManager) {
				refilter();
			}
		}
	}

	private class ScopeFilter extends ViewerFilter {

		public ScopeFilter(AbstractHelpScope scope) {
			this.scope = scope;
		}

		AbstractHelpScope scope;

		@Override
		public boolean select(Viewer viewer, Object parentElement, Object element) {
			if (element instanceof IToc) {
				return ScopeUtils.showInTree((IToc)element, scope);
			}
			if (element instanceof ITopic) {
				return ScopeUtils.showInTree((ITopic)element, scope);
			}
			if (element instanceof IIndexEntry) {
				return ScopeUtils.showInTree((IIndexEntry)element, scope);
			}
			if (element instanceof IIndexSee) {
				return ScopeUtils.showInTree((IIndexSee)element, scope);
			}
			return true;
		}

	}

	protected ReusableHelpPart parent;

	private String id;

	//private Composite container;

	protected TreeViewer treeViewer;

	private TreeItem lastItem;

	private Cursor handCursor;

	private ScopeObserver scopeObserver;

	/**
	 * @param parent
	 * @param toolkit
	 * @param style
	 */
	public HyperlinkTreePart(Composite parent, final FormToolkit toolkit,
			IToolBarManager tbm) {
		handCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
		/*
		container = toolkit.createComposite(parent);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		layout.verticalSpacing = 0;
		container.setLayout(layout);
		Composite sep = toolkit.createCompositeSeparator(container);
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gd.heightHint = 1;
		sep.setLayoutData(gd);

		treeViewer = new TreeViewer(container, SWT.H_SCROLL | SWT.V_SCROLL);
		*/
		treeViewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);
		treeViewer.getTree().setMenu(parent.getMenu());
		treeViewer.getTree().setForeground(
				toolkit.getHyperlinkGroup().getForeground());
		configureTreeViewer();
		treeViewer.setInput(this);
		treeViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
		treeViewer.addOpenListener(event -> doOpenSelection((IStructuredSelection) event.getSelection()));
		treeViewer.addSelectionChangedListener(
				event -> handleSelectionChanged((IStructuredSelection) event.getSelection()));
		treeViewer.getTree().addMouseListener(new MouseAdapter() {
			long lastTime;

			@Override
			public void mouseUp(MouseEvent e) {
				long eventTime = e.time & 0xFFFFFFFFL;
				if (eventTime - lastTime <= e.display.getDoubleClickTime())
					return;
				if (e.button != 1)
					return;
				lastTime = eventTime;
				Point p = new Point(e.x, e.y);
				TreeItem item = treeViewer.getTree().getItem(p);
				if (item != null) {
					Object obj = item.getData();
					if (obj != null) {
						doOpen(obj);
					}
				}
			}
		});

		treeViewer.getTree().addPaintListener(e -> {
			validateLastItem();
			if (lastItem == null)
				return;
			Rectangle bounds = lastItem.getBounds();
			boolean selected = false;
			TreeItem[] items = lastItem.getParent().getSelection();
			for (int i = 0; i < items.length; i++) {
				if (items[i].equals(lastItem)) {
					selected = true;
					break;
				}
			}
			if (selected)
				e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
			else
				e.gc.setForeground(toolkit.getHyperlinkGroup().getActiveForeground());
			FontMetrics fm = e.gc.getFontMetrics();
			int height = fm.getHeight();
			int lineY = bounds.y + height;
			e.gc.drawLine(bounds.x, lineY, bounds.x + bounds.width - 1, lineY);
		});

		treeViewer.getTree().addMouseTrackListener(new MouseTrackAdapter() {

			@Override
			public void mouseExit(MouseEvent e) {
				validateLastItem();
				if (lastItem != null) {
					TreeItem item = lastItem;
					lastItem = null;
					item.setForeground(null);
				}
			}
		});

		treeViewer.getTree().addMouseMoveListener(e -> {
			Point p = new Point(e.x, e.y);
			TreeItem item = treeViewer.getTree().getItem(p);
			validateLastItem();
			if (item != null) {
				if (lastItem != null) {
					if (!lastItem.equals(item)) {
						lastItem.setForeground(null);
						repaintItem(lastItem);
						updateStatus(null);
						lastItem = null;
					} else
						return;
				}
				Object obj = item.getData();
				treeViewer.getTree().setCursor(handCursor);
				IStructuredSelection ssel = (IStructuredSelection) treeViewer.getSelection();
				if (ssel.getFirstElement() == obj)
					item.setForeground(e.display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
				else
					item.setForeground(toolkit.getHyperlinkGroup().getActiveForeground());
				lastItem = item;
				repaintItem(lastItem);
				if (obj instanceof IHelpResource)
					updateStatus((IHelpResource) obj);
				else
					updateStatus(null);
				return;
			} else if (lastItem != null) {
				lastItem.setForeground(null);
				repaintItem(lastItem);
				lastItem = null;
				updateStatus(null);
			}
			treeViewer.getTree().setCursor(null);
		});
		contributeToToolBar(tbm);
		scopeObserver = new ScopeObserver();
		ScopeState.getInstance().getScopeSetManager().addObserver(scopeObserver);
	}

	@Override
	public void dispose() {
		handCursor.dispose();
		if (scopeObserver != null) {
			ScopeState.getInstance().getScopeSetManager().deleteObserver(scopeObserver);
		}
		super.dispose();
	}

	private void repaintItem(TreeItem item) {
		Rectangle bounds = item.getBounds();
		item.getParent().redraw(bounds.x, bounds.y, bounds.width,
				bounds.height, false);
	}

	protected void contributeToToolBar(IToolBarManager tbm) {
		Action collapseAllAction = new Action() {

			@Override
			public void run() {
				BusyIndicator.showWhile(getControl().getDisplay(), () -> doCollapseAll());
			}
		};
		collapseAllAction.setImageDescriptor(HelpUIResources
				.getImageDescriptor(IHelpUIConstants.IMAGE_COLLAPSE_ALL));
		collapseAllAction
				.setToolTipText(Messages.AllTopicsPart_collapseAll_tooltip);
		tbm.insertBefore("back", collapseAllAction); //$NON-NLS-1$
		tbm.insertBefore("back", new Separator()); //$NON-NLS-1$
	}

	private void doCollapseAll() {
		Object[] expanded = treeViewer.getExpandedElements();
		treeViewer.collapseAll();
		treeViewer.update(expanded, null);
	}

	@Override
	public Control getControl() {
		return treeViewer.getControl();
	}

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

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

	@Override
	public void setVisible(boolean visible) {
		getControl().setVisible(visible);
		if (visible)
			treeViewer.refresh();
	}

	private void doOpenSelection(IStructuredSelection sel) {
		Object obj = sel.getFirstElement();
		if (obj != null) {
			doOpen(obj);
		}
	}

	protected void handleSelectionChanged(IStructuredSelection sel) {
		Object obj = sel.getFirstElement();
		if (lastItem != null && !lastItem.isDisposed()) {
			Object lastObj = lastItem.getData();
			if (lastObj==obj)
				lastItem.setForeground(getControl().getDisplay()
							.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
			else
				lastItem.setForeground(parent.getForm().getToolkit().getHyperlinkGroup()
						.getActiveForeground());
			repaintItem(lastItem);
		}
		if (obj instanceof IHelpResource) {
			IHelpResource res = (IHelpResource) obj;
			updateStatus(res, false);
		} else
			updateStatus(null, false);
	}

	private void updateStatus(IHelpResource res) {
		updateStatus(res, true);
	}

	private void updateStatus(IHelpResource res, boolean defaultToSelection) {
		if (defaultToSelection && res == null) {
			IStructuredSelection ssel = (IStructuredSelection) treeViewer
					.getSelection();
			Object obj = ssel.getFirstElement();
			if (obj instanceof IHelpResource)
				res = (IHelpResource) obj;
		}
		if (res != null) {
			String label = res.getLabel();
			String href = getHref(res);
			HyperlinkTreePart.this.parent.handleLinkEntered(new HyperlinkEvent(
					treeViewer.getTree(), href, label, SWT.NULL));
		} else {
			HyperlinkTreePart.this.parent.handleLinkExited(null);
		}
	}

	protected String getHref(IHelpResource res) {
		return res.getHref();
	}

	protected abstract void configureTreeViewer();

	protected abstract void doOpen(Object obj);

	protected void postUpdate(final Object obj) {
		treeViewer.getControl().getDisplay().asyncExec(() -> treeViewer.update(obj, null));
	}

	@Override
	public boolean fillContextMenu(IMenuManager manager) {
		return parent.fillSelectionProviderMenu(treeViewer, manager,
				canAddBookmarks());
	}

	protected abstract boolean canAddBookmarks();

	@Override
	public boolean hasFocusControl(Control focusControl) {
		return treeViewer.getControl().equals(focusControl);
	}

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

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

	@Override
	public void stop() {
	}

	private void validateLastItem() {
		if (lastItem != null && lastItem.isDisposed())
			lastItem = null;
	}

	@Override
	public void refilter() {
		ScopeSetManager manager = ScopeState.getInstance().getScopeSetManager();
		ScopeSet set = manager.getActiveSet();
		EngineDescriptor[] engineDescriptors = parent.getEngineManager().getDescriptors();
		ISearchScope scope = null;
		for (int i = 0; i < engineDescriptors.length; i++) {
			final EngineDescriptor ed = engineDescriptors[i];
			if (ed.getEngineTypeId().equals("org.eclipse.help.ui.localSearch") //$NON-NLS-1$
				  && ed.getEngine() != null) {
				scope = ed.createSearchScope(set.getPreferenceStore());
			}
		}
		WorkingSet workingSet = null;
		LocalHelpScope localScope = (LocalHelpScope) scope;
		workingSet = localScope.getWorkingSet() ;
		treeViewer.resetFilters();
		if (workingSet != null) {
			WorkingSetScope helpScope = new WorkingSetScope(workingSet, set.getName());
		    treeViewer.addFilter(new ScopeFilter(helpScope));
		}
		treeViewer.refresh();
	}
}
