/*******************************************************************************
 * Copyright (c) 2004, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Miguel Garcia (Tech Univ Hamburg-Harburg) - customization for EMF Generics
 *******************************************************************************/

package org.eclipse.emf.emfatic.ui.editor;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;

import org.eclipse.core.resources.IFile;
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.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.emfatic.core.generator.ecore.EcoreGenerator;
import org.eclipse.emf.emfatic.core.generics.util.OneToManyMap;
import org.eclipse.emf.emfatic.core.generics.util.OneToOneMap;
import org.eclipse.emf.emfatic.core.lang.gen.ast.BoundExceptWildcard;
import org.eclipse.emf.emfatic.core.lang.gen.ast.ClassDecl;
import org.eclipse.emf.emfatic.core.lang.gen.ast.CompUnit;
import org.eclipse.emf.emfatic.core.lang.gen.ast.EmfaticASTNode;
import org.eclipse.emf.emfatic.core.lang.gen.ast.Reference;
import org.eclipse.emf.emfatic.core.lang.gen.ast.TypeWithMulti;
import org.eclipse.emf.emfatic.core.lang.gen.ast.Wildcard;
import org.eclipse.emf.emfatic.ui.EmfaticUIPlugin;
import org.eclipse.emf.emfatic.ui.hyperlinks.EmfaticHyperlinkDetector;
import org.eclipse.emf.emfatic.ui.outline.EmfaticContentOutlinePage;
import org.eclipse.emf.emfatic.ui.partition.EmfaticDocumentProvider;
import org.eclipse.emf.emfatic.ui.preferences.PreferenceConstants;
import org.eclipse.emf.emfatic.ui.redsquiggles.EmfaticCSTChangeListener;
import org.eclipse.emf.emfatic.ui.views.TypesView;
import org.eclipse.gymnast.runtime.core.ast.ASTNode;
import org.eclipse.gymnast.runtime.core.outline.OutlineNode;
import org.eclipse.gymnast.runtime.ui.editor.LDTEditor;
import org.eclipse.gymnast.runtime.ui.editor.LDTSourceViewerConfiguration;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.ISourceViewerExtension2;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.texteditor.ContentAssistAction;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;

public class EmfaticEditor extends LDTEditor implements IShowInTargetList,
		IShowInSource {

	private EmfaticEditorSelectionListener selectionListener = new EmfaticEditorSelectionListener(
			this);
	private EmfaticContentOutlinePage _emfaticContentOutlinePage;
	private EmfaticKeyListener _keyListener = null;
	private OutlineNode[] lastShownOutlineNodes = new OutlineNode[0];
	private IViewReference _typesViewReference = null;
	private HighlightingManager highlightingManager;

	public EmfaticEditor() {
		addParseTreeChangedListener(new EmfaticCSTChangeListener(this));
		setDocumentProvider(new EmfaticDocumentProvider());
		
		highlightingManager = new HighlightingManager();
		
		PlatformUI.getWorkbench().getThemeManager().addPropertyChangeListener(new ThemeChangeListener() {
			@Override
			public void themeChange() {
				highlightingManager.initialiseDefaultColors();
				refreshText();
			}
		});

		highlightingManager.getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() {
			@Override
			public void propertyChange(PropertyChangeEvent event) {
				if (highlightingManager.isColorPreference(event.getProperty())) {
					refreshText();
				}
			}
		});
	}

	public void refreshText() {
		ISourceViewer viewer= getSourceViewer();
		if (!(viewer instanceof ISourceViewerExtension2))
			return;
		((ISourceViewerExtension2)viewer).unconfigure();
		initializeEditor();
		viewer.configure(getSourceViewerConfiguration());
	}

	protected LDTSourceViewerConfiguration createSourceViewerConfiguration() {
		return new EmfaticSourceViewerConfiguration(this);
	}
	
	@Override
	public void doSave(IProgressMonitor progressMonitor) {
		super.doSave(progressMonitor);
		if(EmfaticUIPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.AUTO_GENERATE_ECORE))
			generateEcoreFile();
	}

	/**
	 * Creates/updates the ecore file when saving the emf file
	 */
	private void generateEcoreFile() {
		IEditorInput input = getEditorInput();
		if(input instanceof IFileEditorInput) {
			final IFile file=((IFileEditorInput)input).getFile();
			// use a job to create/override the ecore file...
			Job job = new Job("Generating Ecore Model for " + file.getName()) {
				protected IStatus run(IProgressMonitor monitor) {
				    new EcoreGenerator().generate(file, monitor);
					return Status.OK_STATUS;
				}				
			};
			// we might create a new file in the container
			job.setRule(file.getParent());
			job.schedule();
		}
	}

	@Override
	protected EmfaticOutlineConfiguration createOutlineConfiguration() {
		return new EmfaticOutlineConfiguration(this);
	}

	private ProjectionSupport projectionSupport;
	private ProjectionAnnotationModel annotationModel;
	private Annotation[] oldAnnotations;

	/**
	 * folding support, as explained in
	 * http://www.eclipse.org/articles/Article-Folding-in-Eclipse-Text-Editors/folding.html
	 */
	public void updateFoldingStructure(List<Position> positions) {
		initFoldingSupport();
		Annotation[] annotations = new Annotation[positions.size()];
		// the new (annotation, position) pairs
		HashMap<ProjectionAnnotation, Position> newAnnotations = new HashMap<ProjectionAnnotation, Position>();
		for (int i = 0; i < positions.size(); i++) {
			ProjectionAnnotation annotation = new ProjectionAnnotation();
			newAnnotations.put(annotation, positions.get(i));
			annotations[i] = annotation;
		}
		annotationModel.modifyAnnotations(oldAnnotations, newAnnotations, null);
		oldAnnotations = annotations;
	}

	/**
	 * folding support, as explained in
	 * http://www.eclipse.org/articles/Article-Folding-in-Eclipse-Text-Editors/folding.html
	 * 
	 */
	public void createPartControl(Composite parent) {
		super.createPartControl(parent);
		initFoldingSupport();
		selectionListener.install(getSelectionProvider());
		_keyListener = new EmfaticKeyListener(this);
		getSourceViewer().getTextWidget().addKeyListener(_keyListener);
	}

	private void initFoldingSupport() {
		if (annotationModel == null) {
			ProjectionViewer viewer = (ProjectionViewer) getSourceViewer();
			projectionSupport = new ProjectionSupport(viewer,
					getAnnotationAccess(), getSharedColors());
			// see AntEditor for hovers displaying HTML
			/*
			 * A summary is an annotation that gets created out of all
			 * annotations with a type that has been registered through this
			 * method and that are inside the folded region.
			 * 
			 */
			projectionSupport
					.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error");
			projectionSupport
					.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning");
			projectionSupport.install();
			// turn projection mode on
			viewer.doOperation(ProjectionViewer.TOGGLE);
			annotationModel = viewer.getProjectionAnnotationModel();
		}
	}

	/**
	 * folding support, as explained in
	 * http://www.eclipse.org/articles/Article-Folding-in-Eclipse-Text-Editors/folding.html
	 * 
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite,
	 *      org.eclipse.jface.text.source.IVerticalRuler, int)
	 */
	protected ISourceViewer createSourceViewer(Composite parent,
			IVerticalRuler ruler, int styles) {
		fAnnotationAccess = getAnnotationAccess();
		fOverviewRuler = createOverviewRuler(getSharedColors());
		ISourceViewer viewer = new ProjectionViewer(parent, ruler,
				getOverviewRuler(), isOverviewRulerVisible(), styles);
		// ensure decoration support has been created and configured.
		getSourceViewerDecorationSupport(viewer);
		// viewer.addTextListener(textListener);
		return viewer;
	}

	/*
	 * LDT has already support for this (as well as for ITextListener). I
	 * realized after adding it here
	 */
	public EmfaticASTNode getClosestEnclosingASTNodeAt(int offset, Class<?> filter) {
		return getClosestEnclosingASTNodeAt(offset, 0, filter);
	}

	public EmfaticASTNode getClosestEnclosingASTNodeAt(int offset, int length,
			Class<?> filter) {
		EmfaticASTNode node = getClosestEnclosingASTNodeAtWithin(
				new HashSet<ASTNode>(), getParseRoot(), offset, length, filter);
		return node;
	}

	private EmfaticASTNode getClosestEnclosingASTNodeAtWithin(Set<ASTNode>seenNodes, ASTNode within,
			int offset, int length, Class<?> filter) {
		if (within == null) {
			return null;
		}
		if(seenNodes.contains(within))
			return null;
		seenNodes.add(within);
		ASTNode node = within.getNodeAt(offset, 0);
		// search within the for any ASTNode
		for (int i = offset + 1; (node == null) && (i < offset + length); i++) {
			node = getParseRoot().getNodeAt(i, 0);
		}
		if (node != null) {
			/*
			 * An outer node fulfilling the filter condition may have been found
			 * which hides a more specific node also fulfilling the filter
			 */
			if (node.getChildren().length > 0) {
				for (ASTNode child : node.getChildren()) {
					ASTNode innerNode = getClosestEnclosingASTNodeAtWithin(
							seenNodes, child, offset, length, filter);
					if (innerNode != null) {
						node = innerNode;
						break;
					}
				}
			}
			/*
			 * search upwards till finding a node of type filter, or reaching
			 * the root
			 */
			while (!filter.isInstance(node) && (node.getParent() != null)) {
				node = node.getParent();
			}
		}
		if (filter.isInstance(node)) {
			return (EmfaticASTNode) node;
		} else {
			return null;
		}
	}

	@Override
	public void dispose() {
		if (selectionListener != null) {
			selectionListener.uninstall(getSelectionProvider());
			selectionListener = null;
		}
		super.dispose();
	}

	public OneToOneMap<ASTNode, EObject> getCstDecl2EcoreAST() {
		CompUnit compUnit = (CompUnit) getParseRoot();
		if (compUnit != null) {
			return compUnit.getCstDecl2EcoreAST();
		}
		return null;
	}

	public OneToManyMap<EObject, ASTNode> getEcoreDecl2CstUse() {
		CompUnit compUnit = (CompUnit) getParseRoot();
		if (compUnit != null) {
			return compUnit.getEcoreDecl2CstUse();
		}
		return null;
	}

	public IDocument getDocument() {
		IDocument doc = null;
		if (getDocumentProvider() == null) {
			return doc;
		}
		doc = getDocumentProvider().getDocument(getEditorInput());
		return doc;
	}

	public void openTarget(EmfaticASTNode linkTarget) {
		setSelection(linkTarget, true);
	}

	public void setSelection(EmfaticASTNode reference, boolean moveCursor) {
		if (reference == null) {
			if (moveCursor) {
				resetHighlightRange();
				markInNavigationHistory();
			}
			return;
		}

		if (moveCursor) {
			markInNavigationHistory();
		}

		ISourceViewer sourceViewer = getSourceViewer();
		if (sourceViewer == null) {
			return;
		}
		StyledText textWidget = sourceViewer.getTextWidget();
		if (textWidget == null) {
			return;
		}

		try {
			int offset = reference.getRangeStart();
			if (offset < 0) {
				return;
			}
			int length = reference.getRangeLength();
			textWidget.setRedraw(false);
			if (length > 0) {
				setHighlightRange(offset, length, moveCursor);
			}
			if (!moveCursor) {
				return;
			}
			if (offset > -1 && length > 0) {
				sourceViewer.revealRange(offset, length);
				// Selected region begins one index after offset
				sourceViewer.setSelectedRange(offset, length);
				markInNavigationHistory();
			}
		} catch (IllegalArgumentException x) {
			x.printStackTrace();
		} finally {
			textWidget.setRedraw(true);
		}
	}

	public void setContentOutlinePage(
			EmfaticContentOutlinePage emfaticContentOutlinePage) {
		_emfaticContentOutlinePage = emfaticContentOutlinePage;

	}

	protected EmfaticContentOutlinePage getContentOutlinePage() {
		return _emfaticContentOutlinePage;
	}

	public EObject getEcoreDeclAtCursor() {
		ISelection selection = getSelectionProvider().getSelection();
		if (selection instanceof ITextSelection) {
			ITextSelection ts = (ITextSelection) selection;
			int offset = ts.getOffset();
			int length = ts.getLength();
			ReferedEcoreDecl red = getReferedEcoreDecl(offset, length);
			if (red == null || red.ecoreDecl == null) {
				return null;
			}
			EObject ecoreDecl = red.ecoreDecl;
			return ecoreDecl;
		}
		return null;
	}

	public EObject gotoDeclaration() {
		EObject ecoreDecl = getEcoreDeclAtCursor();
		if (ecoreDecl == null) {
			return null;
		}
		EmfaticASTNode landingPlace = EmfaticHyperlinkDetector.getLandingPlace(
				ecoreDecl, this);
		setSelection(landingPlace, true);
		return ecoreDecl;
	}

	public ReferedEcoreDecl getReferedEcoreDecl(int offset, int length) {
		/*
		 * first chance: Wildcard
		 */
		EmfaticASTNode node = getClosestEnclosingASTNodeAt(offset, length,
				Wildcard.class);
		if (node != null) {
			// it can still be an unbounded wildcard
			node = ((Wildcard) node).getBoundExceptWildcard();
		}
		if (node == null) {
			// second chance: BoundExceptWildcard
			node = getClosestEnclosingASTNodeAt(offset, length,
					BoundExceptWildcard.class);
			if (node == null) {
				// thir chance: TypeWithMult
				node = getClosestEnclosingASTNodeAt(offset, length,
						TypeWithMulti.class);
				if (node == null) {
					// fourth chance: Reference (for an opposite reference)
					node = getClosestEnclosingASTNodeAt(offset, length,
							Reference.class);
					if (node == null) {
						return null;
					}
					node = ((Reference) node).getOppositeName();
				} else {
					// leave a BoundExceptWildcard in node
					node = ((TypeWithMulti) node).getName();
				}
			}
		}
		// actually the QualifiedID was placed in the bigMap
		if (node instanceof BoundExceptWildcard) {
			node = ((BoundExceptWildcard) node)
					.getRawTNameOrTVarOrParamzedTName();
		}
		EObject ecoreDecl = getEcoreDecl2CstUse().getInv(node);
		ReferedEcoreDecl res = new ReferedEcoreDecl();
		res.ecoreDecl = ecoreDecl;
		res.node = node;
		return res;
	}

	public class ReferedEcoreDecl {
		public EObject ecoreDecl;
		public EmfaticASTNode node;
	}

	protected void createActions() {
		super.createActions();
		ResourceBundle bundle = EmfaticEditorMessages.getResourceBundle();

		IAction action = new ContentAssistAction(bundle,
				"ContentAssistProposal.", this); //$NON-NLS-1$
		action
				.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
		setAction("ContentAssistProposal", action); //$NON-NLS-1$
		markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$
		// TODO PlatformUI.getWorkbench().getHelpSystem().setHelp(action,
		// helpContextId);

	}

	@Override
	public OutlineNode[] getOutlineElements() {
		OutlineNode[] candidateOutlineNodes = super.getOutlineElements();
		if (candidateOutlineNodes != null && candidateOutlineNodes.length > 0) {
			lastShownOutlineNodes = candidateOutlineNodes;
		}
		return lastShownOutlineNodes;
	}

	/**
	 * see p. 467 and p. 499 of JDGE 2nd Ed
	 */
	public String[] getShowInTargetIds() {
		EObject ecoreDecl = getEcoreDeclAtCursor();
		String[] res = null;
		if (ecoreDecl == null) {
			ecoreDecl = getEcoreDeclAtCursor2();
			if (ecoreDecl == null) {
				res = new String[] {};
			} else {
				res = new String[] {TypesView.ID };
			}
			
		} else {
			res = new String[] { TypesView.ID };
		}
		return res;
	}

	private EObject getEcoreDeclAtCursor2() {
		ISelection selection = getSelectionProvider().getSelection();
		if (selection instanceof ITextSelection) {
			ITextSelection ts = (ITextSelection) selection;
			int offset = ts.getOffset();
			//int length = ts.getLength();
			ASTNode node = getClosestEnclosingASTNodeAt(offset, ClassDecl.class);
			if (node == null) {
				return null; 
			}
			EObject ecoreDecl = getCstDecl2EcoreAST().get(node);
			return ecoreDecl;
		}
		return null;

	}

	/**
	 * see p. 467 and p. 499 of JDGE 2nd Ed
	 */
	public ShowInContext getShowInContext() {
		if (getEditorInput() instanceof FileEditorInput) {
			FileEditorInput fei = (FileEditorInput) getEditorInput();
			return new ShowInContext(fei.getFile(), getSelectionProvider().getSelection());
		}
		return new ShowInContext(getEditorInput(), getSelectionProvider().getSelection());
	}

	public void showInTypeHierarchy(EClass openedDecl) {
		if (!(openedDecl instanceof EClass)) {
			return;
		}
		TypesView tv = getTypesView();
		if (tv == null) {
			return;
		}
		WeakReference<EClass> wrC = new WeakReference<EClass>(
				(EClass) openedDecl);
		tv.setInput(wrC, true);
	}

	public TypesView getTypesView() {
		// 1) try if there's a cached reference
		if (_typesViewReference != null) {
			TypesView tv = (TypesView) _typesViewReference.getView(false);
			if (tv != null) {
				return tv;
			}
		}
		// 2) look for the view opened by the user
		IWorkbenchPage wp = PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow().getActivePage();
		IViewReference _typesViewReference = wp.findViewReference(TypesView.ID);
		if (_typesViewReference != null) {
			TypesView tv = (TypesView) _typesViewReference.getView(true);
			if (tv != null) {
				return tv;
			}
		}
		// 3) open it programatically
		try {
			IViewPart tv = wp.showView(TypesView.ID);
			return (TypesView) tv;
		} catch (PartInitException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

}
