/*******************************************************************************
 * Copyright (c) 2008 IONA Technologies PLC
 * 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:
 * IONA Technologies PLC - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.internal.cxf.creation.ui.widgets;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
import org.eclipse.jdt.internal.ui.text.SimpleJavaSourceViewerConfiguration;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
import org.eclipse.jdt.ui.text.IColorManager;
import org.eclipse.jdt.ui.text.IJavaPartitions;
import org.eclipse.jdt.ui.text.JavaTextTools;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.FindReplaceDocumentAdapter;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jst.ws.internal.cxf.core.model.Java2WSDataModel;
import org.eclipse.jst.ws.internal.cxf.core.utils.AnnotationUtils;
import org.eclipse.jst.ws.internal.cxf.core.utils.JDTUtils;
import org.eclipse.jst.ws.internal.cxf.creation.ui.CXFCreationUIMessages;
import org.eclipse.jst.ws.internal.cxf.creation.ui.CXFCreationUIPlugin;
import org.eclipse.jst.ws.internal.cxf.creation.ui.viewers.AnnotationColumnLabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;

/**
 * @author sclarke
 */
@SuppressWarnings("restriction")
public class JAXWSAnnotateJavaWidget extends SimpleWidgetDataContributor {
    IStatus status = Status.OK_STATUS;

    private IType type;
    private Java2WSDataModel model;
    private TreeViewer javaTreeViewer;
    private SourceViewer annotationPreviewViewer;

    private TreeViewerColumn webMethodViewerColumn;
    private TreeViewerColumn webParamViewerColumn;
    private TreeViewerColumn requestWrapperViewerColumn;
    private TreeViewerColumn responceWrapperViewerColumn;
    
    public JAXWSAnnotateJavaWidget(Java2WSDataModel model) {
        this.model = model;
    }

    @Override
    public WidgetDataEvents addControls(Composite parent, Listener statusListener) {
        SashForm sashForm = new SashForm(parent, SWT.VERTICAL | SWT.SMOOTH);
        GridLayout gridLayout = new GridLayout(1, true);
        sashForm.setLayout(gridLayout);
        
        GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        sashForm.setLayoutData(gridData);
        
        Composite javaTreecomposite = new Composite(sashForm, SWT.NONE);
        gridLayout = new GridLayout(1, true);
        javaTreecomposite.setLayout(gridLayout);

        gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        javaTreecomposite.setLayoutData(gridData);

        Label outlineLabel = new Label(javaTreecomposite, SWT.NONE);
        outlineLabel.setText(CXFCreationUIMessages.JAXWS_ANNOTATE_JJAVA_WIDGET_SELECT_METHOD_TO_ANNOTATE);

        Tree javaTree = new Tree(javaTreecomposite, SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL
                | SWT.H_SCROLL);
        javaTreeViewer = new TreeViewer(javaTree);

        javaTree.setHeaderVisible(true);
        gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        gridData.heightHint = 10;
        gridData.widthHint = 200;
        javaTree.setLayoutData(gridData);

        TreeViewerColumn classViewerColumn = new TreeViewerColumn(javaTreeViewer, SWT.NONE);
        TreeColumn classColumn = classViewerColumn.getColumn();
        classColumn.setWidth(200);
        classColumn.setMoveable(false);

        final JavaElementLabelProvider javaElementLabelProvider = new JavaElementLabelProvider();
        classViewerColumn.setLabelProvider(new ColumnLabelProvider() {

            @Override
            public Image getImage(Object element) {
                return javaElementLabelProvider.getImage(element);
            }

            @Override
            public String getText(Object element) {
                return javaElementLabelProvider.getText(element);
            }
        });

        javaTreeViewer.setContentProvider(new StandardJavaElementContentProvider(true) {
            @Override
            public Object[] getChildren(Object element) {
                if (element instanceof ICompilationUnit) {
                    try {
                        ICompilationUnit compilationUnit = (ICompilationUnit) element;
                        IType[] types = compilationUnit.getTypes();
                        for (IType type : types) {
                            if (type instanceof SourceType) {
                                return new Object[] {type};
                            }
                        }
                    } catch (JavaModelException jme) {
                        CXFCreationUIPlugin.log(jme.getStatus());
                    }
                }

                if (element instanceof SourceType) {
                    try {
                        SourceType sourceType = (SourceType) element;
                        List<IMethod> publicMethods = new ArrayList<IMethod>();
                        IMethod[] methods = sourceType.getMethods();
                        for (IMethod method : methods) {
                            if (JDTUtils.isPublicMethod(method)) {
                                publicMethods.add(method);
                            }
                        }
                        return publicMethods.toArray(new Object[publicMethods.size()]);
                    } catch (JavaModelException jme) {
                        CXFCreationUIPlugin.log(jme.getStatus());
                    }
                }
                return NO_CHILDREN;
            }

            @Override
            public boolean hasChildren(Object element) {
                return getChildren(element).length > 0;
            }
        });

        javaTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged(SelectionChangedEvent event) {
                if (event.getSelection() instanceof TreeSelection) {
                    TreeSelection treeSelection = (TreeSelection) event.getSelection();
                    Object firstElement = treeSelection.getFirstElement();
                    
                    IDocument document = annotationPreviewViewer.getDocument();
                    FindReplaceDocumentAdapter findReplaceDocumentAdapter = new FindReplaceDocumentAdapter(document);
                    try {
                        if (firstElement instanceof SourceType) {
                            SourceType sourceType = (SourceType) firstElement;
                            String elementName = sourceType.getElementName();
                            
                            String regex = "\\bpublic\\W+(?:\\w+\\W+){1,3}?" + elementName + "\\b";
                            IRegion region = findReplaceDocumentAdapter.find(0, regex, true, true, false, true);

                            annotationPreviewViewer.setSelectedRange(region.getOffset(), region.getLength());
                            annotationPreviewViewer.revealRange(region.getOffset(), region.getLength());
                        } else if (firstElement instanceof SourceMethod) {
                            SourceMethod sourceMethod = (SourceMethod) firstElement;
                            String elementName = sourceMethod.getElementName();

                            String regex = "\\bpublic\\W+(?:\\w+\\W+){1,3}?" + elementName + "\\b";
                            IRegion region = findReplaceDocumentAdapter.find(0, regex, true, true, false, true);
                            annotationPreviewViewer.setSelectedRange(region.getOffset(), region.getLength());
                            annotationPreviewViewer.revealRange(region.getOffset(), region.getLength());
                        }
                    } catch (BadLocationException ble) {
                        CXFCreationUIPlugin.log(ble);
                    }
                }
            }
        });

        createWebMethodViewerColumn(javaTreeViewer);
        createWebParamViewerColumn(javaTreeViewer);
        createRequestWrapperViewerColumn(javaTreeViewer);
        createResponseWrapperViewerColumn(javaTreeViewer);

        javaTreeViewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
        javaTreeViewer.expandAll();

        Composite previewComposite = new Composite(sashForm, SWT.NONE);
        gridLayout = new GridLayout(1, true);
        previewComposite.setLayout(gridLayout);

        gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        javaTreecomposite.setLayoutData(gridData);

        Label previewLabel = new Label(previewComposite, SWT.NONE);
        previewLabel.setText(CXFCreationUIMessages.JAXWS_ANNOTATE_JJAVA_WIDGET_PREVIEW);

        annotationPreviewViewer = createAnnotationPreviewer(previewComposite, SWT.READ_ONLY | SWT.V_SCROLL
                | SWT.H_SCROLL | SWT.BORDER);
        gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        gridData.heightHint = 10;
        gridData.widthHint = 200;
        annotationPreviewViewer.getControl().setLayoutData(gridData);
        
        sashForm.setWeights(new int[]{50, 50});
        
        return this;
    }

    @Override
    public void internalize() {
        type = null;
        javaTreeViewer.setInput(getType().getTypeRoot());
        updateLabelProviders();
        javaTreeViewer.refresh();
        handleAnnotation(getType());
    }

    private IType getType() {
        if (type != null) {
            return type;
        }
        if (model.getFullyQualifiedJavaInterfaceName() != null) {
            type = JDTUtils.getType(JDTUtils.getJavaProject(model.getProjectName()), model
                    .getFullyQualifiedJavaInterfaceName());
        } else if (model.getFullyQualifiedJavaClassName() != null) {
            type =JDTUtils.getType(JDTUtils.getJavaProject(model.getProjectName()), model
                    .getFullyQualifiedJavaClassName());
        }
        
        if (type == null) {
            type = JDTUtils.getType(JDTUtils.getJavaProject(model.getProjectName()), model
                    .getJavaStartingPoint());
        }

        return type;
    }
    
    private TreeViewerColumn createWebMethodViewerColumn(TreeViewer treeViewer) {
        webMethodViewerColumn = new TreeViewerColumn(treeViewer, SWT.CENTER);
        TreeColumn webMethodColumn = webMethodViewerColumn.getColumn();
        webMethodColumn.setText("@" + AnnotationUtils.WEB_METHOD); //$NON-NLS-1$
        webMethodColumn.setWidth(100);
        webMethodColumn.setAlignment(SWT.CENTER);
        webMethodColumn.setMoveable(false);
        webMethodViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
                AnnotationUtils.WEB_METHOD, getType()));
        webMethodViewerColumn.setEditingSupport(new AnnotationEditingSupport(treeViewer,
                AnnotationUtils.WEB_METHOD));
        return webMethodViewerColumn;
    }

    private TreeViewerColumn createWebParamViewerColumn(TreeViewer treeViewer) {
        webParamViewerColumn = new TreeViewerColumn(treeViewer, SWT.CENTER);
        TreeColumn webParamColumn = webParamViewerColumn.getColumn();
        webParamColumn.setText("@" + AnnotationUtils.WEB_PARAM); //$NON-NLS-1$
        webParamColumn.setWidth(100);
        webParamColumn.setAlignment(SWT.CENTER);
        webParamColumn.setMoveable(false);
        webParamViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
                AnnotationUtils.WEB_PARAM, getType()));
        webParamViewerColumn.setEditingSupport(new AnnotationEditingSupport(treeViewer,
                AnnotationUtils.WEB_PARAM));
        return webParamViewerColumn;
    }

    private TreeViewerColumn createRequestWrapperViewerColumn(TreeViewer treeViewer) {
        requestWrapperViewerColumn = new TreeViewerColumn(treeViewer, SWT.CENTER);
        TreeColumn createRequestWrapperColumn = requestWrapperViewerColumn.getColumn();
        createRequestWrapperColumn.setText("@" + AnnotationUtils.REQUEST_WRAPPER); //$NON-NLS-1$
        createRequestWrapperColumn.setWidth(100);
        createRequestWrapperColumn.setMoveable(false);
        requestWrapperViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
                AnnotationUtils.REQUEST_WRAPPER, getType()));
        requestWrapperViewerColumn.setEditingSupport(new AnnotationEditingSupport(treeViewer, 
                AnnotationUtils.REQUEST_WRAPPER));
        return requestWrapperViewerColumn;
    }

    private TreeViewerColumn createResponseWrapperViewerColumn(TreeViewer treeViewer) {
        responceWrapperViewerColumn = new TreeViewerColumn(treeViewer, SWT.CENTER);
        TreeColumn responceWrapperColumn = responceWrapperViewerColumn.getColumn();
        responceWrapperColumn.setText("@" + AnnotationUtils.RESPONSE_WRAPPER); //$NON-NLS-1$
        responceWrapperColumn.setWidth(100);
        responceWrapperColumn.setMoveable(false);
        responceWrapperViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
                AnnotationUtils.RESPONSE_WRAPPER, getType()));
        responceWrapperViewerColumn.setEditingSupport(new AnnotationEditingSupport(treeViewer,
                AnnotationUtils.RESPONSE_WRAPPER));
        return responceWrapperViewerColumn;
    }
    
    private void updateLabelProviders() {
        webMethodViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
                AnnotationUtils.WEB_METHOD, getType()));
        webParamViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
                AnnotationUtils.WEB_PARAM, getType()));
        requestWrapperViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
                AnnotationUtils.REQUEST_WRAPPER, getType()));
        responceWrapperViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
                AnnotationUtils.RESPONSE_WRAPPER, getType()));
    }
    
    private void handleAnnotation(IType type) {
        try {
            annotationPreviewViewer.setRedraw(false);

            ICompilationUnit compilationUnit = type.getCompilationUnit();
            IProgressMonitor monitor =  new NullProgressMonitor();
            
            TextFileChange textFileChange = new TextFileChange("Annotation Changes", 
                    (IFile)compilationUnit.getResource());
            MultiTextEdit multiTextEdit = new MultiTextEdit();
            textFileChange.setEdit(multiTextEdit);
            textFileChange.setKeepPreviewEdits(true);
//            compositeChange.setSaveMode(TextFileChange.FORCE_SAVE);

            AnnotationUtils.getWebServiceAnnotationChange(type, model, textFileChange);

            IMethod[] typeMethods = JDTUtils.getPublicMethods(type);
            for (int i = 0; i < typeMethods.length; i++) {
                IMethod method = typeMethods[i];
                Map<String, Boolean> methodAnnotationMap = model.getMethodMap().get(method);
                if (methodAnnotationMap.get(AnnotationUtils.WEB_METHOD)) {
                    AnnotationUtils.getWebMethodAnnotationChange(type, method, textFileChange);
                }
                if (methodAnnotationMap.get(AnnotationUtils.REQUEST_WRAPPER)) {
                    AnnotationUtils.getRequestWrapperAnnotationChange(type, method, textFileChange);
                }
                if (methodAnnotationMap.get(AnnotationUtils.RESPONSE_WRAPPER)) {
                    AnnotationUtils.getResponseWrapperAnnotationChange(type, method, textFileChange);
                }
                if (methodAnnotationMap.get(AnnotationUtils.WEB_PARAM)) {
                    List<SingleVariableDeclaration> parameters = AnnotationUtils.getMethodParameters(
                            type, method);
                    for (SingleVariableDeclaration parameter : parameters) {
                        AnnotationUtils.getWebParamAnnotationChange(type, method, parameter, textFileChange);
                    }
                } 
            }
            
            AnnotationUtils.getImportsChange(compilationUnit, model, textFileChange, false);
            annotationPreviewViewer.getDocument().set(textFileChange.getPreviewContent(monitor));

            annotationPreviewViewer.setRedraw(true);

        } catch (CoreException ce) {
            CXFCreationUIPlugin.log(ce.getStatus());
        } catch (MalformedTreeException mte) {
            CXFCreationUIPlugin.log(mte);
        } 
    }

    private SourceViewer createAnnotationPreviewer(Composite parent, int styles) {
        JavaPlugin javaPlugin = JavaPlugin.getDefault();
        IPreferenceStore store = javaPlugin.getCombinedPreferenceStore();
        JavaTextTools javaTextTools = javaPlugin.getJavaTextTools();
        annotationPreviewViewer = new JavaSourceViewer(parent, null, null, true, styles, store);
        IColorManager colorManager = javaTextTools.getColorManager();
        SimpleJavaSourceViewerConfiguration configuration = new SimpleJavaSourceViewerConfiguration(
                colorManager, store, null, IJavaPartitions.JAVA_PARTITIONING, true);

        annotationPreviewViewer.configure(configuration);

        Font font = JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT);
        annotationPreviewViewer.getTextWidget().setFont(font);
        annotationPreviewViewer.setEditable(false);

        String source = JDTUtils.getSourceFromType(getType());
        IDocument document = new Document(source);

        JavaPlugin.getDefault().getJavaTextTools().setupJavaDocumentPartitioner(document,
                IJavaPartitions.JAVA_PARTITIONING);
        annotationPreviewViewer.setDocument(document);

        return annotationPreviewViewer;
    }

    @Override
    public IStatus getStatus() {
        return status;
    }

    private class AnnotationEditingSupport extends EditingSupport {
        private CheckboxCellEditor checkboxCellEditor;

        private String annotationKey;
        
        public AnnotationEditingSupport(TreeViewer viewer, String annotationKey) {
            super(viewer);
            this.annotationKey = annotationKey;
            checkboxCellEditor = new CheckboxCellEditor(viewer.getTree());
        }

        @Override
        protected boolean canEdit(Object element) {
            return !AnnotationUtils.isAnnotationPresent(type.findMethods((IMethod) element)[0], 
                    annotationKey);
        }

        @Override
        protected CellEditor getCellEditor(Object element) {
            return checkboxCellEditor;
        }

        @Override
        protected Object getValue(Object element) {
            Boolean annotate = model.getMethodMap().get(element).get(annotationKey);
            return annotate;
        }

        @Override
        protected void setValue(Object element, Object value) {
            if (element instanceof SourceMethod) {
                SourceMethod method = (SourceMethod) element;
                Boolean annotate = (Boolean) value;
                Map<String, Boolean> annotationMap = model.getMethodMap().get(element);
                annotationMap.put(annotationKey, annotate);
                handleAnnotation(method.getDeclaringType());
                getViewer().refresh(true);
            }
        }
    }
}
