/*******************************************************************************
 * Copyright (c) 2004 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.wst.xsd.ui.internal.dialogs.types.common;

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

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

public class ComponentSelectionDialog extends Dialog {
    private Display display = Display.getCurrent();
    private String dialogTitle;

    protected IComponentSelectionProvider provider;
    private List componentTreeViewerInput;
    private List masterComponentList;
    
    // widgets
    protected Composite topComposite;
    protected Composite bottomComposite; 
    private String filterTextLabel = "";
    private String componentListLabel = "Components:";  // TODO: Externalize String
    private Text textFilter;
    protected TreeViewer componentTreeViewer;
    private org.eclipse.swt.widgets.List qualifierList;
    
    protected Object componentSelection;
    protected Object qualifierTextSelection;

    public ComponentSelectionDialog(Shell shell, String dialogTitle, IComponentSelectionProvider provider) {
        super(shell);
        setShellStyle(getShellStyle() | SWT.RESIZE);
        this.dialogTitle = dialogTitle;
        this.provider = provider;
        
        componentTreeViewerInput = new ArrayList();
        masterComponentList = new ArrayList();
    }

    /*
     * This method should be called before createDialogArea(Composite)
     */
    public void setComponentTreeLabel(String string) {
        componentListLabel = string;
    }

    /*
     * This method should be called before createDialogArea(Composite)
     */
    public void setFilterLabel(String string) {
        filterTextLabel = string;
    }
    
    public void create() {
        super.create();
        setTextFilterFocus();
    }
    
    protected void setTextFilterFocus() {
        textFilter.setFocus();        
    }

    public Control createDialogArea(Composite parent) {
        getShell().setText(dialogTitle);

        Composite mainComposite = (Composite) super.createDialogArea(parent);
        GridData gData = (GridData) mainComposite.getLayoutData();
        gData.heightHint = 500;
        gData.widthHint = 400;

        // Subclasses may use this Composite to add desired widgets
        //topComposite = new Composite(mainComposite, SWT.NONE);
        //topComposite.setLayoutData(new GridData());
        //topComposite.setLayout(new GridLayout());
        
        // do we need to introduce a method here to contain this
        // so we can add different parent other than 'topComposite'
        Composite filterLabelAndTree = new Composite(mainComposite, SWT.NONE);
        GridData gd = new GridData(GridData.FILL_BOTH);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        filterLabelAndTree.setLayoutData(new GridData(GridData.FILL_BOTH));
        filterLabelAndTree.setLayout(layout);

        // Create Text textFilter
        Label filterLabel = new Label(filterLabelAndTree, SWT.NONE);
        filterLabel.setText(filterTextLabel);// + "(? = any character, * = any string):"); // TODO: Externalize String

        textFilter = new Text(filterLabelAndTree, SWT.SINGLE | SWT.BORDER);
        textFilter.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));        
        textFilter.addModifyListener(new TextFilterModifyAdapter());
        GridData textFilterData = new GridData();
        textFilterData.horizontalAlignment = GridData.FILL;
        textFilterData.grabExcessHorizontalSpace = true;
        textFilter.setLayoutData(textFilterData);

        //textFilter.setSelection(0);
        //textFilter.setf
        
        
        // Create Component TreeViewer
        createComponentTreeViewer(filterLabelAndTree);

        // Create Qualifier List widget
        Label qualifierLabel = new Label(mainComposite, SWT.NONE);
        qualifierLabel.setText("Qualifier:");                       // TODO: Externalize String

        qualifierList = new org.eclipse.swt.widgets.List(mainComposite, SWT.BORDER | SWT.SINGLE);
        GridData data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        data.grabExcessHorizontalSpace = true;
        data.heightHint = 45;
        qualifierList.setLayoutData(data);
                
        bottomComposite = new Composite(mainComposite, SWT.NONE);
        bottomComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        bottomComposite.setLayout(new GridLayout());

        // Populate the Component TreeViewer via the provider
        // TODO: Is this the right way to set/get the ContentProvider?
        componentTreeViewer.setContentProvider(new ComponentTreeContentProvider());
        componentTreeViewer.setLabelProvider(provider.getLabelProvider());
        componentTreeViewer.setSorter(new ViewerSorter());
        componentTreeViewer.setInput(componentTreeViewerInput);
        
        populateMasterComponentList();
        refreshTreeViewer("");

        return mainComposite;
    }

    protected TreeViewer createTreeViewer(Composite comp, String title) {
        Label label = new Label(comp, SWT.NONE);
        label.setText(title);

        TreeViewer treeViewer = new TreeViewer(new Tree(comp, SWT.SINGLE | SWT.BORDER));
        Control treeWidget = treeViewer.getTree();
        GridData gd = new GridData(GridData.FILL_BOTH);
        treeWidget.setLayoutData(gd);

        return treeViewer;
    }
    
    /*
     * Creates the Component TreeViewer.
     */
    private void createComponentTreeViewer(Composite base) {
        componentTreeViewer = createTreeViewer(base, componentListLabel);    
        
        componentTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                IStructuredSelection structuredSelection = (IStructuredSelection) event.getSelection();
                List qualifiers = provider.getQualifiers(structuredSelection.getFirstElement());
                updateQualifierList(qualifiers);
                updateCanFinish();
            }
        });
    }
    
    private void updateQualifierList(List qualifiers) {
        qualifierList.removeAll();
        Iterator it = qualifiers.iterator();
        while (it.hasNext()) {
            qualifierList.add(it.next().toString());
        }
    }
    
    
    /*
     * Returns the processed filter text for the Text field.  Inserts a "."
     * before each supported meta-character.
     */
    protected String getProcessedFilterString() {
        return processFilterString(textFilter.getText());
    }

    /*
     * If supported metacharacters are used in the filter string, we need to
     * insert a "." before each metacharacter.
     */
    private String processFilterString(String inputString) {
        if (!(inputString.equals(""))) {
            inputString = insertString("*", ".", inputString);
            inputString = insertString("?", ".", inputString);
            inputString = inputString + ".*";
        } else {
            inputString = ".*";
        }

        return inputString.toLowerCase();
    }
    
    /*
     * Helper method to insert a "." before each metacharacter in the
     * search/filter string.
     */
    private String insertString(String target, String newString, String string) {
        ArrayList list = new ArrayList();
        StringBuffer stringBuffer = new StringBuffer(string);

        int index = stringBuffer.indexOf(target);
        while (index != -1) {
            stringBuffer = stringBuffer.insert(index, newString);
            index = stringBuffer.indexOf(target, index + newString.length() + target.length());
        }

        return stringBuffer.toString();
    }

    /*
     * Listens to changes made in the text filter widget
     */
    private class TextFilterModifyAdapter implements ModifyListener {
        public void modifyText(ModifyEvent e) {
            if (e.widget == textFilter) {
                if (delayedEvent != null) {
                    delayedEvent.CANCEL = true;
                }

                delayedEvent = new DelayedEvent();
                Display.getCurrent().timerExec(400, delayedEvent);
            }
        }
    }

    //TODO... do we really need one instance?
    private DelayedEvent delayedEvent;

    /*
     * Update the component TreeViewer when the text filter is modified.
     * Use a DelayedEvent so we don't update on every keystroke.
     */
    private class DelayedEvent implements Runnable {
        public boolean CANCEL = false;

        public void run() {
            if (!CANCEL) {
                refreshTreeViewer(getProcessedFilterString());
                
                // Select first match
                if (componentTreeViewer.getTree().getItemCount() > 0) {
                    TreeItem item = componentTreeViewer.getTree().getItems()[0];
                    TreeItem items[] = new TreeItem[1];
                    items[0] = item;
                    componentTreeViewer.getTree().setSelection(items);
                }
                
                // Update qualifierList
                IStructuredSelection structuredSelection = (IStructuredSelection) componentTreeViewer.getSelection();
                List qualifiers = provider.getQualifiers(structuredSelection.getFirstElement());
                updateQualifierList(qualifiers);
                
                updateCanFinish();
            }
        }
    }

    class ComponentList implements IComponentList {
        private Vector objectVector = new Vector();
        private long currentChangeCounter = 0;
        
        public void addComponent(Object o) {
            objectVector.add(o);
            currentChangeCounter++;
            doViewerUpdate();
        }
        
        private void doViewerUpdate() {
            // TODO: Investigate if we should also add a timer condition??
            if (currentChangeCounter == 10) {
                currentChangeCounter = 0;
                fireUpdateList(this);
            }
        }

        public int size() {
            return objectVector.size();
        }
        
        public List subList(int startIndex, int endIndex) {
            return objectVector.subList(startIndex, endIndex);
        }
        
        public Iterator iterator() {
            return objectVector.iterator();
        }
    }

    
    // this method gets called from a non-ui thread so needs to call
    // asyncExec to ensure the UI updates happen on the UI thread
    //
    protected void fireUpdateList(final ComponentList list) {    
        Runnable runnable = new Runnable() {
            public void run(){
                // add new objects
                int growingListSize = list.size();
                int currentSize = masterComponentList.size();
                if (growingListSize > currentSize) {
                    masterComponentList.addAll(list.subList(currentSize, growingListSize));
                }

                refreshTreeViewer(getProcessedFilterString());
            }
        };
        display.asyncExec(runnable);        
    }

    
    /*
     * Populate the Component TreeViewer with items.
     */
    protected void populateMasterComponentList() {
        masterComponentList.clear();
        ILabelProvider labelProvider = provider.getLabelProvider();
        
        final ComponentList componentList = new ComponentList();
        provider.getComponents(componentList, true);
        
        Job job = new Job("read components") {
          protected IStatus run(IProgressMonitor monitor) {
            try {
              // this stuff gets executed on a non-UI thread
              //
              provider.getComponents(componentList, false);
              
              // Do a final update of our Input for the component tree viewer.
              fireUpdateList(componentList);
            }
            catch (Exception e) {
            }
            return Status.OK_STATUS;
          }          
        };
        job.schedule();
    }
    
    protected void refreshTreeViewer(String filterText) {
        componentTreeViewerInput.clear();
        ILabelProvider labelProvider = provider.getLabelProvider();
        Pattern regex = Pattern.compile(filterText);
        Iterator it = masterComponentList.iterator();
        while (it.hasNext()) {
            Object item = it.next();
            String itemString = labelProvider.getText(item);           
            Matcher m = regex.matcher(itemString.toLowerCase());
            if (itemString.toLowerCase().startsWith(filterText) || m.matches()) {
                componentTreeViewerInput.add(item);
            }
        }
        
        componentTreeViewer.refresh();
    }
    
    /*
     * If there is a selection in the ComponentTreeViewer, enable OK
     */
    protected void updateCanFinish() {
        IStructuredSelection selection = (IStructuredSelection) componentTreeViewer.getSelection();
        if (selection.getFirstElement() != null) {
            getButton(IDialogConstants.OK_ID).setEnabled(true);
        }
        else {
            getButton(IDialogConstants.OK_ID).setEnabled(false);
        }
    }
    
    protected void okPressed() {
        IStructuredSelection selection = (IStructuredSelection) componentTreeViewer.getSelection();
        componentSelection = selection.getFirstElement();
        int qualifierIndex = qualifierList.getSelectionIndex();
        if (qualifierIndex < 0) {
            qualifierIndex = 0;
        }
        qualifierTextSelection = qualifierList.getItem(qualifierIndex);
        
        super.okPressed();
    }
    
    private class ComponentTreeContentProvider implements ITreeContentProvider {
        public Object[] getChildren(Object parentElement) {
            if (parentElement instanceof List) {
                return ((List) parentElement).toArray();
            }
            return new Object[0];
        }
        
        public Object[] getElements(Object inputElement) {
            return getChildren(inputElement);
        }
        
        public Object getParent(Object element) {
            return null;
        }
        
        public boolean hasChildren(Object element) {
            if (getChildren(element).length > 0) {
                return true;
            }
            return false;
        }
        
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }
        
        public void dispose() {
        }
    }
}
