/*******************************************************************************
 * Copyright (c) 2006, 2008 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.common.ui.internal.search.dialogs;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
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.resources.IFile;
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.action.MenuManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
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.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.osgi.util.TextProcessor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.ViewForm;
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.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
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.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.wst.common.core.search.scope.SearchScope;
import org.eclipse.wst.common.ui.internal.Messages;


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

    protected ComponentSearchListDialogConfiguration configuration;
    private List componentTableViewerInput;
    private List masterComponentList;
    
    // widgets
    protected Composite topComposite;
    protected Composite bottomComposite; 
    private Text textFilter;
    protected TableViewer componentTableViewer;
    
    protected String fileLocationLabel = Messages._UI_LABEL_DECLARATION_LOCATION;
    protected ViewForm fileLocationView;    
    protected CLabel locationLabel;

    // keep track of the item previously selected in the table
	private TableItem prevItem;
	private String prevItemText;

	protected Object componentSelection;
    protected Object qualifierTextSelection;
    
	protected ToolBar filterToolBar;
	protected ToolItem toolItem;
	protected MenuManager fMenuManager;
	
	protected HashMap TableDecoratorTrackingTool = new HashMap();  
    private Button newButton;
 

	public ComponentSearchListDialog(Shell shell, String dialogTitle, ComponentSearchListDialogConfiguration configuration) {
        super(shell);
        setShellStyle(getShellStyle() | SWT.RESIZE);
        this.dialogTitle = dialogTitle;
        this.configuration = configuration;
        componentTableViewerInput = new ArrayList();
        masterComponentList = new ArrayList();
        configuration.init(this);
    }
    
	public void create() {
        super.create();
        getButton(IDialogConstants.OK_ID).setEnabled(false);
        setTextFilterFocus();
    }
    
    protected void setTextFilterFocus() {
        textFilter.setFocus();        
    }

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

        Composite mainComposite = (Composite) super.createDialogArea(parent);
        GridData gData = (GridData) mainComposite.getLayoutData();
        gData.heightHint = 500;
        
        configuration.createWidgetAboveQualifierBox(mainComposite);        
        // 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 filterLabelAndText = new Composite(mainComposite, SWT.NONE);
        GridLayout layoutFilterLabelAndText = new GridLayout(2, false);
        layoutFilterLabelAndText.marginWidth = 0;
        layoutFilterLabelAndText.marginHeight = 0;
        filterLabelAndText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        filterLabelAndText.setLayout(layoutFilterLabelAndText);

        // Create Text textFilter
        
        Label filterLabel = new Label(filterLabelAndText, SWT.NONE);
        filterLabel.setText(configuration.getFilterLabelText());// + "(? = any character, * = any string):");
        GridData filterLabelData = new GridData();
        filterLabelData.horizontalSpan = 2;
        filterLabel.setLayoutData(filterLabelData);

        textFilter = new Text(filterLabelAndText, 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);
        
        final INewComponentHandler handler = configuration.getNewComponentHandler();
        if (handler != null)
        {  
           newButton = new Button(filterLabelAndText, SWT.NONE);
           newButton.setText(Messages._UI_LABEL_New);  
           newButton.addSelectionListener(new SelectionListener()
           {

            public void widgetDefaultSelected(SelectionEvent e)
            {
              handler.openNewComponentDialog();              
            }

            public void widgetSelected(SelectionEvent e)
            {
              handler.openNewComponentDialog();
            }             
           });                   
        }
        
        // Create Component TableViewer
        createComponentTableViewer(mainComposite);

        configuration.createWidgetAboveQualifierBox(mainComposite);
        
        // Create Qualifier List widget
        Label qualifierLabel = new Label(mainComposite, SWT.NONE);
        qualifierLabel.setText(Messages._UI_LABEL_QUALIFIER);
		qualifierLabel.setText(fileLocationLabel);

        fileLocationView = new ViewForm(mainComposite, SWT.BORDER | SWT.FLAT );
        GridData data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        data.grabExcessHorizontalSpace = true;
        data.heightHint = 22;
        fileLocationView.setLayoutData(data);
        
    	locationLabel = new CLabel(fileLocationView, SWT.FLAT);
        fileLocationView.setContent(locationLabel);
    	locationLabel.setFont(fileLocationView.getFont());

        configuration.createWidgetBelowQualifierBox(mainComposite);
        
        bottomComposite = new Composite(mainComposite, SWT.NONE);
        bottomComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        bottomComposite.setLayout(new GridLayout());

        // Populate the Component TableViewer via the provider
        // TODO: Is this the right way to set/get the ContentProvider?
        componentTableViewer.setContentProvider(new ComponentTableContentProvider());
        componentTableViewer.setLabelProvider(configuration.getDescriptionProvider().getLabelProvider());
        componentTableViewer.setSorter(new ViewerSorter());
        componentTableViewer.setInput(componentTableViewerInput);
        
        
        // TODO (cs) need to do some work to make the default search scope
        // more well defined, currently the default behaviour is to pass a null
        // argument in to populateMasterComponentList but we should provide
        // getters/setters to allow the default to be controlled
        populateMasterComponentList(null);
        refreshTableViewer("");

        return mainComposite;
    }
    
    /*
     * Creates the Component TableViewer.
     */
    private void createComponentTableViewer(Composite base) {
        componentTableViewer = createFilterMenuAndTableViewer(base);    
        
        componentTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                //IStructuredSelection structuredSelection = (IStructuredSelection) event.getSelection();
                //List qualifiers = searchListProvider.getQualifiers(structuredSelection.getFirstElement());
                //updateQualifierList(qualifiers);
                updateCanFinish();
            }
        });
        
        componentTableViewer.getTable().addSelectionListener(new SelectionListener(){
        	// Changing the text for the component selected and display its source
        	// file in the box under the table viewer
          
        	IComponentDescriptionProvider descriptionProvider = configuration.getDescriptionProvider();        	
			public void widgetSelected(SelectionEvent e) {				
				run();
			}

			public void widgetDefaultSelected(SelectionEvent e) {
        // bug 144548 - unnecessary
        // run();
			}

			private void run() {
				// restores the text of previous item
				if (prevItem != null && !prevItem.isDisposed()){
					prevItem.setText(prevItemText);
				}
				TableItem[] items = componentTableViewer.getTable().getSelection();
				Object component = items[0].getData();

				prevItem = items[0];
				prevItemText = items[0].getText();

				// add clarification for the first selected item
				items[0].setText(  descriptionProvider.getName(component) + " - " + 
    					descriptionProvider.getQualifier(component));

				updateLocationView(component, descriptionProvider);
			}
        });
        
        componentTableViewer.addDoubleClickListener(new IDoubleClickListener() {

			public void doubleClick(DoubleClickEvent event) {
				okPressed();
			}
        	
        });
    }
    
    protected TableViewer createFilterMenuAndTableViewer(Composite comp) {
    	Composite labelAndFilter = new Composite(comp, SWT.NONE);
    	labelAndFilter.setLayoutData(new GridData(GridData.FILL_BOTH));
		GridLayout layout= new GridLayout();
		layout.numColumns= 2;
		layout.marginWidth= 0; layout.marginHeight= 0;
    	labelAndFilter.setLayout(layout);
    	
        Label tableLabel = new Label(labelAndFilter, SWT.NONE);
        tableLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        tableLabel.setText(configuration.getListLabelText());
        
        filterToolBar = new ToolBar(labelAndFilter,SWT.FLAT);
        configuration.createToolBarItems(filterToolBar);

        TableViewer tableViewer = new TableViewer(new Table(labelAndFilter, SWT.SINGLE | SWT.BORDER));
        Control TableWidget = tableViewer.getTable();
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.horizontalSpan = 2;
        TableWidget.setLayoutData(gd);

        return tableViewer;
    }
    
    private void updateLocationView(Object component, IComponentDescriptionProvider lp) {
    	IFile file = lp.getFile(component);
    	
    	if ( file == null ){
    		locationLabel.setText("");
    		locationLabel.setImage(null);
    		return;
    	}
    	String filePath = "";
    	filePath = file.getFullPath().toString();
        //locationView.redraw();
        
        locationLabel.setText(TextProcessor.process(filePath));
        locationLabel.setImage(lp.getFileIcon(component));
    }
    
    
    /*
     * 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) {
        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 TableViewer 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) {
                refreshTableViewer(getProcessedFilterString());
                
                // Select first match
                if (componentTableViewer.getTable().getItemCount() > 0) {
                    TableItem item = componentTableViewer.getTable().getItems()[0];
                    TableItem items[] = new TableItem[1];
                    items[0] = item;
                    componentTableViewer.getTable().setSelection(items);
                }
                
                // Update qualifierList
                //IStructuredSelection structuredSelection = (IStructuredSelection) componentTableViewer.getSelection();
                // TODO ... manage qualifiers
                //List qualifiers = searchListProvider.getQualifiers(structuredSelection.getFirstElement());
                //updateQualifierList(qualifiers);
                
                updateCanFinish();
            }
        }
    }

    class ComponentList implements IComponentList {
        private Vector objectVector = new Vector();
        private long currentChangeCounter = 0;
        private long lastUpdateTime = 0;
        
        public void add(Object o) {
            objectVector.add(o);
            currentChangeCounter++;
            doViewerUpdate();
        }
        
        public void addAll(Collection collection)
        {
          objectVector.addAll(collection);
          currentChangeCounter += collection.size();
          doViewerUpdate();          
        }
        
        private void doViewerUpdate() {
            // TODO: Investigate if we should also add a timer condition??
          //  if (currentChangeCounter >= 10) {
          //      currentChangeCounter = 0;
          //      fireUpdateList(this);
          //  }
          
          // cs: yep I think we really do need to use a time based approach
          //          
          long time = System.currentTimeMillis();
          if (time - lastUpdateTime > 300)
          {
             lastUpdateTime = time;
             fireUpdateList(ComponentList.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));
                }

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

    
    public void updateForFilterChange()
    {
      populateMasterComponentList(null);
      refreshTableViewer(getProcessedFilterString());
    }  
    
    /*
     * Populate the Component TreeViewer with items.
     */
    protected void populateMasterComponentList(final SearchScope searchScope) {
        masterComponentList.clear();
        
        final ComponentList componentList = new ComponentList();
        
        // TODO (cs) it doesn't seem to make sennse to do any of the work on the UI thread
        // I've change the behaviour here to do all of the work in the background
        //
        //searchListProvider._populateComponentListQuick(componentList, 0);        
        Job job = new Job("read components") {
          protected IStatus run(IProgressMonitor monitor) {
            try {
              // this stuff gets executed on a non-UI thread
              //
              configuration.getSearchListProvider().populateComponentList(componentList, searchScope, null);              
              // Do a final update of our Input for the component tree viewer.
              fireUpdateList(componentList);
            }
            catch (Exception e) {
            	e.printStackTrace();
            }
            return Status.OK_STATUS;
          }          
        };
        job.schedule();
    }
    
    protected void refreshTableViewer(String filterText) {
        componentTableViewerInput.clear();
        ILabelProvider labelProvider = configuration.getDescriptionProvider().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()) {
                componentTableViewerInput.add(item);
            }
        }
        
        componentTableViewer.refresh();
        decorateTable();
    }
    
    /**
     * Looking at each item in the Table. If there are other items with same name
     * , then add extra info (namespace, file) into the the text label of all these
     * duplicated items.
     * - This should be called everytime the Table viewer is refreshed..
     */
    protected void decorateTable(){
    	TableDecoratorTrackingTool.clear();
    	
    	IComponentDescriptionProvider lp = configuration.getDescriptionProvider();

    	// init the name-duplicates counter
    	for (int i = 0; i < componentTableViewerInput.size(); i++){
    		Object currentItem = componentTableViewerInput.get(i);
    		String name = lp.getName(currentItem);
    		Integer count = (Integer) TableDecoratorTrackingTool.get(name);
			if ( count == null){
    			TableDecoratorTrackingTool.put(name, new Integer(1));
    		}
    		else{
    			TableDecoratorTrackingTool.put(
    					name, new Integer(count.intValue() + 1));
    		}
    	}

    	// Modify/decorate those items in the Table that have duplicated name
    	TableItem[] items = componentTableViewer.getTable().getItems();
    	for (int i =0 ; i < items.length; i++){
    		Object currentItem = items[i].getData();
    		Integer count = (Integer) TableDecoratorTrackingTool.get(lp.getName(currentItem));
    		if ( count != null && count.intValue() > 1){	
    			items[i].setText(lp.getName(currentItem) + " - " + 
    					lp.getQualifier(currentItem));
    		}
    	}
    }
    

    
    /*
     * If there is a selection in the ComponentTreeViewer, enable OK
     */
    protected void updateCanFinish() {
        IStructuredSelection selection = (IStructuredSelection) componentTableViewer.getSelection();
        if (selection.getFirstElement() != null) {
            getButton(IDialogConstants.OK_ID).setEnabled(true);
        }
        else {
            getButton(IDialogConstants.OK_ID).setEnabled(false);
        }
    }
    
    protected void okPressed() {
        IStructuredSelection selection = (IStructuredSelection) componentTableViewer.getSelection();
        componentSelection = selection.getFirstElement();
        
        super.okPressed();
    }
    
    private class ComponentTableContentProvider 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() {
        }
    }


    public ComponentSpecification getSelectedComponent()
    {
      ComponentSpecification result = null;
      if (componentSelection != null)
      {  
        result = new ComponentSpecification();
        IComponentDescriptionProvider componentDescriptionProvider = configuration.getDescriptionProvider();
        result.setName(componentDescriptionProvider.getName(componentSelection));
        result.setQualifier(componentDescriptionProvider.getQualifier(componentSelection));
        result.setFile(componentDescriptionProvider.getFile(componentSelection));
        result.setObject(componentSelection);
      }  
      return result;
    }       
}
