/*******************************************************************************
 * Copyright (c) 2004, 2013 Mylyn project committers and others.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * https://www.eclipse.org/legal/epl-2.0
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *******************************************************************************/

package org.eclipse.mylyn.internal.cdt.ui.editor;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IParent;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.context.core.AbstractContextListener;
import org.eclipse.mylyn.context.core.ContextChangeEvent;
import org.eclipse.mylyn.context.core.ContextCore;
import org.eclipse.mylyn.context.core.IInteractionElement;
import org.eclipse.mylyn.internal.cdt.ui.CDTStructureBridge;
import org.eclipse.mylyn.internal.cdt.ui.CDTUIBridgePlugin;
import org.eclipse.mylyn.internal.cdt.ui.CDTUiBridge;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.progress.UIJob;

/**
 * @author Mik Kersten
 * @author Jeff Johnston
 * @author Shawn Minto
 */
public class ActiveFoldingListener extends AbstractContextListener {

	private final CEditor editor;

	private ICFoldingStructureProvider updater;

	private static CDTStructureBridge bridge = (CDTStructureBridge) ContextCore.getStructureBridge(CDTStructureBridge.CONTENT_TYPE);

	private boolean enabled = false;

	private boolean isDisposed = false;

	private final IPropertyChangeListener PREFERENCE_LISTENER = new IPropertyChangeListener() {
		public void propertyChange(PropertyChangeEvent event) {
			if (event.getProperty().equals(CDTUIBridgePlugin.AUTO_FOLDING_ENABLED)) {
				if (Boolean.parseBoolean(event.getNewValue().toString())) {
					enabled = true;
				} else {
					enabled = false;
				}
				updateFolding();
			}
		}
	};

	public ActiveFoldingListener(CEditor editor) {
		this.editor = editor;
		ContextCore.getContextManager().addListener(this);
		CDTUIBridgePlugin.getDefault().getPreferenceStore().addPropertyChangeListener(PREFERENCE_LISTENER);

		enabled = CDTUIBridgePlugin.getDefault()
				.getPreferenceStore()
				.getBoolean(CDTUIBridgePlugin.AUTO_FOLDING_ENABLED);
		try {
			Class<CEditor> clazz = CEditor.class;
			Field f = clazz.getDeclaredField("fProjectionModelUpdater"); //$NON-NLS-1$
			f.setAccessible(true);
			ICFoldingStructureProvider updater = (ICFoldingStructureProvider) f.get(editor);
			if (updater instanceof ICFoldingStructureProvider) {
				this.updater = updater;
			} else {
				StatusHandler.log(new Status(IStatus.ERROR, CDTUIBridgePlugin.ID_PLUGIN,
						"Could not install active folding on provider: " + clazz + ", must extend " //$NON-NLS-1$ //$NON-NLS-2$
								+ ICFoldingStructureProvider.class.getName()));
			}
		} catch (Exception e) {
			StatusHandler.log(new Status(IStatus.ERROR, CDTUIBridgePlugin.ID_PLUGIN,
					"Could not install auto folding, reflection denied", e)); //$NON-NLS-1$
		}

		// XXX Look into this, there must be something else that we can do to handle this case
		Job j = new UIJob(Messages.ActiveFoldingListener_Updating_Folding) {

			@Override
			public IStatus runInUIThread(IProgressMonitor monitor) {
				// need the isDisposed since we do the folding asynchronously and the editor could have been closed
				// between the time the job was scheduled and the time it runs
				if (!isDisposed) {
					updateFolding();
				}
				return Status.OK_STATUS;
			}

		};
		j.schedule(1000);
	}

	public void dispose() {
		isDisposed = true;
		ContextCore.getContextManager().removeListener(this);
		CDTUIBridgePlugin.getDefault().getPreferenceStore().removePropertyChangeListener(PREFERENCE_LISTENER);
	}

	public void updateFolding() {
		if (!enabled || !ContextCore.getContextManager().isContextActive()) {
			editor.resetProjection();
		} else if (editor.getEditorInput() == null) {
			return;
		} else {
			try {
				List<ICElement> toExpand = new ArrayList<ICElement>();
				List<ICElement> toCollapse = new ArrayList<ICElement>();

				ICElement element = CDTUiBridge.getInputCElement(editor);
				if (element instanceof ITranslationUnit) {
					ITranslationUnit compilationUnit = (ITranslationUnit) element;
					List<ICElement> allChildren = getAllChildren(compilationUnit);
					for (ICElement child : allChildren) {
						IInteractionElement interactionElement = ContextCore.getContextManager().getElement(
								bridge.getHandleIdentifier(child));
						if (interactionElement != null && interactionElement.getInterest().isInteresting()) {
							toExpand.add(child);
						} else {
							toCollapse.add(child);
						}
					}
				}
				if (updater != null) {
					collapseAllElements();
					Point selectedRange = editor.getViewer().getSelectedRange();
					expandElements(toExpand.toArray(new ICElement[toExpand.size()]));
					editor.getViewer().setSelectedRange(selectedRange.x, selectedRange.y);
					editor.getViewer().revealRange(selectedRange.x, selectedRange.y);
				}
			} catch (Exception e) {
				StatusHandler.log(new Status(IStatus.ERROR, CDTUIBridgePlugin.ID_PLUGIN, "Could not update folding", e)); //$NON-NLS-1$
			}
		}
	}

	protected void collapseElements(ICElement[] elements) {
		for (ICElement element : elements) {
			collapse(element);
		}
	}

	private void collapseAllElements() {
		CSourceViewer viewer = (CSourceViewer) editor.getViewer();
		if (viewer != null) {
			viewer.doOperation(ProjectionViewer.COLLAPSE_ALL);
		}
	}

	private void collapse(ICElement element) {
		// FIXME we do not support collapse right now
//		CSourceViewer viewer = (CSourceViewer) editor.getViewer();
//		editor.setSelection(element);
//		viewer.doOperation(ProjectionViewer.COLLAPSE);
	}

	protected void expandElements(ICElement[] elements) {
		for (ICElement element : elements) {
			expand(element);
		}
	}

	private void expand(ICElement element) {
		CSourceViewer viewer = (CSourceViewer) editor.getViewer();
		if (element instanceof ISourceReference && !(element instanceof ITranslationUnit)) {
			ISourceReference reference = (ISourceReference) element;

			try {
				viewer.exposeModelRange(new Region(reference.getSourceRange().getIdStartPos(), 0));
			} catch (CModelException e) {
				// ignore failures
			}

			// makes things jump around
//			editor.setSelection(element);
//			viewer.doOperation(ProjectionViewer.EXPAND);
		}
	}

	private static List<ICElement> getAllChildren(IParent parentElement) {
		List<ICElement> allChildren = new ArrayList<ICElement>();
		try {
			for (ICElement child : parentElement.getChildren()) {
				allChildren.add(child);
				if (child instanceof IParent) {
					allChildren.addAll(getAllChildren((IParent) child));
				}
			}
		} catch (CModelException e) {
			// ignore failures
		}
		return allChildren;
	}

	public void updateFolding(List<IInteractionElement> elements) {
		try {
			for (IInteractionElement element : elements) {
				if (updater == null || !enabled) {
					return;
				} else {
					Object object = bridge.getObjectForHandle(element.getHandleIdentifier());
					if (object instanceof ICElement) {
						ICElement member = (ICElement) object;
						if (element.getInterest().isInteresting()) {
							expandElements(new ICElement[] { member });
							// expand the next 2 children down (e.g. anonymous types)
							if (!(member instanceof IParent)) {
								return;
							}
							ICElement[] children = ((IParent) member).getChildren();
							if (children.length == 1) {
								expandElements(new ICElement[] { children[0] });
								if (children[0] instanceof IParent) {
									ICElement[] childsChildren = ((IParent) children[0]).getChildren();
									if (childsChildren.length == 1) {
										expandElements(new ICElement[] { childsChildren[0] });
									}
								}
							}
						} else {
							collapseElements(new ICElement[] { member });
						}
					}
				}
			}
		} catch (Exception e) {
			// ignore elements that we can't resolve
		}
	}

	@Override
	public void contextChanged(ContextChangeEvent event) {
		switch (event.getEventKind()) {
		case ACTIVATED:
		case DEACTIVATED:
			if (CDTUIBridgePlugin.getDefault().getPreferenceStore().getBoolean(CDTUIBridgePlugin.AUTO_FOLDING_ENABLED)) {
				updateFolding();
			}
			break;
		case CLEARED:
			if (event.isActiveContext()) {
				if (CDTUIBridgePlugin.getDefault()
						.getPreferenceStore()
						.getBoolean(CDTUIBridgePlugin.AUTO_FOLDING_ENABLED)) {
					updateFolding();
				}
			}
			break;
		case INTEREST_CHANGED:
			updateFolding(event.getElements());
			break;
		}
	}

	public static void resetProjection(CEditor editor2) {
		// ignore

	}
}
