/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.ide.misc;

import java.util.*;
import java.util.List;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.util.ListenerList;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;

/**
 *	Workbench-level composite that combines a CheckboxTreeViewer and CheckboxListViewer.
 *	All viewer selection-driven interactions are handled within this object
 */
public class CheckboxTreeAndListGroup implements ICheckStateListener, ISelectionChangedListener, ITreeViewerListener {
	private	Object			root;
	private	Object			currentTreeSelection;
	private	List			expandedTreeNodes = new ArrayList();
	private	Map				checkedStateStore = new HashMap(9);
	private List			whiteCheckedTreeItems = new ArrayList();
	private	ListenerList	listeners = new ListenerList();
	
	private	ITreeContentProvider		treeContentProvider;
	private	IStructuredContentProvider	listContentProvider;
	private ILabelProvider				treeLabelProvider;
	private ILabelProvider				listLabelProvider;
	
	// widgets
	private	CheckboxTreeViewer	treeViewer;
	private	CheckboxTableViewer	listViewer;
/**
 *	Create an instance of this class.  Use this constructor if you wish to specify
 *	the width and/or height of the combined widget (to only hardcode one of the
 *	sizing dimensions, specify the other dimension's value as -1)
 *
 *	@param parent org.eclipse.swt.widgets.Composite
 *	@param style int
 *  @param rootObject java.lang.Object
 *	@param childPropertyName java.lang.String
 *	@param parentPropertyName java.lang.String
 *	@param listPropertyName java.lang.String
 *	@param width int
 *	@param height int
 */
public CheckboxTreeAndListGroup(
	Composite parent,Object rootObject,
	ITreeContentProvider treeContentProvider,ILabelProvider treeLabelProvider,
	IStructuredContentProvider listContentProvider,ILabelProvider listLabelProvider,
	int style,int width,int height) {

	root = rootObject;
	this.treeContentProvider = treeContentProvider;
	this.listContentProvider = listContentProvider;
	this.treeLabelProvider = treeLabelProvider;
	this.listLabelProvider = listLabelProvider;
	createContents(parent, width, height, style);
}
/**
 * This method must be called just before this window becomes visible.
 */
public void aboutToOpen() {
	determineWhiteCheckedDescendents(root);
	checkNewTreeElements(treeContentProvider.getElements(root));
	currentTreeSelection = null;

	//select the first element in the list
	Object[] elements = treeContentProvider.getElements(root);
	Object primary = elements.length > 0 ? elements[0] : null;
	if (primary != null) {
		treeViewer.setSelection(new StructuredSelection(primary));
	}
	treeViewer.getControl().setFocus();
}
/**
 *	Add the passed listener to self's collection of clients
 *	that listen for changes to element checked states
 *
 *	@param listener ICheckStateListener
 */
public void addCheckStateListener(ICheckStateListener listener) {
	listeners.add(listener);
}
/**
 *	Add the receiver and all of it's ancestors to the checkedStateStore if they
 * are not already there.
 */
private void addToHierarchyToCheckedStore(Object treeElement) {

	// if this tree element is already gray then its ancestors all are as well
	if (!checkedStateStore.containsKey(treeElement))
		checkedStateStore.put(treeElement, new ArrayList());

	Object parent = treeContentProvider.getParent(treeElement);
	if (parent != null)
		addToHierarchyToCheckedStore(parent);
}
/**
 *	Return a boolean indicating whether all children of the passed tree element
 *	are currently white-checked
 *
 *	@return boolean
 *	@param treeElement java.lang.Object
 */
protected boolean areAllChildrenWhiteChecked(Object treeElement) {
	Object[] children = treeContentProvider.getChildren(treeElement);
	for (int i = 0; i < children.length; ++i) {
		if (!whiteCheckedTreeItems.contains(children[i]))
			return false;
	}
	
	return true;
}
/**
 *	Return a boolean indicating whether all list elements associated with
 *	the passed tree element are currently checked
 *
 *	@return boolean
 *	@param treeElement java.lang.Object
 */
protected boolean areAllElementsChecked(Object treeElement) {
	List checkedElements = (List)checkedStateStore.get(treeElement);
	if (checkedElements == null)	// ie.- tree item not even gray-checked
		return false;

	return getListItemsSize(treeElement) == checkedElements.size();
}
/**
 *	Iterate through the passed elements which are being realized for the first
 *	time and check each one in the tree viewer as appropriate
 */
protected void checkNewTreeElements(Object[] elements) {
	for (int i = 0; i < elements.length; ++i) {
		Object currentElement = elements[i];
		boolean checked = checkedStateStore.containsKey(currentElement);
		treeViewer.setChecked(currentElement,checked);
		treeViewer.setGrayed(currentElement,checked && !whiteCheckedTreeItems.contains(currentElement));
	}
}
/**
*	An item was checked in one of self's two views.  Determine which
*	view this occurred in and delegate appropriately
*
*	@param event CheckStateChangedEvent
*/
public void checkStateChanged(final CheckStateChangedEvent event) {

	//Potentially long operation - show a busy cursor
	BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
		public void run() {
			if (event.getCheckable().equals(treeViewer))
				treeItemChecked(event.getElement(), event.getChecked());
			else
				listItemChecked(event.getElement(), event.getChecked(), true);

			notifyCheckStateChangeListeners(event);
		}
	});
}
/**
 *	Lay out and initialize self's visual components.
 *
 *	@param parent org.eclipse.swt.widgets.Composite
 *	@param width int
 *	@param height int
 */
protected void createContents(Composite parent, int width, int height, int style) {
	// group pane
	Composite composite = new Composite(parent,style);
	GridLayout layout = new GridLayout();
	layout.numColumns = 2;
	layout.makeColumnsEqualWidth = true;
	layout.marginHeight = 0;
	layout.marginWidth = 0;
	composite.setLayout(layout);
	composite.setLayoutData(new GridData(GridData.FILL_BOTH));
	composite.setFont(parent.getFont());
			
	createTreeViewer(composite, width/2, height);
	createListViewer(composite, width/2, height);
	
	initialize();
}
/**
 *	Create this group's list viewer.
 */
protected void createListViewer(Composite parent, int width, int height) {
	listViewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER);
	GridData data = new GridData(GridData.FILL_BOTH);
	data.widthHint = width;
	data.heightHint = height;
	listViewer.getTable().setLayoutData(data);
	listViewer.getTable().setFont(parent.getFont());
	listViewer.setContentProvider(listContentProvider);
	listViewer.setLabelProvider(listLabelProvider);
	listViewer.addCheckStateListener(this);
}
/**
 *	Create this group's tree viewer.
 */
protected void createTreeViewer(Composite parent, int width, int height) {
	Tree tree = new Tree(parent, SWT.CHECK | SWT.BORDER);
	GridData data = new GridData(GridData.FILL_BOTH);
	data.widthHint = width;
	data.heightHint = height;
	tree.setLayoutData(data);
	tree.setFont(parent.getFont());
	
	treeViewer = new CheckboxTreeViewer(tree);
	treeViewer.setContentProvider(treeContentProvider);
	treeViewer.setLabelProvider(treeLabelProvider);
	treeViewer.addTreeListener(this);
	treeViewer.addCheckStateListener(this);
	treeViewer.addSelectionChangedListener(this);
}
/**
 * Returns a boolean indicating whether the passed tree element should be
 * at LEAST gray-checked.  Note that this method does not consider whether
 * it should be white-checked, so a specified tree item which should be
 * white-checked will result in a <code>true</code> answer from this method.
 * To determine whether a tree item should be white-checked use method
 * #determineShouldBeWhiteChecked(Object).
 *
 * @param element java.lang.Object
 * @return boolean
 * @see #determineShouldBeWhiteChecked(java.lang.Object)
 */
protected boolean determineShouldBeAtLeastGrayChecked(Object treeElement) {
	// if any list items associated with treeElement are checked then it
	// retains its gray-checked status regardless of its children
	List checked = (List)checkedStateStore.get(treeElement);
	if (checked != null && (!checked.isEmpty()))
		return true;

	// if any children of treeElement are still gray-checked then treeElement
	// must remain gray-checked as well
	Object[] children = treeContentProvider.getChildren(treeElement);
	for (int i = 0 ; i < children.length; ++i) {
		if (checkedStateStore.containsKey(children[i]))
			return true;
	}

	return false;
}
/**
 * Returns a boolean indicating whether the passed tree item should be
 * white-checked.
 *
 * @return boolean
 * @param treeElement java.lang.Object
 */
protected boolean determineShouldBeWhiteChecked(Object treeElement) {
	return areAllChildrenWhiteChecked(treeElement) && areAllElementsChecked(treeElement);
}
/**
 *	Recursively add appropriate tree elements to the collection of
 *	known white-checked tree elements.
 *
 *	@param treeElement java.lang.Object
 */
protected void determineWhiteCheckedDescendents(Object treeElement) {
	// always go through all children first since their white-checked
	// statuses will be needed to determine the white-checked status for
	// this tree element
	Object[] children = treeContentProvider.getElements(treeElement);
	for (int i = 0; i < children.length; ++i)
		determineWhiteCheckedDescendents(children[i]);

	// now determine the white-checked status for this tree element
	if (determineShouldBeWhiteChecked(treeElement))
		setWhiteChecked(treeElement,true);
}
/**
 * Cause the tree viewer to expand all its items
 */
public void expandAll() {
	treeViewer.expandAll();
}
/**
 *	Answer a flat collection of all of the checked elements in the
 *	list portion of self
 *
 *	@return java.util.Vector
 */
public Iterator getAllCheckedListItems() {
	List result = new ArrayList();
	Iterator listCollectionsEnum = checkedStateStore.values().iterator();
	
	while (listCollectionsEnum.hasNext()) {
		Iterator currentCollection = ((List)listCollectionsEnum.next()).iterator();
		while (currentCollection.hasNext())
			result.add(currentCollection.next());
	}
	
	return result.iterator();
}
/**
 *	Answer a collection of all of the checked elements in the tree portion
 *	of self
 *
 *	@return java.util.Vector
 */
public Set getAllCheckedTreeItems() {
	return checkedStateStore.keySet();
}
/**
 *	Answer the number of elements that have been checked by the
 *	user.
 *
 *	@return int
 */
public int getCheckedElementCount() {
	return checkedStateStore.size();
}
/**
 *	Return a count of the number of list items associated with a
 *	given tree item.
 *
 *	@return int
 *	@param treeElement java.lang.Object
 */
protected int getListItemsSize(Object treeElement) {
	Object[] elements = listContentProvider.getElements(treeElement);
	return elements.length;
}
/**
 * Get the table the list viewer uses.
 * @return org.eclipse.swt.widgets.Table
 */
public Table getListTable() {
	return this.listViewer.getTable();
}
/**
 *	Logically gray-check all ancestors of treeItem by ensuring that they
 *	appear in the checked table
 */
protected void grayCheckHierarchy(Object treeElement) {

	// if this tree element is already gray then its ancestors all are as well
	if (checkedStateStore.containsKey(treeElement))
		return;		// no need to proceed upwards from here

	checkedStateStore.put(treeElement,new ArrayList());
	if (determineShouldBeWhiteChecked(treeElement)) {
		setWhiteChecked(treeElement, true);
	}
	Object parent = treeContentProvider.getParent(treeElement);
	if (parent != null)
		grayCheckHierarchy(parent);
}
/**
 *	Set the initial checked state of the passed list element to true.
 */
public void initialCheckListItem(Object element) {
	Object parent = treeContentProvider.getParent(element);
	currentTreeSelection = parent;
	//As this is not done from the UI then set the box for updating from the selection to false 
	listItemChecked(element, true, false);
	updateHierarchy(parent);
}
/**
 *	Set the initial checked state of the passed element to true,
 *	as well as to all of its children and associated list elements
 */
public void initialCheckTreeItem(Object element) {
	treeItemChecked(element, true);
}
/**
 *	Initialize this group's viewers after they have been laid out.
 */
protected void initialize() {
	treeViewer.setInput(root);
}
/**
 *	Callback that's invoked when the checked status of an item in the list
 *	is changed by the user. Do not try and update the hierarchy if we are building the
 *  initial list.
 */
protected void listItemChecked(
	Object listElement,
	boolean state,
	boolean updatingFromSelection) {
	List checkedListItems = (List) checkedStateStore.get(currentTreeSelection);

	if (state) {
		if (checkedListItems == null) {
			// since the associated tree item has gone from 0 -> 1 checked
			// list items, tree checking may need to be updated
			grayCheckHierarchy(currentTreeSelection);
			checkedListItems = (List) checkedStateStore.get(currentTreeSelection);
		}
		checkedListItems.add(listElement);
	} else {
		checkedListItems.remove(listElement);
		if (checkedListItems.isEmpty()) {
			// since the associated tree item has gone from 1 -> 0 checked
			// list items, tree checking may need to be updated
			ungrayCheckHierarchy(currentTreeSelection);
		}
	}

	if (updatingFromSelection)
		updateHierarchy(currentTreeSelection);
}
/**
 *	Notify all checked state listeners that the passed element has had
 *	its checked state changed to the passed state
 */
protected void notifyCheckStateChangeListeners(final CheckStateChangedEvent event) {
	Object[] array = listeners.getListeners();
	for (int i = 0; i < array.length; i ++) {
		final ICheckStateListener l = (ICheckStateListener)array[i];
		Platform.run(new SafeRunnable() {
			public void run() {
				l.checkStateChanged(event);
			}
			public void handleException(Throwable e) {
				super.handleException(e);
				//If and unexpected exception happens, remove it
				//to make sure the workbench keeps running.
				removeCheckStateListener(l);
			}
		});
	}
}
/**
 *Set the contents of the list viewer based upon the specified selected
 *tree element.  This also includes checking the appropriate list items.
 *
 *@param treeElement java.lang.Object
 */
protected void populateListViewer(final Object treeElement) {
	listViewer.setInput(treeElement);
	List listItemsToCheck = (List) checkedStateStore.get(treeElement);

	if (listItemsToCheck != null) {
		Iterator listItemsEnum = listItemsToCheck.iterator();
		while (listItemsEnum.hasNext())
			listViewer.setChecked(listItemsEnum.next(), true);
	}
}
/**
 *	Remove the passed listener from self's collection of clients
 *	that listen for changes to element checked states
 *
 *	@param listener ICheckStateListener
 */
public void removeCheckStateListener(ICheckStateListener listener) {
	listeners.remove(listener);
}
/**
 *	Handle the selection of an item in the tree viewer
 *
 *	@param selection ISelection
 */
public void selectionChanged(SelectionChangedEvent event) {
	IStructuredSelection selection = (IStructuredSelection) event.getSelection();
	Object selectedElement = selection.getFirstElement();
	if (selectedElement == null) {
		currentTreeSelection = null;
		listViewer.setInput(currentTreeSelection);
		return;
	}

	// ie.- if not an item deselection
	if (selectedElement != currentTreeSelection)
		populateListViewer(selectedElement);
	
	currentTreeSelection = selectedElement;
}
/**
 * Select or deselect all of the elements in the tree depending on the value of the selection
 * boolean. Be sure to update the displayed files as well.
 */
public void setAllSelections(final boolean selection) {

	//Potentially long operation - show a busy cursor
	BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
		public void run() {
			setTreeChecked(root, selection);
			listViewer.setAllChecked(selection);
		}
	});
}
/**
 *	Set the list viewer's providers to those passed
 *
 *	@param contentProvider ITreeContentProvider
 *	@param labelProvider ILabelProvider
 */
public void setListProviders(IStructuredContentProvider contentProvider, ILabelProvider labelProvider) {
	listViewer.setContentProvider(contentProvider);
	listViewer.setLabelProvider(labelProvider);
}
/**
 *	Set the sorter that is to be applied to self's list viewer
 */
public void setListSorter(ViewerSorter sorter) {
	listViewer.setSorter(sorter);
}
/**
 * Set the root of the widget to be new Root. Regenerate all of the tables and lists from this
 * value.
 * @param newRoot 
 */
public void setRoot(Object newRoot) {
	this.root = newRoot;
	initialize();
}
/**
 *	Set the checked state of the passed tree element appropriately, and
 *	do so recursively to all of its child tree elements as well
 */
protected void setTreeChecked(Object treeElement,boolean state) {

	if (treeElement.equals(currentTreeSelection)) {
	    listViewer.setAllChecked(state);
	}
	
	if (state) {
		Object[] listItems = listContentProvider.getElements(treeElement);
		List listItemsChecked = new ArrayList();
		for (int i = 0; i < listItems.length; ++i)
			listItemsChecked.add(listItems[i]);

		checkedStateStore.put(treeElement,listItemsChecked);
	} else
		checkedStateStore.remove(treeElement);

	setWhiteChecked(treeElement,state);
	treeViewer.setChecked(treeElement,state);
	treeViewer.setGrayed(treeElement,false);
			
	// now logically check/uncheck all children as well
	Object[] children = treeContentProvider.getChildren(treeElement);
	for (int i = 0; i < children.length; ++i) {
		setTreeChecked(children[i],state);
	}
}
/**
 *	Set the tree viewer's providers to those passed
 *
 *	@param contentProvider ITreeContentProvider
 *	@param labelProvider ILabelProvider
 */
public void setTreeProviders(ITreeContentProvider contentProvider, ILabelProvider labelProvider) {
	treeViewer.setContentProvider(contentProvider);
	treeViewer.setLabelProvider(labelProvider);
}
/**
 *	Set the sorter that is to be applied to self's tree viewer
 */
public void setTreeSorter(ViewerSorter sorter) {
	treeViewer.setSorter(sorter);
}
/**
 *	Adjust the collection of references to white-checked tree elements appropriately.
 *
 *	@param treeElement java.lang.Object
 *	@param isWhiteChecked boolean
 */
protected void setWhiteChecked(Object treeElement, boolean isWhiteChecked) {
	if (isWhiteChecked) {
		if (!whiteCheckedTreeItems.contains(treeElement))
			whiteCheckedTreeItems.add(treeElement);
	} else
		whiteCheckedTreeItems.remove(treeElement);
}
/**
 *	Handle the collapsing of an element in a tree viewer
 */
public void treeCollapsed(TreeExpansionEvent event) {
	// We don't need to do anything with this
}
/**
 *	Handle the expansionsion of an element in a tree viewer
 */
public void treeExpanded(TreeExpansionEvent event) {

	Object item = event.getElement();
	
	// First see if the children need to be given their checked state at all.  If they've
	// already been realized then this won't be necessary
	if (!expandedTreeNodes.contains(item)) {
		expandedTreeNodes.add(item);
		checkNewTreeElements(treeContentProvider.getChildren(item));
	}
}
/**
 *  Callback that's invoked when the checked status of an item in the tree
 *  is changed by the user.
 */
protected void treeItemChecked(Object treeElement,boolean state) {

	// recursively adjust all child tree elements appropriately
	setTreeChecked(treeElement,state);

	Object parent = treeContentProvider.getParent(treeElement);
	if (parent == null)
		return;

	// now update upwards in the tree hierarchy 
	if (state)
		grayCheckHierarchy(parent);
	else
		ungrayCheckHierarchy(parent);
		
	updateHierarchy(treeElement);
}
/**
 *	Logically un-gray-check all ancestors of treeItem iff appropriate.
 */
protected void ungrayCheckHierarchy(Object treeElement) {
	if (!determineShouldBeAtLeastGrayChecked(treeElement))
		checkedStateStore.remove(treeElement);

	Object parent = treeContentProvider.getParent(treeElement);
	if (parent != null)
		ungrayCheckHierarchy(parent);
}
/**
 *	Set the checked state of self and all ancestors appropriately
 */
protected void updateHierarchy(Object treeElement) {

	boolean whiteChecked = determineShouldBeWhiteChecked(treeElement);
	boolean shouldBeAtLeastGray = determineShouldBeAtLeastGrayChecked(treeElement);

	treeViewer.setChecked(treeElement, shouldBeAtLeastGray);
	setWhiteChecked(treeElement, whiteChecked);
	if (!whiteChecked)
		treeViewer.setGrayed(treeElement, shouldBeAtLeastGray);

	// proceed up the tree element hierarchy
	Object parent = treeContentProvider.getParent(treeElement);
	if (parent != null) {
		updateHierarchy(parent);
	}
}
/**
 * Update the selections of the tree elements in items to reflect the new
 * selections provided.
 * @param Map with keys of Object (the tree element) and values of List (the selected
 * list elements).
 */
public void updateSelections(final Map items) {

	//Potentially long operation - show a busy cursor
	BusyIndicator.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
		public void run() {
			Iterator keyIterator = items.keySet().iterator();

			//Update the store before the hierarchy to prevent updating parents before all of the children are done
			while (keyIterator.hasNext()) {
				Object key = keyIterator.next();
				//Replace the items in the checked state store with those from the supplied items
				List selections = (List) items.get(key);
				if (selections.size() == 0)
					//If it is empty remove it from the list
					checkedStateStore.remove(key);
				else {
					checkedStateStore.put(key, selections);
					// proceed up the tree element hierarchy
					Object parent = treeContentProvider.getParent(key);
					if (parent != null) {
						addToHierarchyToCheckedStore(parent);
					}
				}
			}

			//Now update hierarchies
			keyIterator = items.keySet().iterator();

			while (keyIterator.hasNext()) {
				Object key = keyIterator.next();
				updateHierarchy(key);
				if (currentTreeSelection != null && currentTreeSelection.equals(key)) {
					listViewer.setAllChecked(false);
					listViewer.setCheckedElements(((List) items.get(key)).toArray());
				}
			}
		}
	});

}
}
