/*******************************************************************************
 * Copyright (c) 2005, 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.debug.internal.ui.importexport.breakpoints;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import org.eclipse.core.runtime.Assert;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointContainer;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsComparator;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsContentProvider;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsLabelProvider;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsView;
import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsViewer;
import org.eclipse.debug.internal.ui.views.breakpoints.IBreakpointOrganizer;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IViewPart;

/**
 * This class creates a simplified debug view that can be used in wizards etc., to emulate the current debug view
 * 
 * @see WizardExportBreakpointsPage
 * @see WizardImportBreakpointsPage
 *
 * @since 3.2
 */
public class EmbeddedBreakpointsViewer {

	//widgets
	private IStructuredSelection fSelection = null;
	private BreakpointsContentProvider fProvider = null;
	private Tree fTree = null;
	private BreakpointsViewer fViewer = null;
	private ICheckStateListener fCheckListener = new ICheckStateListener() {
		public void checkStateChanged(CheckStateChangedEvent event) {
			updateCheckedState(event.getElement(), event.getChecked());
		}
	};
	
	/**
	 * This constructor allows a specific selection to be used in stead of the default
	 * 
	 * @param parent the parent composite to add this one to
	 * @param input the input to the viewer
	 * @param selection the selection to set on the viewer
	 */
	public EmbeddedBreakpointsViewer(Composite parent, Object input, IStructuredSelection selection) {
		Assert.isNotNull(parent);
		Assert.isNotNull(input);
		createControl(parent, input, selection);
	}
	
	/**
	 * Creates the control initialized to the current view, selection, and organization of the breakpoints view
	 * @param parent the parent composite to add this one to.
	 * 
	 * @param parent the parent composite to add this one to
	 * @param input the input for the viewer
	 * @param selection the selection for the viewer to be initialized to. If null the selection from the breakpoints view is used
	 */
	private void createControl(Composite parent, Object input, IStructuredSelection selection) {
		fSelection = selection;
		if(fSelection == null) {
			IViewPart fViewpart = DebugUIPlugin.getActiveWorkbenchWindow().getActivePage().findView(IDebugUIConstants.ID_BREAKPOINT_VIEW);
			if(fViewpart != null) {
				fSelection = (IStructuredSelection)fViewpart.getViewSite().getSelectionProvider().getSelection();
			}
			else {
				fSelection = new StructuredSelection();
			}
		}
		Composite composite = SWTFactory.createComposite(parent, parent.getFont(), 1, 1, GridData.FILL_BOTH, 0, 0);
		
		// create the treeview
		fTree = new Tree(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CHECK);
		GridData gd = new GridData(GridData.FILL_BOTH);
		gd.heightHint = 150;
		fTree.setLayoutData(gd);
		fProvider = new BreakpointsContentProvider();
		BreakpointsView view = ((BreakpointsView)DebugUIPlugin.getActiveWorkbenchWindow().getActivePage().findView(IDebugUIConstants.ID_BREAKPOINT_VIEW));
		fViewer = new BreakpointsViewer(fTree);
		BreakpointsLabelProvider labelprovider = new BreakpointsLabelProvider();
		if(view != null) {
			//if we have handle to the view try get the current attributes, that way the 
			//presentation of the embedded viewer matches the current view
			IBaseLabelProvider current = ((StructuredViewer)view.getViewer()).getLabelProvider();
			if (current instanceof BreakpointsLabelProvider) {
				current = ((BreakpointsLabelProvider)current).getPresentation();
			}
			Map map = null;
			if(current instanceof DelegatingModelPresentation) {
				map = ((DelegatingModelPresentation) current).getAttributes();
			}
			if(map != null) {
				Object key = null;
				IDebugModelPresentation newpres = labelprovider.getPresentation();
				for(Iterator iter = map.keySet().iterator(); iter.hasNext();) {
					key = iter.next();
					newpres.setAttribute((String) key, map.get(key));
				}
			}
		}
		fViewer.setComparator(new BreakpointsComparator());
		fViewer.setLabelProvider(labelprovider);
		fViewer.addCheckStateListener(fCheckListener);
		IBreakpointOrganizer[] orgs = null;
		if(view != null) {
			 orgs = view.getBreakpointOrganizers();
		}
		fViewer.setContentProvider(fProvider);
		fViewer.setInput(input);
		fProvider.setOrganizers(orgs);
		initViewerState();
	}
	
	/**
	 * Performs the initialization of the viewer from a selection
	 */
	private void initViewerState() {
		Object[] items = fSelection.toArray();
		fViewer.setGrayedElements(new Object[] {});
		fViewer.setCheckedElements(new Object[] {});
		ArrayList list = new ArrayList();
		for(int i = 0; i < items.length; i++) {
			Object item = items[i];
			if(item instanceof IBreakpoint) {
				list.add(item);
			}
			else if (item instanceof BreakpointContainer) {
				getBreakpointsFromContainers((BreakpointContainer)item, list);
			}
		}
		for(int i = 0; i < list.size(); i++) {
			updateCheckedState(list.get(i), true);
		}
	}
	
	/**
	 * FInds the breakpoints of a given container
	 * @param container the container to get breakpoints from
	 * @param list the list of breakpoints to update state for
	 */
	private void getBreakpointsFromContainers(BreakpointContainer container, ArrayList list) {
		Object[] elements = container.getChildren();
		for(int i = 0; i < elements.length; i++) {
			if(elements[i] instanceof IBreakpoint) {
				list.add(elements[i]);
			}
			else {
				getBreakpointsFromContainers((BreakpointContainer)elements[i], list);
			}
		}
	}
	
	/**
	 * Returns the selection from the viewer with no duplicates
	 * @return the selection from the viewer with no duplicates
	 */
	public IStructuredSelection getCheckedElements() {
		Object[] list = fViewer.getCheckedElements();
		Vector selected = new Vector();
		for(int i = 0; i < list.length; i++) {
			if(!selected.contains(list[i])) {
				selected.addElement(list[i]);
			}
		}
		return new StructuredSelection(selected);
	}
	
	/**
	 * Allows access to the viewer
	 * @return the viewer
	 */
	public BreakpointsViewer getViewer() {
		return fViewer;
	}
   
	/**
	 * finds all occurrences of a widget to update
	 * @param element the element to search for when finding occurrences
	 * @return a list of widget occurrences to update or an empty list
	 */
    private Widget[] searchItems(Object element) {
        ArrayList list = new ArrayList();
        TreeItem[] items = fTree.getItems();
        for (int i = 0; i < items.length; i++) {
        	findAllOccurrences(items[i], element, list);
        }
        return (Widget[]) list.toArray(new Widget[0]);
    }
    
    /**
     * performs the actual search for items in the tree
     * @param list the list to add matches to
     * @param item the item in the tree
     * @param element the element to compare
     */
    private void findAllOccurrences(TreeItem item, Object element, ArrayList list) {
        if (element.equals(item.getData())) {
                list.add(item);
        }
        TreeItem[] items = item.getItems();
        for (int i = 0; i < items.length; i++) {
        	findAllOccurrences(items[i], element, list);
        }
    }
    
	 /**
     * Update the checked state of the given element and all of its children.
     * 
     * @param obj the object that has been changed
     * @param enable the checked status of the obj
     */
    private void updateCheckedState(Object obj, boolean enable) {
	        if (obj instanceof IBreakpoint) {
	        	Widget[] list = searchItems(obj);
	        	TreeItem item = null;
	        	for(int i = 0; i < list.length; i++) {
		        	item = (TreeItem)list[i];
		            item.setChecked(enable);
		            refreshParents(item);
	        	}
	        }
	        else if (obj instanceof BreakpointContainer) {
	        	ArrayList bps = new ArrayList();
	        	getBreakpointsFromContainers((BreakpointContainer)obj, bps);
	        	for(int j = 0; j < bps.size(); j++) {
	        		updateCheckedState(bps.get(j), enable);
	        	}
	        }
     }

    /**
     * refreshes the grayed/checked state of the parents of item
     * @param item the item to refresh parents of
     */
    private void refreshParents(TreeItem item) {
    	TreeItem parent = item.getParentItem();
    	while (parent != null) {
    		int checked = getNumberChildrenChecked(parent);
        	if(checked == 0) {
        		parent.setGrayed(false);
            	parent.setChecked(false);
        	}
        	else if(checked == parent.getItemCount()) {
        		if(getNumberChildrenGrayed(parent) > 0) {
        			parent.setGrayed(true);
        		}
        		else {
        			parent.setGrayed(false);
        		}
         		parent.setChecked(true);
        	}
        	else {
        		parent.setGrayed(true);
            	parent.setChecked(true);
        	}
    		parent = parent.getParentItem();
    	}
    }
    
    /**
     * Gets the number of grayed children for this parent
     * @param parent the parent to inspect
     * @return treu is any one or more children is grayed, false otherwise
     */
    private int getNumberChildrenGrayed(TreeItem parent) {
    	TreeItem[] children = parent.getItems();
    	int count = 0;
    	for(int i = 0; i < children.length; i++) {
    		if(children[i].getGrayed()) {
    			count++;
    		}
    	}
    	return count;
    }
    
    /**
     * Checks to see if all of the children under an given parent are checked or not
     * @param children the children to check
     * @return true if all children are checked, false otherwise
     */
    private int getNumberChildrenChecked(TreeItem parent) {
    	TreeItem[] children = parent.getItems();
    	int count = 0;
    	for(int i = 0; i < children.length; i++) {
    		if(children[i].getChecked()) {
    			count++;
    		}
    	}
    	return count;
    }
}
