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

package org.eclipse.debug.internal.ui.preferences;

import java.io.IOException;
import java.io.StringReader;
import com.ibm.icu.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.ILaunchMode;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchGroupFilter;
import org.eclipse.debug.internal.ui.launchConfigurations.PerspectiveManager;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.preference.RadioGroupFieldEditor;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.activities.ActivityManagerEvent;
import org.eclipse.ui.activities.IActivityManagerListener;
import org.eclipse.ui.activities.WorkbenchActivityHelper;
import org.eclipse.ui.model.WorkbenchViewerSorter;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Provides one place to set perspective preferences
 * 
 * @since 3.2
 */
public class PerspectivePreferencePage extends PreferencePage implements IWorkbenchPreferencePage, IDebugPreferenceConstants, IActivityManagerListener {

	// constants
	private static final String DEBUG_LAUNCH_GROUP = "org.eclipse.debug.ui.launchGroup.debug"; //$NON-NLS-1$

	private static final String LAST_SELECTED_CONFIGTYPE = "last_selected"; //$NON-NLS-1$

	private static final int LABEL_WIDTH_HINT = 450;

	/**
	 * A composite to add and dispose fComboComposites from
	 */
	private Composite fPerspectiveComp = null;
	
	/**
	 * Launch configuration type to mode mapping. allows us to store all the
	 * changed information until ok, apply or cancel is pressed Formed as
	 * follows: Map<typeId,HashMap<modeId, perspective>>
	 */
	private HashMap fTypeInformationMapping = null;

	/**
	 * The list of perspective labels
	 */
	private String[] fPerspectiveLabels = null;

	/**
	 * A mapping of perspective labels to ids of the form Map<label, id>
	 */
	private HashMap fPerspectiveIds = null;

	/**
	 * the composite to add the combo boxes and their labels to
	 */
	private Composite fComboPlaceHolder = null;

	/**
	 * the viewer for the list of launch configurations
	 */
	private TreeViewer fViewer = null;

	/**
	 * The tree for the viewer
	 */
	private Tree fTree = null;

	/**
	 * Manages a launch configuration
	 */
	private ILaunchManager fLManager = DebugPlugin.getDefault().getLaunchManager();

	/**
	 * The global manager for all launch configurations
	 */
	private LaunchConfigurationManager fLCM = DebugUIPlugin.getDefault().getLaunchConfigurationManager();

	/**
	 * manages perspectives
	 */
	private PerspectiveManager fPmanager = DebugUIPlugin.getDefault().getPerspectiveManager();

	/**
	 * The field for switching perspective on run/debug
	 */
	private RadioGroupFieldEditor perspec = null;

	/**
	 * The field for switching when suspends
	 */
	private RadioGroupFieldEditor suspend = null;

	/**
	 * The currently selected ILaunchConfiguration from the tree
	 */
	private ILaunchConfigurationType fCurrentType = null;

	/**
	 * listens for widgets to change their selection. In this case we use it
	 * soley for setting changes in any of the combo boxes for perspective
	 * types.
	 */
	private SelectionAdapter fSelectionAdapter = new SelectionAdapter() {
		public void widgetSelected(SelectionEvent e) {
			Object source = e.getSource();
			if (source instanceof Combo) {
				Combo combo = (Combo) source;
				HashMap map = (HashMap) fTypeInformationMapping.get(fCurrentType);
				if (map == null) {
					map = new HashMap();
				}// end if
				map.put(combo.getData(), fPerspectiveIds.get(combo.getText()));
				fTypeInformationMapping.put(fCurrentType, map);
			}// end if
		}// end widgetselected
	};

	/**
	 * Default constructor
	 */
	public PerspectivePreferencePage() {
		IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore();
		setPreferenceStore(store);
		setTitle(DebugPreferencesMessages.PerspectivePreferencePage_6);
		setDescription(DebugPreferencesMessages.PerspectivePreferencePage_0);
	}// end constructor

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.IPreferencePage#performOk()
	 */
	public boolean performOk() {
		IPreferenceStore store = getPreferenceStore();
		perspec.store();
		suspend.store();
		for (Iterator iter = fTypeInformationMapping.keySet().iterator(); iter.hasNext();) {
			ILaunchConfigurationType typekey = (ILaunchConfigurationType)iter.next();
			HashMap map = (HashMap) fTypeInformationMapping.get(typekey);
			for (Iterator iter2 = map.keySet().iterator(); iter2.hasNext();) {
				String modekey = (String) iter2.next();
				String perspective = (String) map.get(modekey);
				if (perspective != null) {
					if (perspective.equals(DebugPreferencesMessages.PerspectivePreferencePage_4)) {
						perspective = IDebugUIConstants.PERSPECTIVE_NONE;
					}// end if
				}// end if
				else {
					perspective = IDebugUIConstants.PERSPECTIVE_NONE;
				}//end else
				fPmanager.setLaunchPerspective(typekey, modekey, perspective);
			}// end for
		}// end for
		if(fCurrentType != null) {
			store.setValue(LAST_SELECTED_CONFIGTYPE, fCurrentType.getName());
		}
		DebugUIPlugin.getDefault().savePluginPreferences();
		return super.performOk();
	}// end performOK

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
	 */
	public void init(IWorkbench workbench) {}

	/**
	 * Restore the state from the preference store
	 */
	private void restoreState() {
		String xml = getPreferenceStore().getString(IInternalDebugUIConstants.PREF_LAUNCH_PERSPECTIVES);
//	bug 111485	in case a new plugin offers a launch type between invocations, do this prior to setting them to saved states
		setDefaultPerspectives();
		if (xml != null && xml.length() > 0) {
			try {
				Element root = null;
				DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
				parser.setErrorHandler(new DefaultHandler());
				StringReader reader = new StringReader(xml);
				InputSource source = new InputSource(reader);
				root = parser.parse(source).getDocumentElement();
				NodeList list = root.getChildNodes();
				int length = list.getLength();
				for (int i = 0; i < length; ++i) {
					Node node = list.item(i);
					short nt = node.getNodeType();
					if (nt == Node.ELEMENT_NODE) {
						Element element = (Element) node;
						String nodeName = element.getNodeName();
						if (nodeName.equalsIgnoreCase(PerspectiveManager.ELEMENT_PERSPECTIVE)) {
							String type = element.getAttribute(PerspectiveManager.ATTR_TYPE_ID);
							ILaunchConfigurationType typeobj = fLManager.getLaunchConfigurationType(type);
							String mode = element.getAttribute(PerspectiveManager.ATTR_MODE_ID);
							if(typeobj != null) {
								String perspective = fPmanager.getLaunchPerspective(typeobj, mode);
								HashMap map = (HashMap) fTypeInformationMapping.get(typeobj);
								if(map == null) {
									map = new HashMap();
								}//end if
								map.put(mode, (perspective != null ? perspective : IDebugUIConstants.PERSPECTIVE_NONE));
								fTypeInformationMapping.put(typeobj, map);
							}//end if
						}// end if
					}// end if
				}// end for
			}// end try
			catch (ParserConfigurationException e) {DebugUIPlugin.log(e);} 
			catch (SAXException e) {DebugUIPlugin.log(e);}
			catch (IOException e) {DebugUIPlugin.log(e);}
		}// end if
		perspec.load();
		suspend.load();
		TreeItem item = findLastSelected(getPreferenceStore().getString(LAST_SELECTED_CONFIGTYPE));
		if (item != null) {
			fTree.setSelection(new TreeItem[] { item });
		}// end if
		else {
			if(fTree.getItemCount() > 0) {
				fTree.setSelection(new TreeItem[] { fTree.getItem(0) });
			}
		}// end else
		fCurrentType = (ILaunchConfigurationType) ((IStructuredSelection) fViewer.getSelection()).getFirstElement();
		buildComboBoxes(fCurrentType);
	}// restoreState

	/**
	 * Sets the default perspectives for the modes of an ILaunchConfiguration
	 */
	private void setDefaultPerspectives() {
		ILaunchConfigurationType[] types = fLManager.getLaunchConfigurationTypes();
		ArrayList modes = null;
		HashMap map = null;
		for (int i = 0; i < types.length; i++) {
			modes = new ArrayList(types[i].getSupportedModes());
			map = new HashMap();
			for (int j = 0; j < modes.size(); j++) {
				String mode = (String) modes.get(j);
				String persp = fPmanager.getDefaultLaunchPerspective(types[i], mode);
				map.put(mode, (persp != null ? persp : IDebugUIConstants.PERSPECTIVE_NONE));
			}// end for
			fTypeInformationMapping.put(types[i], map);
		}// end for
	}//setDefaultPerspective

	/**
	 * Finds the ILaunchConfiguration within the tree based on its text
	 * 
	 * @param last
	 *            the name of the last Launch Configuration selected
	 * @return the treeitem if found or null
	 */
	private TreeItem findLastSelected(String last) {
		TreeItem[] selection = fTree.getItems();
		for (int i = 0; i < selection.length; i++) {
			if (selection[i].getText().equals(last)) {
				return selection[i];
			}// end if
		}// end for
		return null;
	}// end findLastSelected

	/**
	 * Builds all possible combo boxes per supported modes
	 */
	private void buildComboBoxes(ILaunchConfigurationType type) {
		HashMap launchmodes = (HashMap) fTypeInformationMapping.get(type);
		if (fComboPlaceHolder != null) {
			fComboPlaceHolder.dispose();
		}// end if
		Font font = fPerspectiveComp.getFont();
		fComboPlaceHolder = new Composite(fPerspectiveComp, SWT.NONE);
		fComboPlaceHolder.setLayout(new GridLayout(2, false));
		fComboPlaceHolder.setLayoutData(new GridData(GridData.FILL_BOTH));
		fComboPlaceHolder.setFont(font);
		Label label = new Label(fComboPlaceHolder, SWT.NONE);
		label.setText(DebugPreferencesMessages.PerspectivePreferencePage_2);
		label.setFont(font);
		GridData gd = null;
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 2;
		label.setLayoutData(gd);
		if(launchmodes != null) {
			for(Iterator iter = launchmodes.keySet().iterator(); iter.hasNext();) {
				String modekey = (String)iter.next();
				String persp = (String)launchmodes.get(modekey);
	       // build label
				label = new Label(fComboPlaceHolder, SWT.NONE);
				label.setFont(font);
				gd = new GridData(GridData.BEGINNING);
				label.setLayoutData(gd);
				ILaunchMode mode = fLManager.getLaunchMode(modekey);
				String clabel = mode.getLabel();
				//resolve conflict with Default and Debug mneumonics bug 122882
				if(clabel.equals(DebugPreferencesMessages.PerspectivePreferencePage_7)) {
					clabel = DebugPreferencesMessages.PerspectivePreferencePage_8;
				}
				label.setText(MessageFormat.format(DebugPreferencesMessages.PerspectivePreferencePage_3, new String[] { clabel }));
			// build combobox
				Combo combo = new Combo(fComboPlaceHolder, SWT.READ_ONLY);
				combo.setFont(font);
				combo.setItems(fPerspectiveLabels);
				combo.setData(modekey);
				gd = new GridData(GridData.BEGINNING);
				combo.setLayoutData(gd);
				if(persp.equals(IDebugUIConstants.PERSPECTIVE_NONE)) {
					persp = DebugPreferencesMessages.PerspectivePreferencePage_4;
				}//end if
				else {
					IPerspectiveDescriptor desc = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(persp);
					persp = (desc != null ? desc.getLabel() : DebugPreferencesMessages.PerspectivePreferencePage_4);
				}//end else
				combo.setText(persp);
				combo.addSelectionListener(fSelectionAdapter);
			}//end for
		}
		fPerspectiveComp.layout();
	}// buildComboBoxes

	/**
	 * Handles the change in selection from the launch configuration listing
	 * 
	 * @param event
	 *            the selection changed event
	 */
	private void handleLaunchConfigurationSelectionChanged(SelectionChangedEvent event) {
		// handle prompting and saving before moving on.
		ILaunchConfigurationType type = (ILaunchConfigurationType) ((IStructuredSelection) event.getSelection()).getFirstElement();
		if(type != null) {
			if(!type.equals(fCurrentType)) {
				//if they are the same do nothing
				fCurrentType = type;
				buildComboBoxes(fCurrentType);
			}
		}
	}// end handleLaunchConfigurationSelectionChanged

	/**
	 * Gets the perspective labels
	 * 
	 * @return the (label, id) mappings of perspectives
	 */
	private void getPerspectiveLabels() {
		IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry();
		IPerspectiveDescriptor[] descriptors = filterIds(registry.getPerspectives());
		fPerspectiveLabels = new String[descriptors.length + 1];
		fPerspectiveLabels[0] = DebugPreferencesMessages.PerspectivePreferencePage_4;
		fPerspectiveIds = new HashMap();
		for (int i = 0; i < descriptors.length; i++) {
			fPerspectiveLabels[i + 1] = descriptors[i].getLabel();
			fPerspectiveIds.put(descriptors[i].getLabel(), descriptors[i].getId());
		}// end for
	}// end getPerspectiveLabels

	/**
	 * filters the list of labels based on capabilities
	 * @param ids ther ids we want to filter
	 * @return the filtered list of ids based on capabilities
	 */
	private IPerspectiveDescriptor[] filterIds(IPerspectiveDescriptor[] ids) {
		ArrayList list = new ArrayList();
		for(int i = 0; i < ids.length; i++) {
			if(!WorkbenchActivityHelper.filterItem(ids[i])) {
				list.add(ids[i]);
			}
		}
		return (IPerspectiveDescriptor[])list.toArray(new IPerspectiveDescriptor[list.size()]);
	}
	
	/**
	 * Simple method to create a spacer in the page
	 * 
	 * @param composite
	 *            the composite to add the spacer to
	 * @param columnSpan
	 *            the amount of space for the spacer
	 */
	protected void createSpacer(Composite composite, int columnSpan) {
		Label label = new Label(composite, SWT.NONE);
		GridData gd = new GridData();
		gd.horizontalSpan = columnSpan;
		label.setLayoutData(gd);
	}// end createSpacer

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
	 */
	protected void performDefaults() {
		perspec.loadDefault();
		suspend.loadDefault();
		setDefaultPerspectives();
		buildComboBoxes(fCurrentType);
		super.performDefaults();
	}// end performdefaults

	/* (non-Javadoc)
	 * @see org.eclipse.jface.preference.PreferencePage#createControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createControl(Composite parent) {
		super.createControl(parent);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IDebugHelpContextIds.PERSPECTIVE_PREFERENCE_PAGE);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createContents(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout(1, false));
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        
	// create the global radio buttons
		createSpacer(composite, 1);
		perspec = new RadioGroupFieldEditor(
				IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE,
				DebugPreferencesMessages.LaunchingPreferencePage_11, 3,
				new String[][] {{DebugPreferencesMessages.LaunchingPreferencePage_12, MessageDialogWithToggle.ALWAYS },
							{ DebugPreferencesMessages.LaunchingPreferencePage_13, MessageDialogWithToggle.NEVER },
							{ DebugPreferencesMessages.LaunchingPreferencePage_14, MessageDialogWithToggle.PROMPT } }, 
							composite,
							true);
		perspec.setPreferenceName(IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE);
		perspec.setPreferenceStore(getPreferenceStore());
		suspend = new RadioGroupFieldEditor(
				IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND,
				DebugPreferencesMessages.DebugPreferencePage_21, 3,
				new String[][] {{ DebugPreferencesMessages.DebugPreferencePage_22, MessageDialogWithToggle.ALWAYS },
								{ DebugPreferencesMessages.DebugPreferencePage_23, MessageDialogWithToggle.NEVER },
								{ DebugPreferencesMessages.DebugPreferencePage_24, MessageDialogWithToggle.PROMPT } }, 
								composite,
								true);
		suspend.setPreferenceName(IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND);
		suspend.setPreferenceStore(getPreferenceStore());
		
		createSpacer(composite, 1);
		
		Label lbl = new Label(composite, SWT.LEFT + SWT.WRAP);
		lbl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		((GridData)lbl.getLayoutData()).widthHint = LABEL_WIDTH_HINT;
		lbl.setText(MessageFormat.format(DebugPreferencesMessages.PerspectivePreferencePage_5, null));
		
		Composite comp = new Composite(composite, SWT.FILL);
		comp.setLayout(new GridLayout(2, false));
		comp.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		Composite treeComp = new Composite(comp, SWT.NONE);
		treeComp.setLayout(new GridLayout(1, true));
		treeComp.setLayoutData(new GridData(GridData.FILL_BOTH));
		Label label = new Label(treeComp, SWT.NONE);
		label.setText(DebugPreferencesMessages.PerspectivePreferencePage_1);
		
		fTree = new Tree(treeComp, SWT.H_SCROLL + SWT.V_SCROLL + SWT.SINGLE + SWT.BORDER);
		fTree.setLayoutData(new GridData(GridData.FILL_BOTH));
		fViewer = new TreeViewer(fTree);
		fViewer.setLabelProvider(DebugUITools.newDebugModelPresentation());
		fViewer.setSorter(new WorkbenchViewerSorter());
		fViewer.setContentProvider(new LaunchConfigurationTreeContentProviderNoChildren(null, parent.getShell()));
		fViewer.addFilter(new LaunchGroupFilter(fLCM.getLaunchGroup(DEBUG_LAUNCH_GROUP)));
		fViewer.setInput(fLManager.getLaunchConfigurationTypes());
		fViewer.expandAll();
		fViewer.addPostSelectionChangedListener(new ISelectionChangedListener() {
					public void selectionChanged(SelectionChangedEvent event) {
						handleLaunchConfigurationSelectionChanged(event);
					}//end selectionChanged
				});
		fPerspectiveComp = new Composite(comp, SWT.NONE);
		fPerspectiveComp.setLayout(new GridLayout(1, true));
		fPerspectiveComp.setLayoutData(new GridData(GridData.FILL_BOTH));
		fTypeInformationMapping = new HashMap();
		// get the available labels
		getPerspectiveLabels();
		// restore from preference store
		restoreState();
        
		PlatformUI.getWorkbench().getActivitySupport().getActivityManager().addActivityManagerListener(this);
		
		Dialog.applyDialogFont(composite);
		return composite;
	}// end createControl

	/* (non-Javadoc)
	 * @see org.eclipse.ui.activities.IActivityManagerListener#activityManagerChanged(org.eclipse.ui.activities.ActivityManagerEvent)
	 */
	public void activityManagerChanged(ActivityManagerEvent activityManagerEvent) {
		if(!fTree.isDisposed()) {
			fViewer.refresh();
			getPerspectiveLabels();
			restoreState();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.DialogPage#dispose()
	 */
	public void dispose() {
		PlatformUI.getWorkbench().getActivitySupport().getActivityManager().removeActivityManagerListener(this);
		super.dispose();
	}

}// end class
