/*******************************************************************************
 * Copyright (c) 2005, 2008 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
 *     QNX Software System
 *     Anton Leherbauer (Wind River Systems)
 *     Markus Schorn (Wind River Systems)
 *     Sergey Prigogin (Google)
 *******************************************************************************/
package org.eclipse.photran.internal.cdtinterface.ui.editor;

import java.util.ResourceBundle;

import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.internal.ui.actions.SelectionConverter;
import org.eclipse.cdt.internal.ui.editor.CContentOutlinePage;
import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.editor.ConstructedCEditorMessages;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.IWorkingCopyManager;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.search.ui.actions.TextSearchGroup;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.editors.text.TextEditor;
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.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

/**
 * A {@link TextEditor} that reuses the Outline view from CDT, as well as its document provider
 * and possibly its ruler context menu.  Also uses CDT's resource bundle to support content
 * assist actions.
 *
 * @author Jeff Overbey, mostly copied from {@link CEditor}
 */
/*
 * The parts of this code that don't follow Photran's source formatting conventions were copied
 * from CDT.
 */
@SuppressWarnings("restriction")
public abstract class CDTBasedTextEditor extends TextEditor implements ISelectionChangedListener
{
    ///////////////////////////////////////////////////////////////////////////////////////////////
    // Utility Methods to Be Called in Subclass Constructors
    ///////////////////////////////////////////////////////////////////////////////////////////////

    private TextSearchGroup textSearchGroup;

    protected void useCDTDocumentProvider()
    {
        // We must use the CUIPlugin's document provider in order for the
        // working copy manager in setOutlinePageInput (below) to function correctly.
        setDocumentProvider(CUIPlugin.getDefault().getDocumentProvider());
    }

    protected void useCDTRulerContextMenuID()
    {
        // JO: This gives you a "Toggle Breakpoint" action (and others)
        // when you right-click the Fortran editor's ruler
        setRulerContextMenuId("#CEditorRulerContext"); //$NON-NLS-1$
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////
    // Actions (use CDT resource bundle)
    ///////////////////////////////////////////////////////////////////////////////////////////////

    @Override
    protected void createActions()
    {
        super.createActions();

        // See CEditor#createActions

        final ResourceBundle bundle = ConstructedCEditorMessages.getResourceBundle();

        // Add content assist actions
        
        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$

        action= new TextOperationAction(bundle, "ContentAssistContextInformation.", this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION); //$NON-NLS-1$
        action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
        setAction("ContentAssistContextInformation", action); //$NON-NLS-1$
        markAsStateDependentAction("ContentAssistContextInformation", true); //$NON-NLS-1$
        
        // Add Search > Text actions to the menu bar (added to context menu in #editorContextMenuAboutToShow(IMenuManager) below)
        
        textSearchGroup = new TextSearchGroup(this);
    }
    
    /**
     * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
     */
    @Override
    public void editorContextMenuAboutToShow(IMenuManager menu)
    {
        super.editorContextMenuAboutToShow(menu);
        
        if (textSearchGroup != null) {
            textSearchGroup.fillContextMenu(menu);
        }
    }
    
    @Override
    public void dispose()
    {
        if (textSearchGroup != null) {
            textSearchGroup.dispose();
        }
        super.dispose();
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////
    // Outline View Support
    ///////////////////////////////////////////////////////////////////////////////////////////////

    private CContentOutlinePage fOutlinePage;

    /**
     * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
     */
    @Override
    public Object getAdapter(Class required) {
        if (IContentOutlinePage.class.equals(required)) {
            return getOutlinePage();
        }
        if (required == IShowInTargetList.class) {
            return new IShowInTargetList() {
                @SuppressWarnings("deprecation")
                public String[] getShowInTargetIds() {
                    return new String[] { CUIPlugin.CVIEW_ID, IPageLayout.ID_OUTLINE, IPageLayout.ID_RES_NAV };
                }

            };
        }
        if (required == IShowInSource.class) {
            ICElement ce= null;
            try {
                ce= SelectionConverter.getElementAtOffset(this);
            } catch (CModelException ex) {
                ce= null;
            }
            if (ce != null) {
                final ISelection selection= new StructuredSelection(ce);
                return new IShowInSource() {
                    public ShowInContext getShowInContext() {
                        return new ShowInContext(getEditorInput(), selection);
                    }
                };
            }
        }
        return super.getAdapter(required);
    }

    /**
     * Gets the outline page of the c-editor.
     * @return Outline page.
     */
    public CContentOutlinePage getOutlinePage() {
        if (fOutlinePage == null) {
            fOutlinePage = new CContentOutlinePage(new CEditor());
            fOutlinePage.addSelectionChangedListener(this);
        }
        setOutlinePageInput(fOutlinePage, getEditorInput());
        return fOutlinePage;
    }

    /**
     * Sets an input for the outline page.
     * @param page Page to set the input.
     * @param input Input to set.
     */
    public static void setOutlinePageInput(CContentOutlinePage page, IEditorInput input) {
        if (page != null) {
            IWorkingCopyManager manager = CUIPlugin.getDefault().getWorkingCopyManager();
            IWorkingCopy workingCopy = manager.getWorkingCopy(input);
            if (workingCopy != null)
                page.setInput(workingCopy);
        }
    }

    // ISelectionChangedListener Implementation ///////////////////////////////////////////////////
    // (for updating editor when Outline clicked)

    /**
     * React to changed selection in the outline view.
     * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
     */
    public void selectionChanged(SelectionChangedEvent event) {
        ISelection sel = event.getSelection();
        if (sel instanceof IStructuredSelection) {
            IStructuredSelection selection = (IStructuredSelection) sel;
            Object obj = selection.getFirstElement();
            if (obj instanceof ISourceReference) {
                try {
                    ISourceRange range = ((ISourceReference) obj).getSourceRange();
                    if (range != null) {
                        setSelection(range, !isActivePart());
                    }
                } catch (CModelException e) {
                    // Selection change not applied.
                }
            }
        }
    }

    /**
     * Sets the current editor selection to the source range. Optionally
     * sets the current editor position.
     *
     * @param element the source range to be shown in the editor, can be null.
     * @param moveCursor if true the editor is scrolled to show the range.
     */
    public void setSelection(ISourceRange element, boolean moveCursor) {

        if (element == null) {
            return;
        }

        try {
            IRegion alternateRegion = null;
            int start = element.getStartPos();
            int length = element.getLength();

            // Sanity check sometimes the parser may throw wrong numbers.
            if (start < 0 || length < 0) {
                start = 0;
                length = 0;
            }

            // 0 length and start and non-zero start line says we know
            // the line for some reason, but not the offset.
            if (length == 0 && start == 0 && element.getStartLine() > 0) {
                // We have the information in term of lines, we can work it out.
                // Binary elements return the first executable statement so we have to substract -1
                start = getDocumentProvider().getDocument(getEditorInput()).getLineOffset(element.getStartLine() - 1);
                if (element.getEndLine() > 0) {
                    length = getDocumentProvider().getDocument(getEditorInput()).getLineOffset(element.getEndLine()) - start;
                } else {
                    length = start;
                }
                // create an alternate region for the keyword highlight.
                alternateRegion = getDocumentProvider().getDocument(getEditorInput()).getLineInformation(element.getStartLine() - 1);
                if (start == length || length < 0) {
                    if (alternateRegion != null) {
                        start = alternateRegion.getOffset();
                        length = alternateRegion.getLength();
                    }
                }
            }
            setHighlightRange(start, length, moveCursor);

            if (moveCursor) {
                start = element.getIdStartPos();
                length = element.getIdLength();
                if (start == 0 && length == 0 && alternateRegion != null) {
                    start = alternateRegion.getOffset();
                    length = alternateRegion.getLength();
                }
                if (start > -1 && getSourceViewer() != null) {
                    getSourceViewer().revealRange(start, length);
                    getSourceViewer().setSelectedRange(start, length);
                }
                updateStatusField(ITextEditorActionConstants.STATUS_CATEGORY_INPUT_POSITION);
            }
            return;
        } catch (IllegalArgumentException x) {
            // No information to the user
        } catch (BadLocationException e) {
            // No information to the user
        }

        if (moveCursor)
            resetHighlightRange();
    }

    /**
     * Checks is the editor active part.
     * @return <code>true</code> if editor is the active part of the workbench.
     */
    private boolean isActivePart() {
        IWorkbenchWindow window = getSite().getWorkbenchWindow();
        IPartService service = window.getPartService();
        return (this == service.getActivePart());
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////
    // Utility Methods for Subclasses
    ///////////////////////////////////////////////////////////////////////////////////////////////

    public void forceOutlineViewUpdate()
    {
        try
        {
            CoreModel.getDefault().getCModel().makeConsistent(new NullProgressMonitor());
        }
        catch (CModelException e)
        {
            // Ignore
        }
    }
}
