/******************************************************************************
 * Copyright (c) 2005, 2006 IBM Corporation and others.
 * 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:
 *    IBM Corporation - initial API and implementation 
 ****************************************************************************/
package org.eclipse.gmf.runtime.common.ui.services.elementselection;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gmf.runtime.common.core.util.StringStatics;
import org.eclipse.gmf.runtime.common.ui.services.internal.l10n.CommonUIServicesMessages;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
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.Table;
import org.eclipse.swt.widgets.Text;

/**
 * The element selection composite. The composite functional similar to the JDT
 * select type dialog. There is a filter field and a table containing a list of
 * elements to select from.
 * <p>
 * The element selection composite requires an IElementSelectionInput as input
 * for the element selection service.
 * <p>
 * Subclasses must override the {@link #isValidSelection}and
 * {@link #handleSelection(boolean)} to provide custom validation.
 * 
 * @author Anthony Hunter
 */
public abstract class ElementSelectionComposite
    implements IElementSelectionListener {

    /**
     * The title to display at the top of the element selection composite.
     */
    private final String title;

    /**
     * The elements that have been selected by the user.
     */
    private final List selectedElements = new ArrayList();

    /**
     * Text control to display the filter text.
     */
    private Text filterText = null;

    /**
     * The table viewer to display list of matching objects.
     */
    private TableViewer tableViewer = null;

    /**
     * The progress bar when searching for matching objects.
     */
    private ProgressMonitorPart progressBar;

    /**
     * The input for the element selection service.
     */
    private AbstractElementSelectionInput input;

    /**
     * The job running the element selection service.
     */
    private ElementSelectionServiceJob job;

    /**
     * The element selection service to use to search for elements.
     */
    private final ElementSelectionService elementSelectionService;

    /**
     * Control character for the filter.
     * <p>
     * When the user enters the first character into the filterText, element
     * selection service is called. When the user enters the second character
     * after the first, we can use the existing results returned by the service.
     * If the user enters text such that the first character has been changed,
     * we need to query the service again.
     * <p>
     * For example, if the user enters "a" then "ab", we can use the existing
     * results from "a". If the user enters "a" then "b", then we must query a
     * second time.
     * <p>
     * We also must remember if the service has already been called. If the user
     * enters "a" and then "b", we must cancel "a" and wait before calling the
     * service for "b".
     */
    private char firstCharacter = Character.MIN_VALUE;

    private String lastSearchedFor = StringStatics.BLANK;

    private int lastScopeSearchedFor = 0;

    /**
     * matching objects from the element selection service.
     */
    private List matchingObjects = new ArrayList();

    /**
     * Pattern for the input filter.
     */
    private Pattern pattern;

    /**
     * Constructs a new instance that will create the new composite. I will use
     * the default {@linkplain ElementSelectionService#getInstance() selection service}
     * to process the <tt>input</tt>.
     * 
     * @param title
     *            the dialog title
     * @param input
     *            the element selection input.
     */
    public ElementSelectionComposite(String title,
            AbstractElementSelectionInput input) {
        this(title, input, ElementSelectionService.getInstance());
    }

    /**
     * Constructs a new instance that will create the new composite.
     * 
     * @param title the dialog title
     * @param input the element selection input
     * @param elementSelectionService the selection service to use to process the
     *     <tt>input</tt>
     */
    public ElementSelectionComposite(String title,
            AbstractElementSelectionInput input,
            ElementSelectionService elementSelectionService) {
        super();
        this.title = title;
        this.input = input;
        this.elementSelectionService = elementSelectionService;
        this.lastScopeSearchedFor = input.getScope().intValue();
    }

    /**
     * Determines if the selected elements are a valid selection.
     * 
     * @param currentSelectedElements
     *            the selected list of Elements
     * @return <code>true</code> if the selected elements are a valid
     *         selection
     */
    abstract protected boolean isValidSelection(List currentSelectedElements);

    /**
     * Handle a selection change, where the validity of the new selection is
     * encoded in <code>isValid</code>.
     * 
     * @param isValid
     *            <code>true</code> if the new selection is valid,
     *            <code>false</code> otherwise.
     */
    protected abstract void handleSelection(boolean isValid);

    /**
     * Creates the composite.
     * 
     * @param parent
     *            the parent composite
     * @return the new composite
     */
    public Composite createComposite(Composite parent) {

        Composite result = new Composite(parent, SWT.NONE);
        result.setLayout(new GridLayout());
        result.setLayoutData(new GridData(GridData.FILL_BOTH));

        // Add the selection title label
        Label label = new Label(result, SWT.NONE);
        label.setText(title);

        // Add the element selection text widget
        filterText = new Text(result, SWT.SINGLE | SWT.BORDER);
        filterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        filterText.addModifyListener(new ModifyListener() {

            public void modifyText(ModifyEvent e) {
                handleFilterChange();
            }

        });

        // Add the table viewer
        int selectStyle = SWT.SINGLE;
        tableViewer = new TableViewer(result, selectStyle | SWT.H_SCROLL
            | SWT.V_SCROLL | SWT.BORDER);
        tableViewer.setUseHashlookup(true);

        Table table = tableViewer.getTable();
        GridData gridData = new GridData(GridData.FILL_BOTH);
        GC gc = new GC(result);
        gc.setFont(JFaceResources.getDefaultFont());
        FontMetrics fontMetrics = gc.getFontMetrics();
        gc.dispose();
        gridData.widthHint = Dialog
            .convertWidthInCharsToPixels(fontMetrics, 80);
        gridData.heightHint = table.getItemHeight() * 15;
        table.setLayoutData(gridData);

        table.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                handleSelectionChange();
            }

            public void widgetDefaultSelected(SelectionEvent e) {
                handleWidgetDefaultSelected();
            }
        });

        progressBar = new ProgressMonitorPart(result, new GridLayout());
        progressBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        progressBar.setVisible(false);

        tableViewer.setLabelProvider(new LabelProvider() {

            public Image getImage(Object element) {
                assert element instanceof AbstractMatchingObject;
                return ((AbstractMatchingObject) element).getImage();
            }

            public String getText(Object element) {
                assert element instanceof AbstractMatchingObject;
                return ((AbstractMatchingObject) element).getDisplayName();
            }
        });
        tableViewer.setSorter(new ViewerSorter() {

            public int compare(Viewer viewer, Object e1, Object e2) {
                if (e1 instanceof IMatchingObject && e2 instanceof IMatchingObject)
                    return ((IMatchingObject)e1).getName().toLowerCase().compareTo(
                            ((IMatchingObject) e2).getName().toLowerCase());

                return super.compare(viewer, e1, e2);
            }
        });

        createCompositeAdditions(result);

        return result;
    }

    /**
     * The method is provided so that clients can add additional fields to the
     * bottom of the selection composite. For example, clients may want to a
     * checkbox button to the bottom of the composite.
     * 
     * @param parent
     *            the parent composite
     */
    protected void createCompositeAdditions(Composite parent) {
        /* clients are expected to override this method */
    }

    /**
     * Handles a filter change.
     */
    public void handleFilterChange() {
        if (filterText.getText().equals(StringStatics.BLANK)) {
            /* no filter, no results */
            cancel();
            matchingObjects.clear();
            tableViewer.getTable().removeAll();
            firstCharacter = Character.MIN_VALUE;
            return;
        }

        String filter = validatePattern(filterText.getText());
        pattern = Pattern.compile(filter);
        if (firstCharacter != filterText.getText().charAt(0) ||
                this.input.getScope().intValue() != this.lastScopeSearchedFor ||
                !filterText.getText().startsWith(lastSearchedFor)) {
            // scope changes, start from scratch...
            cancel();
            matchingObjects.clear();
            tableViewer.getTable().removeAll();

            firstCharacter = filterText.getText().charAt(0);
            this.lastScopeSearchedFor = this.input.getScope().intValue();

            startElementSelectionService();
        } else {
            /*
             * clear the existing matches in the table and refilter results we have
             * received
             */
            tableViewer.getTable().removeAll();
            for (Iterator i = matchingObjects.iterator(); i.hasNext();) {
                IMatchingObject matchingObject = (IMatchingObject) i.next();
                Matcher matcher = pattern.matcher(matchingObject.getName()
                    .toLowerCase());
                if (matcher.matches()) {
                    tableViewer.add(matchingObject);
                    setSelection();
                }
            }
        }
    }

    /**
     * Fill the table viewer with results from the element selection service.
     */
    private void startElementSelectionService() {
        /*
         * Initialize all possible matching objects from the select element
         * service.
         */
        input.setInput(filterText.getText());
        lastSearchedFor = filterText.getText();

        progressBar.setVisible(true);
        progressBar.beginTask(
            CommonUIServicesMessages.ElementSelectionService_ProgressName,
            IProgressMonitor.UNKNOWN);

        job = elementSelectionService.getMatchingObjects(input, this);
    }

    /**
     * Handles a selection change and validates the new selection.
     */
    private void handleSelectionChange() {
        StructuredSelection selection = (StructuredSelection) tableViewer
            .getSelection();
        if (selection.size() == 0) {
            // nothing selected
            selectedElements.clear();
            handleSelection(false);
            return;
        }

        List selectionList = selection.toList();

        // get the current selected elements
        List currentSelectedElements = new ArrayList();
        for (Iterator iter = selectionList.iterator(); iter.hasNext();) {
            AbstractMatchingObject matchingObject = (AbstractMatchingObject) iter
                .next();
            currentSelectedElements.add(matchingObject);
        }

        // validate selection
        boolean isValidSelection = isValidSelection(currentSelectedElements);

        // store the selection
        selectedElements.clear();
        if (isValidSelection) {
            selectedElements.addAll(currentSelectedElements);
        }

        // update UI based on selection
        handleSelection(isValidSelection);

    }

    /**
     * Gets the user selected elements.
     * 
     * @return the user selected elements
     */
    public List getSelectedElements() {
        List result = new ArrayList();
        for (Iterator iter = selectedElements.iterator(); iter.hasNext();) {
            IMatchingObject matchingObject = (IMatchingObject) iter.next();
            IElementSelectionProvider provider = matchingObject.getProvider();
            Object object = provider.resolve(matchingObject);
            result.add(object);
        }
        return result;
    }

    public void matchingObjectEvent(IMatchingObjectEvent matchingObjectEvent) {
        if (!progressBar.isDisposed()) {
            if (matchingObjectEvent.getEventType() == MatchingObjectEventType.END_OF_MATCHES) {
                progressBar.done();
                progressBar.setVisible(false);
                job = null;
            } else {
                IMatchingObject matchingObject = matchingObjectEvent
                    .getMatchingObject();
                progressBar.worked(1);
                progressBar.subTask(matchingObject.getName());
                matchingObjects.add(matchingObject);
                Matcher matcher = pattern.matcher(matchingObject.getName()
                    .toLowerCase());
                if (matcher.matches()) {
                    tableViewer.add(matchingObject);
                    setSelection();
                }
            }
        }
    }

    /**
     * Cancel the job running the element selection service.
     */
    public void cancel() {
        if (job != null) {
            elementSelectionService.cancelJob(job);
            job = null;
            progressBar.done();
            progressBar.setVisible(false);
        }
    }

    /**
     * Convert the UNIX style pattern entered by the user to a Java regex
     * pattern (? = any character, * = any string).
     * 
     * @param string
     *            the UNIX style pattern.
     * @return a Java regex pattern.
     */
    private String validatePattern(String string) {
        if (string.equals(StringStatics.BLANK)) {
            return string;
        }
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < string.length(); i++) {
            char c = Character.toLowerCase(string.charAt(i));
            if (c == '?') {
                result.append('.');
            } else if (c == '*') {
                result.append(".*"); //$NON-NLS-1$
            } else {
                result.append(c);
            }
        }
        result.append(".*"); //$NON-NLS-1$
        return result.toString();
    }

    /**
     * If there is no selection in the composite, set the selection to the
     * provided MatchingObject.
     * 
     * @param matchingObject
     *            the MatchingObject to select.
     */
    protected void setSelection() {
        StructuredSelection selection = (StructuredSelection) tableViewer
            .getSelection();
        if (selection.isEmpty()) {
            tableViewer.getTable().setSelection(0);
            handleSelectionChange();
        }
    }

    /**
     * Retreive the filter text field.
     * 
     * @return the filter text field.
     */
    public Text getFilterText() {
        return filterText;
    }

    /**
     * Retreive the element selection service job.
     * 
     * @return the element selection service job.
     */
    public ElementSelectionServiceJob getSelectionServiceJob() {
        return job;
    }

    /**
     * Handle the double click of a selection in the table viewer.
     */
    protected void handleWidgetDefaultSelected() {
        /** Default behavior is to do nothing. Subclasses can override. */
    }
}
