/*******************************************************************************
 * 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.INullSelectionListener;
import org.eclipse.ui.IPartListener2;
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 static final String VIEW_ID = "org.eclipse.jst.ws.jaxws.ui.views.AnnotationsView";

    private PageBook pageBook;
    private Tree annotationTree;

    private Composite notAvaiableComposite;
    private ClasspathComposite setupClasspathComposite;

    private TreeViewer annotationTreeViewer;

    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) {
        if (partRef.getId().equals(VIEW_ID)) {
            annotationsViewFilterAction.init();
        }
    }

    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());
                        }
                    }
                }
            }
        } else if (partRef.getId().equals(VIEW_ID)) {
            annotationsViewFilterAction.saveState();
        }
    }

    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);
    }

    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);
        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());
                    }
                }
            });
        }
    }
}