/*******************************************************************************
 * Copyright (c) 2000, 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:
 *   Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation 
 * 			(report 36180: Callers/Callees view)
 *   Michael Fraenkel (fraenkel@us.ibm.com) - patch
 *          (report 60714: Call Hierarchy: display search scope in view title)
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.callhierarchy;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.jdt.core.search.IJavaSearchScope;

import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;

import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionGroup;

import org.eclipse.jdt.ui.IContextMenuConstants;

class SearchScopeActionGroup extends ActionGroup {
	private static final String TAG_SEARCH_SCOPE_TYPE= "search_scope_type"; //$NON-NLS-1$
	private static final String TAG_SELECTED_WORKING_SET= "working_set"; //$NON-NLS-1$
	private static final String TAG_WORKING_SET_COUNT = "working_set_count"; //$NON-NLS-1$
	
	private static final String DIALOGSTORE_SCOPE_TYPE= "SearchScopeActionGroup.search_scope_type"; //$NON-NLS-1$
	private static final String DIALOGSTORE_SELECTED_WORKING_SET= "SearchScopeActionGroup.working_set";  //$NON-NLS-1$
	
	static final int SEARCH_SCOPE_TYPE_WORKSPACE= 1;
	static final int SEARCH_SCOPE_TYPE_PROJECT= 2;
	static final int SEARCH_SCOPE_TYPE_HIERARCHY= 3;
	static final int SEARCH_SCOPE_TYPE_WORKING_SET= 4;
	
	private SearchScopeAction fSelectedAction = null;
	private String[] fSelectedWorkingSetNames = null;
	private CallHierarchyViewPart fView;
	private IDialogSettings fDialogSettings;
	private SearchScopeHierarchyAction fSearchScopeHierarchyAction;
	private SearchScopeProjectAction fSearchScopeProjectAction;
	private SearchScopeWorkspaceAction fSearchScopeWorkspaceAction;
	private SelectWorkingSetAction fSelectWorkingSetAction;
	
	public SearchScopeActionGroup(CallHierarchyViewPart view, IDialogSettings dialogSettings) {
		this.fView= view;
		this.fDialogSettings= dialogSettings;
		createActions();
	}
	
	/**
	 * @return IJavaSearchScope
	 */
	public IJavaSearchScope getSearchScope() {
		if (fSelectedAction != null) {
			return fSelectedAction.getSearchScope();
		}
		
		return null;
	}
	
	public void fillActionBars(IActionBars actionBars) {
		super.fillActionBars(actionBars);
		fillContextMenu(actionBars.getMenuManager());
	}
	
	protected void setActiveWorkingSets(IWorkingSet[] sets) {
		if (sets != null) {
			fSelectedWorkingSetNames = getWorkingSetNames(sets);
			fSelectedAction = new SearchScopeWorkingSetAction(this, sets, getScopeDescription(sets));
		} else {
			fSelectedWorkingSetNames = null;
			fSelectedAction = null;
		}
	}
	
	private String[] getWorkingSetNames(IWorkingSet[] sets) {
		String[] result= new String[sets.length];
		for (int i = 0; i < sets.length; i++) {
			result[i]= sets[i].getName();
		}
		return result;
	}
	
	protected IWorkingSet[] getActiveWorkingSets() {
		if (fSelectedWorkingSetNames != null) {
			return getWorkingSets(fSelectedWorkingSetNames);
		}
		
		return null;
	}
	
	private IWorkingSet[] getWorkingSets(String[] workingSetNames) {
		if (workingSetNames == null) {
			return null;   
		}
		Set workingSets= new HashSet(2);
		for (int j= 0; j < workingSetNames.length; j++) {
			IWorkingSet workingSet= getWorkingSetManager().getWorkingSet(workingSetNames[j]);
			if (workingSet != null) {
				workingSets.add(workingSet);
			}
		}
		
		return (IWorkingSet[])workingSets.toArray(new IWorkingSet[workingSets.size()]);
	}
	
	/**
	 * Sets the new search scope type.
	 *  
	 * @param newSelection New action which should be the checked one
	 * @param ignoreUnchecked Ignores actions which are unchecked (necessary since both the old and the new action fires).
	 */
	protected void setSelected(SearchScopeAction newSelection, boolean ignoreUnchecked) {
		if (!ignoreUnchecked || newSelection.isChecked()) {
			if (newSelection instanceof SearchScopeWorkingSetAction) {
				fSelectedWorkingSetNames = getWorkingSetNames(((SearchScopeWorkingSetAction) newSelection).getWorkingSets());
			} else {
				fSelectedWorkingSetNames = null;
			}
			
			if (newSelection != null) {
				fSelectedAction= newSelection;
			} else {
				fSelectedAction= fSearchScopeWorkspaceAction;
			}
			
			fDialogSettings.put(DIALOGSTORE_SCOPE_TYPE, getSearchScopeType());
			fDialogSettings.put(DIALOGSTORE_SELECTED_WORKING_SET, fSelectedWorkingSetNames);
		}
	}
	
	protected CallHierarchyViewPart getView() {
		return fView;
	}
	
	protected IWorkingSetManager getWorkingSetManager() {
		IWorkingSetManager workingSetManager = PlatformUI.getWorkbench()
		.getWorkingSetManager();
		
		return workingSetManager;
	}
	
	protected void fillSearchActions(IMenuManager javaSearchMM) {
		Action[] actions = getActions();
		
		for (int i = 0; i < actions.length; i++) {
			Action action = actions[i];
			
			if (action.isEnabled()) {
				javaSearchMM.add(action);
			}
		}
		
		javaSearchMM.setVisible(!javaSearchMM.isEmpty());
	}
	
	public void fillContextMenu(IMenuManager menu) {
		menu.add(new Separator(IContextMenuConstants.GROUP_SEARCH));
		
		MenuManager javaSearchMM = new MenuManager(CallHierarchyMessages.SearchScopeActionGroup_searchScope, 
				IContextMenuConstants.GROUP_SEARCH);
		javaSearchMM.setRemoveAllWhenShown(true);
		
		javaSearchMM.addMenuListener(new IMenuListener() {
			/* (non-Javadoc)
			 * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
			 */
			public void menuAboutToShow(IMenuManager manager) {
				fillSearchActions(manager);
			}
		});
		
		fillSearchActions(javaSearchMM);
		menu.appendToGroup(IContextMenuConstants.GROUP_SEARCH, javaSearchMM);
	}
	
	private Action[] getActions() {
		List actions = new ArrayList(SearchUtil.LRU_WORKINGSET_LIST_SIZE + 4);
		addAction(actions, fSearchScopeWorkspaceAction);
		addAction(actions, fSearchScopeProjectAction);
		addAction(actions, fSearchScopeHierarchyAction);
		addAction(actions, fSelectWorkingSetAction);
		
		Iterator iter= SearchUtil.getLRUWorkingSets().sortedIterator();
		while (iter.hasNext()) {
			IWorkingSet[] workingSets= (IWorkingSet[])iter.next();
			String description = SearchUtil.toString(workingSets);
			SearchScopeWorkingSetAction workingSetAction = new SearchScopeWorkingSetAction(this, workingSets, description);
			
			if (isSelectedWorkingSet(workingSets)) {
				workingSetAction.setChecked(true);
			}
			
			actions.add(workingSetAction);
		}
		
		Action[] result = (Action[]) actions.toArray(new Action[actions.size()]);
		
		ensureExactlyOneCheckedAction(result);
		return result;
	}
	
	private void ensureExactlyOneCheckedAction(Action[] result) {
		int checked = getCheckedActionCount(result);
		if (checked != 1) {
			if (checked > 1) {
				for (int i = 0; i < result.length; i++) {
					Action action = result[i];
					action.setChecked(false);
				}
			}
			fSearchScopeWorkspaceAction.setChecked(true);
		}
	}
	
	private int getCheckedActionCount(Action[] result) {
		// Ensure that exactly one action is selected
		int checked= 0;
		for (int i = 0; i < result.length; i++) {
			Action action = result[i];
			if (action.isChecked()) {
				checked++;
			}
		}
		return checked;
	}
	
	private void addAction(List actions, Action action) {
		if (action == fSelectedAction) {
			action.setChecked(true);
		} else {
			action.setChecked(false);
		}
		
		actions.add(action);
	}
	
	private void createActions() {
		fSearchScopeWorkspaceAction = new SearchScopeWorkspaceAction(this);
		fSelectWorkingSetAction = new SelectWorkingSetAction(this);
		fSearchScopeHierarchyAction = new SearchScopeHierarchyAction(this);
		fSearchScopeProjectAction = new SearchScopeProjectAction(this);
		
		int searchScopeType;
		try {
			searchScopeType= fDialogSettings.getInt(DIALOGSTORE_SCOPE_TYPE);
		} catch (NumberFormatException e) {
			searchScopeType= SEARCH_SCOPE_TYPE_WORKSPACE;
		}
		String[] workingSetNames= fDialogSettings.getArray(DIALOGSTORE_SELECTED_WORKING_SET);
		setSelected(getSearchScopeAction(searchScopeType, workingSetNames), false);
	}
	
	public void saveState(IMemento memento) {
		int type= getSearchScopeType();
		memento.putInteger(TAG_SEARCH_SCOPE_TYPE, type);
		if (type == SEARCH_SCOPE_TYPE_WORKING_SET) {
			memento.putInteger(TAG_WORKING_SET_COUNT, fSelectedWorkingSetNames.length);
			for (int i = 0; i < fSelectedWorkingSetNames.length; i++) {
				String workingSetName = fSelectedWorkingSetNames[i];
				memento.putString(TAG_SELECTED_WORKING_SET+i, workingSetName);
			}
		}
	}
	
	public void restoreState(IMemento memento) {
		String[] workingSetNames= null;
		Integer scopeType= memento.getInteger(TAG_SEARCH_SCOPE_TYPE);
		if (scopeType != null) {
			if (scopeType.intValue() == SEARCH_SCOPE_TYPE_WORKING_SET) {
				Integer workingSetCount= memento.getInteger(TAG_WORKING_SET_COUNT);
				if (workingSetCount != null) {
					workingSetNames = new String[workingSetCount.intValue()];
					for (int i = 0; i < workingSetCount.intValue(); i++) {
						workingSetNames[i]= memento.getString(TAG_SELECTED_WORKING_SET+i);
					}   
				}
			}
			setSelected(getSearchScopeAction(scopeType.intValue(), workingSetNames), false);
		}
	}
	
	private SearchScopeAction getSearchScopeAction(int searchScopeType, String[] workingSetNames) {
		switch (searchScopeType) {
			case SEARCH_SCOPE_TYPE_WORKSPACE: 
				return fSearchScopeWorkspaceAction;
			case SEARCH_SCOPE_TYPE_PROJECT: 
				return fSearchScopeProjectAction;
			case SEARCH_SCOPE_TYPE_HIERARCHY: 
				return fSearchScopeHierarchyAction;
			case SEARCH_SCOPE_TYPE_WORKING_SET:
				IWorkingSet[] workingSets= getWorkingSets(workingSetNames);
				if (workingSets != null && workingSets.length > 0) {
					return new SearchScopeWorkingSetAction(this, workingSets, getScopeDescription(workingSets));
				}
				return null;
		}
		return null;
	}
	
	private int getSearchScopeType() {
		if (fSelectedAction != null) {
			return fSelectedAction.getSearchScopeType();
		}
		return 0;
	}
	
	private String getScopeDescription(IWorkingSet[] workingSets) {
		return Messages.format(CallHierarchyMessages.WorkingSetScope, new String[] {SearchUtil.toString(workingSets)}); 
	}
	
	/**
	 * Determines whether the specified working sets correspond to the currently selected working sets.
	 * @param workingSets
	 * @return Returns true if the specified working sets correspond to the currently selected working sets
	 */
	private boolean isSelectedWorkingSet(IWorkingSet[] workingSets) {
		if (fSelectedWorkingSetNames != null && fSelectedWorkingSetNames.length == workingSets.length) {
			Set workingSetNames= new HashSet(workingSets.length);
			for (int i = 0; i < workingSets.length; i++) {
				workingSetNames.add(workingSets[i].getName());
			}
			for (int i = 0; i < fSelectedWorkingSetNames.length; i++) {
				if (!workingSetNames.contains(fSelectedWorkingSetNames[i])) {
					return false;
				}
			}
			return true;
		}
		return false;
	}
	
	public String getFullDescription() {
		if (fSelectedAction != null)
			return fSelectedAction.getFullDescription();
		return null;
	}
}

