/*******************************************************************************
 * Copyright (c) 2009 Shane Clarke.
 * 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:
 *    Shane Clarke - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.internal.jaxws.ui.views;

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

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.ILocalVariable;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jst.ws.annotations.core.AnnotationDefinition;
import org.eclipse.jst.ws.annotations.core.AnnotationsManager;
import org.eclipse.jst.ws.annotations.core.utils.AnnotationUtils;
import org.eclipse.jst.ws.internal.jaxws.ui.JAXWSUIMessages;
import org.eclipse.jst.ws.internal.jaxws.ui.JAXWSUIPlugin;
import org.eclipse.jst.ws.internal.jaxws.ui.actions.AnnotationsViewFilterAction;
import org.eclipse.jst.ws.internal.jaxws.ui.widgets.ClasspathComposite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.INullSelectionListener;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.texteditor.ITextEditor;

public class AnnotationsView extends ViewPart implements INullSelectionListener, IPartListener2 {
    private PageBook pageBook;
    private Tree annotationTree;

    private Composite notAvaiableComposite;
    private ClasspathComposite setupClasspathComposite;

    private TreeViewer annotationTreeViewer;

    private IMemento memento;

    private AnnotationsViewFilterAction annotationsViewFilterAction;

    public AnnotationsView() {
    }

    @Override
    public void createPartControl(Composite parent) {
        pageBook = new PageBook(parent, SWT.NONE);

        annotationTree = new Tree(pageBook, SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL
                | SWT.H_SCROLL);
        annotationTreeViewer = new TreeViewer(annotationTree);

        annotationTreeViewer.setContentProvider(new AnnotationsViewContentProvider());
        annotationTreeViewer.getTree().setHeaderVisible(true);
        annotationTreeViewer.getTree().setLinesVisible(true);

        TreeViewerColumn annotationsViewerColumn = new TreeViewerColumn(annotationTreeViewer, SWT.NONE);
        annotationsViewerColumn.setLabelProvider(new AnnotationsColumnLabelProvider());
        TreeColumn annotationsColumn = annotationsViewerColumn.getColumn();
        annotationsColumn.setWidth(400);
        annotationsColumn.setMoveable(false);
        annotationsColumn.setText(JAXWSUIMessages.ANNOTATIONS_VIEW_ANNOTATIONS_COLUMN_NAME);

        TreeViewerColumn valuesViewerColumn = new TreeViewerColumn(annotationTreeViewer, SWT.NONE);
        valuesViewerColumn.setLabelProvider(new AnnotationsValuesColumnLabelProvider(annotationTreeViewer));
        valuesViewerColumn.setEditingSupport(new AnnotationsValuesEditingSupport(this, annotationTreeViewer));
        TreeColumn valuesColumn = valuesViewerColumn.getColumn();
        valuesColumn.setWidth(400);
        valuesColumn.setMoveable(false);
        valuesColumn.setAlignment(SWT.LEFT);
        valuesColumn.setText(JAXWSUIMessages.ANNOTATIONS_VIEW_ANNOTATIONS_VALUES_COLUMN_NAME);

        //Selection Service
        startListeningForSelectionChanges();
        //Part Service
        getViewSite().getWorkbenchWindow().getPartService().addPartListener(this);

        contributeToActionBars();

        notAvaiableComposite = new Composite(pageBook, SWT.NONE);
        GridLayout gridLayout = new GridLayout();
        notAvaiableComposite.setLayout(gridLayout);
        GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        notAvaiableComposite.setLayoutData(gridData);
        notAvaiableComposite.setBackground(getBackgroundColor(parent));
        Label label = new Label(notAvaiableComposite, SWT.NONE);
        label.setBackground(getBackgroundColor(parent));
        label.setText(JAXWSUIMessages.ANNOTATIONS_VIEW_ANNOTATIONS_NOT_AVAILABLE_ON_SELECTION);

        annotationTreeViewer.setComparator(new ViewerComparator() {
            @Override
            public int compare(Viewer viewer, Object obj1, Object obj2) {
                if (obj1 instanceof Class<?> && ((Class<?>) obj1).isAnnotation()
                        && obj2 instanceof Class<?> && ((Class<?>) obj2).isAnnotation()) {
                    return ((Class<? extends java.lang.annotation.Annotation>) obj1).getCanonicalName().compareTo(
                            ((Class<? extends java.lang.annotation.Annotation>) obj2).getCanonicalName());
                }
                if (obj1 instanceof Method && obj2 instanceof Method) {
                    return ((Method)obj1).getName().compareTo(((Method)obj2).getName());
                }
                return super.compare(viewer, obj1, obj2);
            }
        });

        //TODO Add a Faceted Project composite
        setupClasspathComposite = new ClasspathComposite(pageBook, SWT.NONE);

        pageBook.showPage(notAvaiableComposite);
    }

    private Color getBackgroundColor(Composite parent) {
        if (Display.getDefault().getHighContrast()) {
            return parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
        } else {
            return parent.getDisplay().getSystemColor(SWT.COLOR_WHITE);
        }
    }

    private void startListeningForSelectionChanges() {
        getViewSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(this);
    }

    private void stopListeningForSelectionChanges() {
        getViewSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(this);
    }

    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
        IWorkbenchPage workbenchPage = getViewSite().getWorkbenchWindow().getActivePage();

        if (workbenchPage == null) {
            return;
        }

        IWorkbenchPartReference workbenchPartReference = workbenchPage.getActivePartReference();

        if (workbenchPartReference == null || workbenchPartReference.getId().equals(getViewSite().getId())
                || !workbenchPartReference.getId().equals(JavaUI.ID_CU_EDITOR)) {
            return;
        }

        IEditorPart editorPart = workbenchPage.getActiveEditor();

        IFileEditorInput fileEditorInput = (IFileEditorInput) editorPart.getEditorInput();

        if (selection instanceof TextSelection) {
            ITextSelection txtSelection = (TextSelection) selection;
            ICompilationUnit compilationUnit = JavaCore.createCompilationUnitFrom(fileEditorInput.getFile());
            if (compilationUnit != null) {
                updateView(compilationUnit, txtSelection);
            }
        }
    }

    public void updateView(IJavaElement javaElement, ITextSelection textSelection) {
        TreePath[] expandedTreePaths = annotationTreeViewer.getExpandedTreePaths();

        IJavaProject javaProject = javaElement.getJavaProject();

        if (!checkClasspath(javaProject)) {
            annotationTreeViewer.setInput(null);
            pageBook.showPage(setupClasspathComposite);
            return;
        }

        pageBook.showPage(annotationTree);

        int offset = textSelection.getOffset();
        try {
            ICompilationUnit compilationUnit = null;
            if (javaElement instanceof ICompilationUnit) {
                compilationUnit = (ICompilationUnit)javaElement;
                javaElement = compilationUnit.getElementAt(offset);
            }

            if (javaElement == null) {
                return;
            }

            if (javaElement.getElementType() == IJavaElement.PACKAGE_DECLARATION) {
                if (javaElement.getResource().getName().equals("package-info.java")) { //$NON-NLS-1$
                    setInput(javaElement);
                } else {
                    annotationTreeViewer.setInput(null);
                }
            }

            if (javaElement.getElementType() == IJavaElement.IMPORT_DECLARATION) {
                annotationTreeViewer.setInput(null);
            }

            if (javaElement.getElementType() == IJavaElement.TYPE) {
                IType type = (IType)javaElement;
                if (!type.isMember()) {
                    setInput(type);
                } else {
                    annotationTreeViewer.setInput(null);
                }
            }

            if (javaElement.getElementType() == IJavaElement.FIELD) {
                IField field = (IField)javaElement;
                if (!field.getDeclaringType().isMember()) {
                    setInput(field);
                } else {
                    annotationTreeViewer.setInput(null);
                }
            }

            if (javaElement.getElementType() == IJavaElement.METHOD) {
                IMethod method = (IMethod) javaElement;
                if (!method.getDeclaringType().isMember()) {
                    ILocalVariable localVariable = AnnotationUtils.getLocalVariable(method, offset);
                    if (localVariable != null) {
                        setInput(localVariable);
                    } else {
                        setInput(method);
                    }
                } else {
                    annotationTreeViewer.setInput(null);
                }
            }
            annotationTreeViewer.refresh();
        } catch (JavaModelException jme) {
            JAXWSUIPlugin.log(jme.getStatus());
        }

        annotationTreeViewer.setExpandedTreePaths(expandedTreePaths);
    }

    private void setInput(IJavaElement javaElement) {
        if (annotationTreeViewer.getInput() == null) {
            annotationTreeViewer.setInput(javaElement);
        } else if (!annotationTreeViewer.getInput().equals(javaElement)) {
            annotationTreeViewer.setInput(javaElement);
        }
    }

    private boolean checkClasspath(IJavaProject javaProject) {
        List<String> categories = new ArrayList<String>();
        categories.addAll(AnnotationsManager.getAnnotationCategories());
        ViewerFilter[] viewerFilters = annotationTreeViewer.getFilters();
        for (ViewerFilter viewerFilter : viewerFilters) {
            if (viewerFilter instanceof AnnotationsViewCategoryFilter) {
                categories.removeAll(((AnnotationsViewCategoryFilter)viewerFilter).getCategories());
            }
        }

        boolean jwsReady = true;
        try {
            for (String category : categories) {
                List<AnnotationDefinition> annotationDefinitions = AnnotationsManager
                .getAnnotationsByCategory(category);
                String className = annotationDefinitions.get(0).getAnnotationClassName();
                if (javaProject.findType(className) == null) {
                    jwsReady = false;
                    setupClasspathComposite.updateLibraryLabel(category);
                    break;
                } else {
                    continue;
                }
            }
        } catch (JavaModelException jme) {
            JAXWSUIPlugin.log(jme.getStatus());
        }
        return jwsReady;
    }

    public void partActivated(IWorkbenchPartReference partRef) {
        IWorkbenchPart workbenchPart = partRef.getPart(false);
        if (partRef.getId().equals(JavaUI.ID_CU_EDITOR)) {
            javaEditorActivated((IEditorPart) workbenchPart);
        } else if (partRef.getId().equals(getViewSite().getId())) {
            annotationsViewActivated();
        } else {
            clearAnnotationsView();
        }
    }

    public void partDeactivated(IWorkbenchPartReference partRef) {
    }

    public void partVisible(IWorkbenchPartReference partRef) {
        if (partRef.getId().equals(getViewSite().getId())) {
            startListeningForSelectionChanges();
        }
    }

    public void partHidden(IWorkbenchPartReference partRef) {
        if (partRef.getId().equals(getViewSite().getId())) {
            stopListeningForSelectionChanges();
        }
    }

    public void partOpened(IWorkbenchPartReference partRef) {
    }

    public void partClosed(IWorkbenchPartReference partRef) {
        if (partRef.getId().equals(JavaUI.ID_CU_EDITOR)) {
            if (getViewSite() != null) {
                IWorkbenchWindow workbenchWindow = getViewSite().getWorkbenchWindow();
                if (workbenchWindow != null) {
                    IWorkbenchPage workbenchPage = workbenchWindow.getActivePage();
                    if (workbenchPage != null) {
                        IEditorPart editorPart = workbenchPage.getActiveEditor();
                        try {
                            if (editorPart == null
                                    || !(editorPart.getEditorInput() instanceof IFileEditorInput)
                                    || !IDE.getEditorDescriptor(
                                            ((IFileEditorInput) editorPart.getEditorInput()).getFile()).getId()
                                            .equals(JavaUI.ID_CU_EDITOR)) {
                                clearAnnotationsView();
                            }
                        } catch (PartInitException pie) {
                            JAXWSUIPlugin.log(pie.getStatus());
                        }
                    }
                }
            }
        }
    }

    public void partBroughtToTop(IWorkbenchPartReference partRef) {
    }

    public void partInputChanged(IWorkbenchPartReference partRef) {
    }

    private void clearAnnotationsView() {
        annotationTreeViewer.setInput(null);
        annotationTreeViewer.refresh();
        pageBook.showPage(notAvaiableComposite);
    }

    private void javaEditorActivated(IEditorPart editorPart) {
        ITextEditor textEditor = (ITextEditor) editorPart;
        ISelection selection = textEditor.getSelectionProvider().getSelection();
        IJavaElement javaElement = (IJavaElement) editorPart.getEditorInput().getAdapter(IJavaElement.class);
        if (javaElement != null) {
            pageBook.showPage(annotationTree);
            updateView(javaElement, (ITextSelection) selection);
            selectionChanged(editorPart, selection);
        }
    }

    private void annotationsViewActivated() {
        try {
            IEditorPart editorPart = getViewSite().getPage().getActiveEditor();
            if (editorPart != null) {
                IEditorInput editorInput = editorPart.getEditorInput();
                if (editorInput instanceof IFileEditorInput) {
                    IFile file = ((IFileEditorInput) editorInput).getFile();
                    IEditorDescriptor editorDescriptor = IDE.getEditorDescriptor(file);
                    if (editorDescriptor.getId().equals(JavaUI.ID_CU_EDITOR)) {
                        javaEditorActivated(editorPart);
                    }
                }
            }
        } catch (PartInitException pie) {
            JAXWSUIPlugin.log(pie.getStatus());
        }
    }

    @Override
    public void dispose() {
        super.dispose();
        stopListeningForSelectionChanges();
        getViewSite().getWorkbenchWindow().getPartService().removePartListener(this);
    }

    @Override
    public void init(IViewSite site, IMemento memento) throws PartInitException {
        super.init(site, memento);
        this.memento = memento;
    }

    @Override
    public void saveState(IMemento memento) {
        super.saveState(memento);
        annotationsViewFilterAction.saveState(memento);
    }

    private void contributeToActionBars() {
        IActionBars bars = getViewSite().getActionBars();
        fillLocalPullDown(bars.getMenuManager());
    }

    private void fillLocalPullDown(IMenuManager manager) {
        annotationsViewFilterAction = new AnnotationsViewFilterAction(this, annotationTreeViewer,
                JAXWSUIMessages.ANNOTATIONS_VIEW_FILTER_ACTION_NAME);
        if (memento != null) {
            annotationsViewFilterAction.init(memento);
        }
        manager.add(annotationsViewFilterAction);
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    @Override
    public void setFocus() {
        annotationTreeViewer.getControl().setFocus();
    }

    public void refreshLabels() {
        annotationTreeViewer.refresh();
    }

    public void refresh() {
        Display display = annotationTreeViewer.getControl().getDisplay();
        if (!display.isDisposed()) {
            display.asyncExec(new Runnable() {
                public void run() {
                    IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
                    IWorkbenchPage workbenchPage = workbenchWindow.getActivePage();
                    IEditorPart editorPart = workbenchPage.getActiveEditor();
                    try {
                        if (editorPart != null
                                && editorPart.getEditorInput() instanceof IFileEditorInput
                                && IDE.getEditorDescriptor(
                                        ((IFileEditorInput) editorPart.getEditorInput()).getFile()).getId()
                                        .equals(JavaUI.ID_CU_EDITOR)) {
                            ITextEditor txtEditor = (ITextEditor) workbenchPage.getActiveEditor();
                            IFileEditorInput fileEditorInput = (IFileEditorInput) txtEditor.getEditorInput();
                            ICompilationUnit compilationUnit = JavaCore.createCompilationUnitFrom(fileEditorInput.getFile());
                            if (compilationUnit != null) {
                                if (!compilationUnit.isConsistent()) {
                                    compilationUnit.makeConsistent(new NullProgressMonitor());
                                }
                                updateView(compilationUnit, (ITextSelection) txtEditor.getSelectionProvider()
                                        .getSelection());
                            }
                        }
                    } catch (JavaModelException jme) {
                        JAXWSUIPlugin.log(jme.getStatus());
                    } catch (PartInitException pie) {
                        JAXWSUIPlugin.log(pie.getStatus());
                    }
                }
            });
        }
    }
}