/*******************************************************************************
 * 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.IMethod;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
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.jst.ws.jaxws.core.utils.JDTUtils;
import org.eclipse.swt.SWT;
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() {
	}

    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(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
		Label label = new Label(notAvaiableComposite, SWT.NONE);
		label.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
		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<?>) {
                  return AnnotationsManager.getAnnotationDefinitionForClass(obj1).getAnnotationClassName().
                      compareTo(AnnotationsManager.getAnnotationDefinitionForClass(obj2).
                              getAnnotationClassName());
                }
                if (obj1 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 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();
        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 = JDTUtils.getCompilationUnitFromFile(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$
                    annotationTreeViewer.setInput((IPackageDeclaration) 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()) {
                    annotationTreeViewer.setInput(type);
                } else {
                    annotationTreeViewer.setInput(null);
                }
            }
    
            if (javaElement.getElementType() == IJavaElement.FIELD) {
                IField field = (IField)javaElement;
                if (!field.getDeclaringType().isMember()) {
                    annotationTreeViewer.setInput(field);
                } else {
                    annotationTreeViewer.setInput(null);
                }
            }

            if (javaElement.getElementType() == IJavaElement.METHOD) {
                IMethod method = (IMethod) javaElement;
                if (!method.getDeclaringType().isMember()) {
                    SingleVariableDeclaration parameter = AnnotationUtils
                            .getMethodParameter(null, method, offset);
                    if (parameter != null) {
                        annotationTreeViewer.setInput(parameter);
                    } else {
                        annotationTreeViewer.setInput(method);
                    }
                } else {
                    annotationTreeViewer.setInput(null);
                }
            }
            annotationTreeViewer.refresh();
        } catch (JavaModelException jme) {
            JAXWSUIPlugin.log(jme.getStatus());
        }
        
        annotationTreeViewer.setExpandedTreePaths(expandedTreePaths);
	}
    
    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.
	 */
	public void setFocus() {
		annotationTreeViewer.getControl().setFocus();
	}
	
    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 = JDTUtils
                                    .getCompilationUnitFromFile(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());
                    }
                }
            });
        }
    }
}