/*******************************************************************************
 * Copyright (c) 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.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.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.UIPlugin;


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 = UIPlugin.getString("_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();
        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;
        gData.widthHint = 400;
        
        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(UIPlugin.getString("_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(UIPlugin.getString("_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) {
				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(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
              //
              long time1 = System.currentTimeMillis();
              configuration.getSearchListProvider().populateComponentList(componentList, searchScope, null);              
              // Do a final update of our Input for the component tree viewer.
              fireUpdateList(componentList);
              long time2 = System.currentTimeMillis();
              System.out.println("time=" + (time2 - time1) + " items= " + masterComponentList.size());
            }
            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;
    }       
}
