/*******************************************************************************
 * Copyright (c) 2004, 2005 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
 *     Chris Longfield <clongfield@internap.com> - Fix for Bug 70856
 *******************************************************************************/

package org.eclipse.jface.viewers;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.util.Assert;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Widget;

/**
 * Abstract base class for viewers that contain lists of items (such as a combo or list).
 * Most of the viewer implementation is in this base class, except for the minimal code that
 * actually communicates with the underlying widget.
 * 
 * @see org.eclipse.jface.viewers.ListViewer
 * @see org.eclipse.jface.viewers.ComboViewer
 * 
 * @since 3.0
 */
public abstract class AbstractListViewer extends StructuredViewer {

    /**
     * A list of viewer elements (element type: <code>Object</code>).
     */
    private java.util.List listMap = new ArrayList();

    /**
     * Adds the given string to the underlying widget at the given index
     *  
     * @param string the string to add
     * @param index position to insert the string into
     */
    protected abstract void listAdd(String string, int index);

    /**
     * Sets the text of the item at the given index in the underlying widget.
     * 
     * @param index index to modify
     * @param string new text
     */
    protected abstract void listSetItem(int index, String string);

    /**
     * Returns the zero-relative indices of the items which are currently
     * selected in the underlying widget.  The array is empty if no items are selected.
     * <p>
     * Note: This is not the actual structure used by the receiver
     * to maintain its selection, so modifying the array will
     * not affect the receiver. 
     * </p>
     * @return the array of indices of the selected items
     */
    protected abstract int[] listGetSelectionIndices();

    /**
     * Returns the number of items contained in the underlying widget.
     *
     * @return the number of items
     */
    protected abstract int listGetItemCount();

    /**
     * Sets the underlying widget's items to be the given array of items.
     *
     * @param labels the array of label text
     */
    protected abstract void listSetItems(String[] labels);

    /**
     * Removes all of the items from the underlying widget.
     */
    protected abstract void listRemoveAll();

    /**
     * Removes the item from the underlying widget at the given
     * zero-relative index.
     * 
     * @param index the index for the item
     */
    protected abstract void listRemove(int index);

    /**
     * Selects the items at the given zero-relative indices in the underlying widget.
     * The current selection is cleared before the new items are selected.
     * <p>
     * Indices that are out of range and duplicate indices are ignored.
     * If the receiver is single-select and multiple indices are specified,
     * then all indices are ignored.
     *
     * @param ixs the indices of the items to select
     */
    protected abstract void listSetSelection(int[] ixs);

    /**
     * Shows the selection.  If the selection is already showing in the receiver,
     * this method simply returns.  Otherwise, the items are scrolled until
     * the selection is visible.
     */
    protected abstract void listShowSelection();

    /**
     * Deselects all selected items in the underlying widget.
     */
    protected abstract void listDeselectAll();

    /**
     * Adds the given elements to this list viewer.
     * If this viewer does not have a sorter, the elements are added at the end
     * in the order given; otherwise the elements are inserted at appropriate positions.
     * <p>
     * This method should be called (by the content provider) when elements 
     * have been added to the model, in order to cause the viewer to accurately
     * reflect the model. This method only affects the viewer, not the model.
     * </p>
     *
     * @param elements the elements to add
     */
    public void add(Object[] elements) {
        assertElementsNotNull(elements);
        Object[] filtered = filter(elements);
        ILabelProvider labelProvider = (ILabelProvider) getLabelProvider();
        for (int i = 0; i < filtered.length; i++) {
            Object element = filtered[i];
            int ix = indexForElement(element);
            listAdd(getLabelProviderText(labelProvider,element), ix);
            listMap.add(ix, element);
            mapElement(element, getControl()); // must map it, since findItem only looks in map, if enabled
        }
    }
    
    /**
     * Return the text for the element from the labelProvider.
     * If it is null then return the empty String.
     * @param labelProvider ILabelProvider
     * @param element
     * @return String. Return the emptyString if the labelProvider
     * returns null for the text.
     * 
     * @since 3.1
     */
    private String getLabelProviderText(ILabelProvider labelProvider, Object element){
    	String text = labelProvider.getText(element);
        if(text == null)
        	return "";//$NON-NLS-1$
        return text;
    }

    /**
     * Adds the given element to this list viewer.
     * If this viewer does not have a sorter, the element is added at the end;
     * otherwise the element is inserted at the appropriate position.
     * <p>
     * This method should be called (by the content provider) when a single element 
     * has been added to the model, in order to cause the viewer to accurately
     * reflect the model. This method only affects the viewer, not the model.
     * Note that there is another method for efficiently processing the simultaneous
     * addition of multiple elements.
     * </p>
     *
     * @param element the element
     */
    public void add(Object element) {
        add(new Object[] { element });
    }

    /* (non-Javadoc)
     * Method declared on StructuredViewer.
     * Since SWT.List doesn't use items we always return the List itself.
     */
    protected Widget doFindInputItem(Object element) {
        if (element != null && equals(element, getRoot()))
            return getControl();
        return null;
    }

    /* (non-Javadoc)
     * Method declared on StructuredViewer.
     * Since SWT.List doesn't use items we always return the List itself.
     */
    protected Widget doFindItem(Object element) {
        if (element != null) {
            if (listMap.contains(element))
                return getControl();
        }
        return null;
    }

    /* (non-Javadoc)
     * Method declared on StructuredViewer.
     */
    protected void doUpdateItem(Widget data, Object element, boolean fullMap) {
        if (element != null) {
            int ix = listMap.indexOf(element);
            if (ix >= 0) {
                ILabelProvider labelProvider = (ILabelProvider) getLabelProvider();
                listSetItem(ix, getLabelProviderText(labelProvider,element));
            }
        }
    }

    /* (non-Javadoc)
     * Method declared on Viewer.
     */
    public abstract Control getControl();

    /**
     * Returns the element with the given index from this list viewer.
     * Returns <code>null</code> if the index is out of range.
     *
     * @param index the zero-based index
     * @return the element at the given index, or <code>null</code> if the
     *   index is out of range
     */
    public Object getElementAt(int index) {
        if (index >= 0 && index < listMap.size())
            return listMap.get(index);
        return null;
    }

    /**
     * The list viewer implementation of this <code>Viewer</code> framework
     * method returns the label provider, which in the case of list
     * viewers will be an instance of <code>ILabelProvider</code>.
     */
    public IBaseLabelProvider getLabelProvider() {
        return super.getLabelProvider();
    }

    /* (non-Javadoc)
     * Method declared on Viewer.
     */
    /* (non-Javadoc)
     * Method declared on StructuredViewer.
     */
    protected List getSelectionFromWidget() {
        int[] ixs = listGetSelectionIndices();
        ArrayList list = new ArrayList(ixs.length);
        for (int i = 0; i < ixs.length; i++) {
            Object e = getElementAt(ixs[i]);
            if (e != null)
                list.add(e);
        }
        return list;
    }

    /*
     * Returns the index where the item should be inserted.
     */
    protected int indexForElement(Object element) {
        ViewerSorter sorter = getSorter();
        if (sorter == null)
            return listGetItemCount();
        int count = listGetItemCount();
        int min = 0, max = count - 1;
        while (min <= max) {
            int mid = (min + max) / 2;
            Object data = listMap.get(mid);
            int compare = sorter.compare(this, data, element);
            if (compare == 0) {
                // find first item > element
                while (compare == 0) {
                    ++mid;
                    if (mid >= count) {
                        break;
                    }
                    data = listMap.get(mid);
                    compare = sorter.compare(this, data, element);
                }
                return mid;
            }
            if (compare < 0)
                min = mid + 1;
            else
                max = mid - 1;
        }
        return min;
    }

    /* (non-Javadoc)
     * Method declared on Viewer.
     */
    protected void inputChanged(Object input, Object oldInput) {
        listMap.clear();
        Object[] children = getSortedChildren(getRoot());
        int size = children.length;

        listRemoveAll();
        String[] labels = new String[size];
        for (int i = 0; i < size; i++) {
            Object el = children[i];
            labels[i] = getLabelProviderText((ILabelProvider) getLabelProvider(),el);
            listMap.add(el);
            mapElement(el, getControl()); // must map it, since findItem only looks in map, if enabled
        }
        listSetItems(labels);
    }

    /* (non-Javadoc)
     * Method declared on StructuredViewer.
     */
    protected void internalRefresh(Object element) {

        Control list = getControl();
        if (element == null || equals(element, getRoot())) {
            // the parent
            if (listMap != null)
                listMap.clear();
            unmapAllElements();
            List selection = getSelectionFromWidget();

            list.setRedraw(false);
			listRemoveAll();
            
            Object[] children = getSortedChildren(getRoot());
			String[] items = new String[children.length];
			
			ILabelProvider labelProvider = (ILabelProvider) getLabelProvider();
			
			for (int i = 0; i < items.length; i++) {
                Object el = children[i];
                items[i] = getLabelProviderText(labelProvider, el);
                listMap.add(el);
                mapElement(el, list); // must map it, since findItem only looks in map, if enabled
            }
			
			listSetItems(items);
            list.setRedraw(true);
            setSelectionToWidget(selection, false);
        } else {
            doUpdateItem(list, element, true);
        }
    }

    /**
     * Removes the given elements from this list viewer.
     *
     * @param elements the elements to remove
     */
    private void internalRemove(final Object[] elements) {
        Object input = getInput();
        for (int i = 0; i < elements.length; ++i) {
            if (equals(elements[i], input)) {
                setInput(null);
                return;
            }
            int ix = listMap.indexOf(elements[i]);
            if (ix >= 0) {
                listRemove(ix);
                listMap.remove(ix);
                unmapElement(elements[i], getControl());
            }
        }
    }

    /**
     * Removes the given elements from this list viewer.
     * The selection is updated if required.
     * <p>
     * This method should be called (by the content provider) when elements 
     * have been removed from the model, in order to cause the viewer to accurately
     * reflect the model. This method only affects the viewer, not the model.
     * </p>
     *
     * @param elements the elements to remove
     */
    public void remove(final Object[] elements) {
        assertElementsNotNull(elements);
        if (elements.length == 0) {
        	return;
        }
        preservingSelection(new Runnable() {
            public void run() {
                internalRemove(elements);
            }
        });
    }

    /**
     * Removes the given element from this list viewer.
     * The selection is updated if necessary.
     * <p>
     * This method should be called (by the content provider) when a single element 
     * has been removed from the model, in order to cause the viewer to accurately
     * reflect the model. This method only affects the viewer, not the model.
     * Note that there is another method for efficiently processing the simultaneous
     * removal of multiple elements.
     * </p>
     *
     * @param element the element
     */
    public void remove(Object element) {
        remove(new Object[] { element });
    }

    /**
     * The list viewer implementation of this <code>Viewer</code> framework
     * method ensures that the given label provider is an instance
     * of <code>ILabelProvider</code>.
     */
    public void setLabelProvider(IBaseLabelProvider labelProvider) {
        Assert.isTrue(labelProvider instanceof ILabelProvider);
        super.setLabelProvider(labelProvider);
    }

    /* (non-Javadoc)
     * Method declared on StructuredViewer.
     */
    protected void setSelectionToWidget(List in, boolean reveal) {
        if (in == null || in.size() == 0) { // clear selection
            listDeselectAll();
        } else {
            int n = in.size();
            int[] ixs = new int[n];
            int count = 0;
            for (int i = 0; i < n; ++i) {
                Object el = in.get(i);
                int ix = listMap.indexOf(el);
                if (ix >= 0)
                    ixs[count++] = ix;
            }
            if (count < n) {
                System.arraycopy(ixs, 0, ixs = new int[count], 0, count);
            }
            listSetSelection(ixs);
            if (reveal) {
                listShowSelection();
            }
        }
    }

    int getElementIndex(Object element) {
        return listMap.indexOf(element);
    }

}
