/*******************************************************************************
 * 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.ui.widgets;

import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jst.ws.internal.cxf.core.model.DataBinding;
import org.eclipse.jst.ws.internal.cxf.core.model.Frontend;
import org.eclipse.jst.ws.internal.cxf.core.model.Java2WSContext;
import org.eclipse.jst.ws.internal.cxf.core.model.Java2WSDataModel;
import org.eclipse.jst.ws.internal.cxf.ui.CXFUIMessages;
import org.eclipse.jst.ws.internal.cxf.ui.CXFUIPlugin;
import org.eclipse.jst.ws.internal.cxf.ui.viewers.JavaViewerFilter;
import org.eclipse.jst.ws.jaxws.core.utils.JDTUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;

/**
 * Provides widgets for Java2WS preferences, wizards, dialogs. Enables the reuse
 * of widgets in multiple locations. Widgets have there labeling and tooltips
 * set here and where possible listeners are set which update instances of
 * <code>Java2WSContext</code> and <code>Java2WSDataModel</code>.
 * 
 */
public final class Java2WSWidgetFactory {

    private Java2WSWidgetFactory() {
    }

    public static Label createSOAPBindingLabel(Composite parent) {
        Label defaultSoapBinding = new Label(parent, SWT.NONE);
        defaultSoapBinding.setText(CXFUIMessages.JAVA2WS_DEFAULT_SOAPBINDING_LABEL);
        return defaultSoapBinding;
    }

    public static Combo createSOAPBingCombo(Composite parent, final Java2WSContext context) {
        Combo soapBindingCombo = new Combo(parent, SWT.READ_ONLY);
        soapBindingCombo.setToolTipText(CXFUIMessages.JAVA2WS_SOAP12_BINDING_TOOLTIP);
        soapBindingCombo.add("SOAP 1.1"); //$NON-NLS-1$
        soapBindingCombo.add("SOAP 1.2"); //$NON-NLS-1$
        soapBindingCombo.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                String soapBinding = ((Combo) e.widget).getText();
                if (soapBinding.equals("SOAP 1.2")) { //$NON-NLS-1$
                    context.setSoap12Binding(true);
                } else {
                    context.setSoap12Binding(false);
                }
            }
        });
        if (context.isSoap12Binding()) {
            soapBindingCombo.setText("SOAP 1.2"); //$NON-NLS-1$
        } else {
            soapBindingCombo.setText("SOAP 1.1"); //$NON-NLS-1$
        }

        return soapBindingCombo;
    }

    public static Button createXSDImportsButton(Composite parent, final Java2WSContext context) {
        Button createXSDImports = new Button(parent, SWT.CHECK);
        createXSDImports.setText(CXFUIMessages.JAVA2WS_GEN_XSD_IMPORTS);
        createXSDImports.setToolTipText(CXFUIMessages.JAVA2WS_CREATE_XSD_IMPORTS_TOOLTIP);
        createXSDImports.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                context.setGenerateXSDImports(((Button) e.widget).getSelection());
            }
        });
        createXSDImports.setSelection(context.isGenerateXSDImports());
        return createXSDImports;
    }

    public static Label createFrontendLabel(Composite parent) {
        Label frontendLabel = new Label(parent, SWT.NONE);
        frontendLabel.setText(CXFUIMessages.CXF_DEFAULT_FRONTEND_LABEL);
        return frontendLabel;
    }

    public static Combo createFrontendCombo(Composite parent, final Java2WSContext context) {
        final Combo frontendCombo = new Combo(parent, SWT.READ_ONLY);
        frontendCombo.setToolTipText(CXFUIMessages.JAVA2WS_FRONTEND_TOOLTIP);
        frontendCombo.add(Frontend.JAXWS.getLiteral());
        frontendCombo.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                String frontend = frontendCombo.getText();
                context.setFrontend(Frontend.get(frontend));
                if (frontend.equals(Frontend.JAXWS.getLiteral())) {
                    context.setDatabinding(DataBinding.get(DataBinding.JAXB.getLiteral()));
                }
//                if (frontend.equals("simple")) {
//                    context.setDatabinding("aegis");
//                }
            }
        });
        frontendCombo.setText(context.getFrontend().getLiteral());

        return frontendCombo;
    }

    public static Label createDatabindingLabel(Composite parent) {
        Label databindingLabel = new Label(parent, SWT.NONE);
        databindingLabel.setText(CXFUIMessages.CXF_DEFAULT_DATABINDING_LABEL);
        return databindingLabel;
    }

    public static Combo createDatabindingCombo(Composite parent, final Java2WSContext context) {
        final Combo databindingCombo = new Combo(parent, SWT.READ_ONLY);
        databindingCombo.setToolTipText(CXFUIMessages.JAVA2WS_DATABINDING_TOOLTIP);
        databindingCombo.add(DataBinding.JAXB.getLiteral());
        databindingCombo.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                context.setDatabinding(DataBinding.get(databindingCombo.getText()));
            }
        });
        databindingCombo.setText(context.getDatabinding().getLiteral());
        return databindingCombo;
    }

    public static Button createGenerateClientButton(Composite parent, final Java2WSContext context) {
        final Button genClientButton = new Button(parent, SWT.CHECK);
        genClientButton.setText(CXFUIMessages.JAVA2WS_GEN_CLIENT_LABEL);
        genClientButton.setToolTipText(CXFUIMessages.JAVA2WS_GENERATE_CLIENT_TOOLTIP);
        genClientButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                context.setGenerateClient(genClientButton.getSelection());
            }
        });
        genClientButton.setSelection(context.isGenerateClient());
        return genClientButton;
    }

    public static Button createGenerateServerButton(Composite parent, final Java2WSContext context) {
        final Button genServerButton = new Button(parent, SWT.CHECK);
        genServerButton.setText(CXFUIMessages.JAVA2WS_GEN_SERVER_LABEL);
        genServerButton.setToolTipText(CXFUIMessages.JAVA2WS_GENERATE_SERVER_TOOLTIP);
        genServerButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                context.setGenerateServer(genServerButton.getSelection());
            }
        });
        genServerButton.setSelection(context.isGenerateServer());
        return genServerButton;
    }

    public static Button createGenerateWrapperFaultBeanButton(Composite parent, final Java2WSContext context) {
        final Button genWrapperFaultButton = new Button(parent, SWT.CHECK);
        genWrapperFaultButton.setText(CXFUIMessages.JAVA2WS_GEN_WRAPPER_FAULT_LABEL);
        genWrapperFaultButton.setToolTipText(CXFUIMessages.JAVA2WS_GENERATE_WRAPPERBEAN_TOOLTIP);
        genWrapperFaultButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                context.setGenerateWrapperFaultBeans(genWrapperFaultButton.getSelection());
            }
        });
        genWrapperFaultButton.setSelection(context.isGenerateWrapperFaultBeans());
        return genWrapperFaultButton;
    }

    public static Button createGenerateWSDLButton(Composite parent, final Java2WSContext context) {
        final Button genWSDLButton = new Button(parent, SWT.CHECK);
        genWSDLButton.setText(CXFUIMessages.JAVA2WS_GEN_WSDL_LABEL);
        genWSDLButton.setToolTipText(CXFUIMessages.JAVA2WS_GENERATE_WSDL_TOOLTIP);
        genWSDLButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                context.setGenerateWSDL(genWSDLButton.getSelection());
            }
        });
        genWSDLButton.setSelection(context.isGenerateWSDL());
        return genWSDLButton;
    }

    public static Label createWSDLFileNameLabel(Composite parent) {
        Label wsdlFileNameLabel = new Label(parent, SWT.NONE);
        wsdlFileNameLabel.setText(CXFUIMessages.JAVA2WS_WSDL_FILE_NAME);
        return wsdlFileNameLabel;

    }

    public static Text createWSDLFileNameText(Composite parent, final Java2WSDataModel model) {
        final Text wsdlFileText = new Text(parent, SWT.BORDER);
        wsdlFileText.setToolTipText(CXFUIMessages.JAVA2WS_OUTPUT_FILE_TOOLTIP);
        wsdlFileText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                model.setWsdlFileName(wsdlFileText.getText());
            }
        });
        wsdlFileText.setText(model.getWsdlFileName());
        return wsdlFileText;
    }

    public static Button createUseSEIButton(Composite parent) {
        Button useSEIButton = new Button(parent, SWT.CHECK);
        useSEIButton.setText(CXFUIMessages.JAVA2WS_USE_SEI_BUTTON);
        return useSEIButton;
    }

    public static Label createInformationLabel(Composite parent, IType startingPointType) {
        Label infoLabel = new Label(parent, SWT.WRAP);
        infoLabel.setText(CXFUIMessages.bind(CXFUIMessages.JAVA2WS_USE_SEI_INFO_LABEL, startingPointType
                .getElementName()));
        return infoLabel;
    }

    public static Label createPaddingLabel(Composite parent) {
        return new Label(parent, SWT.NONE);
    }

    public static Button createSelectSEIButton(Composite parent) {
        Button selectSEIButton = new Button(parent, SWT.RADIO);
        selectSEIButton.setText(CXFUIMessages.JAVA2WS_SELECT_SEI_LABEL);
        return selectSEIButton;
    }

    public static Label createSelectSEILabel(Composite parent) {
        Label selectSEILabel = new Label(parent, SWT.NONE);
        selectSEILabel.setText(CXFUIMessages.JAVA2WS_SELECT_SEI_LABEL);
        return selectSEILabel;
    }

    public static Combo createSelectSEICombo(Composite parent, final Java2WSDataModel model,
            IType javaStartingPointType) {
        final Combo seiCombo = new Combo(parent, SWT.BORDER);
        seiCombo.setToolTipText(CXFUIMessages.JAVA2WS_SELECT_SEI_TOOLTIP);

        IJavaProject javaProject = JDTUtils.getJavaProject(model.getProjectName());
        try {
            ITypeHierarchy typeHierarchy = javaStartingPointType.newTypeHierarchy(javaProject, null);
            IType[] allInterfaces = typeHierarchy.getAllInterfaces();
            for (int i = 0; i < allInterfaces.length; i++) {
                IType itype = allInterfaces[i];
                if (!itype.isBinary() && itype.getResource().getProject().equals(javaProject.getProject())) {
                    seiCombo.add(itype.getFullyQualifiedName());
                }
            }
        } catch (JavaModelException jme) {
            CXFUIPlugin.log(jme.getStatus());
        }

        seiCombo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent event) {
                String seiInterfaceName = seiCombo.getText();
                model.setFullyQualifiedJavaInterfaceName(seiInterfaceName);
            }
        });

        seiCombo.deselectAll();
        return seiCombo;
    }

    public static Button createBrowseButton(Composite parent) {
        Button browseButton = new Button(parent, SWT.PUSH);
        browseButton.setText(CXFUIMessages.JAVA2WS_BROWSE_LABEL);
        return browseButton;
    }

    public static Button createExtractSEIButton(Composite parent) {
        Button extractSEIButton = new Button(parent, SWT.RADIO);
        extractSEIButton.setText(CXFUIMessages.JAVA2WS_EXTRACT_SEI_LABEL);
        return extractSEIButton;
    }

    public static Label createExtractSEILabel(Composite parent) {
        Label extractSEILabel = new Label(parent, SWT.NONE);
        extractSEILabel.setText(CXFUIMessages.JAVA2WS_EXTRACT_SEI_LABEL);
        return extractSEILabel;
    }

    public static Text createSEIInterfaceNameText(Composite parent) {
        Text seiInterfaceNameText = new Text(parent, SWT.BORDER);
        seiInterfaceNameText.setToolTipText(CXFUIMessages.JAVA2WS_EXTRACT_SEI_TOOLTIP);
        return seiInterfaceNameText;
    }

    public static Label createMemebersToExtractLabel(Composite parent) {
        Label seiMembersToExtractLabel = new Label(parent, SWT.NONE);
        seiMembersToExtractLabel.setText(CXFUIMessages.JAVA2WS_EXTRACT_MEMBERS_LABEL);
        return seiMembersToExtractLabel;
    }

    public static CheckboxTableViewer createSEIMembersToExtractTableViewer(Composite parent) {
        CheckboxTableViewer seiMembersToExtractTableViewer = CheckboxTableViewer.newCheckList(parent,
                SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
        seiMembersToExtractTableViewer.setLabelProvider(new JavaElementLabelProvider());
        seiMembersToExtractTableViewer.setContentProvider(new ArrayContentProvider());
        return seiMembersToExtractTableViewer;
    }

    public static Button createSelectAllButton(Composite parent) {
        Button selectAllButton = new Button(parent, SWT.PUSH);
        selectAllButton.setText(CXFUIMessages.JAVA2WS_SELECT_ALL_BUTTON);
        return selectAllButton;
    }

    public static Button createDeselectAllButton(Composite parent) {
        Button deselectAllButton = new Button(parent, SWT.PUSH);
        deselectAllButton.setText(CXFUIMessages.JAVA2WS_DESELECT_ALL_BUTTON);
        return deselectAllButton;
    }
    
    public static Label createSelectImplementationLabel(Composite parent) {
        Label selectImplementationLabel = new Label(parent, SWT.NONE);
        selectImplementationLabel.setText(CXFUIMessages.JAVA2WS_SELECT_IMPLEMENTATION);
        return selectImplementationLabel;
    }
    
    public static Combo createSelectImplementationCombo(Composite parent, 
            final Java2WSDataModel model, IType javaStartingPointType) {
        final Combo selectImplementationCombo = new Combo(parent, SWT.BORDER);
        selectImplementationCombo.setToolTipText(CXFUIMessages.JAVA2WS_SELECT_IMPLEMENTATION_TOOLTIP);

        IJavaProject javaProject = JDTUtils.getJavaProject(model.getProjectName());
        try {
            ITypeHierarchy typeHierarchy = javaStartingPointType.newTypeHierarchy(javaProject, null);
            IType[] allImplementations = typeHierarchy.getAllSubtypes(javaStartingPointType);
            for (int i = 0; i < allImplementations.length; i++) {
                IType itype = allImplementations[i];
                if (!itype.isBinary() && itype.getResource().getProject().equals(javaProject.getProject())) {
                    String packageName = itype.getPackageFragment().getElementName();
                    if (packageName.trim().length() > 0) {
                        packageName += "."; //$NON-NLS-1$
                    }
                    String qualifiedName = packageName + itype.getPrimaryElement().getElementName();
                    selectImplementationCombo.add(qualifiedName);
                }
            }
        } catch (JavaModelException jme) {
            CXFUIPlugin.log(jme.getStatus());
        }

        selectImplementationCombo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent event) {
                String implementationName = selectImplementationCombo.getText();
                model.setFullyQualifiedJavaClassName(implementationName);
            }
        });

        selectImplementationCombo.deselectAll();
        return selectImplementationCombo;
    }
    
    /**
     * Creates am <code>ElementTreeSelectionDialog</code> that displays all the classes or all the interfaces
     * within a <code>IJavaProject</code> allowing one class or interface to be selected.
     * 
     * @param parent the parent shell
     * @param title the dialog title
     * @param message the dialog message
     * @param javaProject the java project that is filtered
     * @param elementKinds a flag defining nature of searched elements; the only valid values are: 
     *  <code>IJavaSearchConstants.CLASS</code>
     *  <code>IJavaSearchConstants.INTERFACE</code>
     *  <code>IJavaSearchConstants.CLASS_AND_INTERFACE</code>
     *  
     * @return the element tree selection dialog
     */
    public static ElementTreeSelectionDialog createElementTreeSelectionDialog(Shell parent, String title, 
            String message, IJavaProject javaProject, int elementKinds) {
        ElementTreeSelectionDialog selectionDialog = new ElementTreeSelectionDialog(parent,
                new JavaElementLabelProvider(), new StandardJavaElementContentProvider());
        selectionDialog.setTitle(title);
        selectionDialog.setMessage(message);
        selectionDialog.setAllowMultiple(false);
        selectionDialog.setInput(JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()));

        selectionDialog.addFilter(new JavaViewerFilter(javaProject, elementKinds));

        selectionDialog.setValidator(new ISelectionStatusValidator() {

            public IStatus validate(Object[] selection) {
              if (selection.length == 1) {
                    if (selection[0] instanceof ICompilationUnit) {
                        return new Status(IStatus.OK, CXFUIPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
                    }
                }
                return new Status(IStatus.ERROR, CXFUIPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
            }            
        });

        return selectionDialog;

    }
 
}
