/*******************************************************************************
 * Copyright (c) 2002, 2007 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.ui.internal.cheatsheets.views;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.help.ui.internal.views.HelpTray;
import org.eclipse.help.ui.internal.views.IHelpPartPage;
import org.eclipse.help.ui.internal.views.ReusableHelpPart;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.cheatsheets.CheatSheetListener;
import org.eclipse.ui.cheatsheets.ICheatSheetEvent;
import org.eclipse.ui.cheatsheets.ICheatSheetViewer;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.internal.cheatsheets.CheatSheetPlugin;
import org.eclipse.ui.internal.cheatsheets.CheatSheetStopWatch;
import org.eclipse.ui.internal.cheatsheets.ICheatSheetResource;
import org.eclipse.ui.internal.cheatsheets.Messages;
import org.eclipse.ui.internal.cheatsheets.actions.IMenuContributor;
import org.eclipse.ui.internal.cheatsheets.composite.model.CompositeCheatSheetModel;
import org.eclipse.ui.internal.cheatsheets.composite.views.CompositeCheatSheetPage;
import org.eclipse.ui.internal.cheatsheets.data.CheatSheet;
import org.eclipse.ui.internal.cheatsheets.data.CheatSheetParser;
import org.eclipse.ui.internal.cheatsheets.data.CheatSheetSaveHelper;
import org.eclipse.ui.internal.cheatsheets.data.ICheatSheet;
import org.eclipse.ui.internal.cheatsheets.data.IParserTags;
import org.eclipse.ui.internal.cheatsheets.data.ParserInput;
import org.eclipse.ui.internal.cheatsheets.registry.CheatSheetElement;
import org.eclipse.ui.internal.cheatsheets.registry.CheatSheetRegistryReader;
import org.eclipse.ui.internal.cheatsheets.state.DefaultStateManager;
import org.eclipse.ui.internal.cheatsheets.state.ICheatSheetStateManager;
import org.eclipse.ui.internal.cheatsheets.state.NoSaveStateManager;
import org.eclipse.ui.internal.cheatsheets.state.TrayStateManager;
import org.osgi.framework.Bundle;

public class CheatSheetViewer implements ICheatSheetViewer, IMenuContributor {

	//CS Elements
	private CheatSheetElement contentElement;
	private ParserInput parserInput;
	private String currentID;
	private int currentItemNum;
	// Used to indicate if an invalid cheat sheet id was specified via setInput.
	private boolean invalidCheatSheetId = false;
	// Used to indicate if a null cheat sheet id was specified via setInput.
	private boolean nullCheatSheetId = false;

	private CheatSheetParser parser;
	private ICheatSheet model;
	private CheatSheetManager manager;
	private CheatSheetSaveHelper saveHelper;

	private CheatSheetExpandRestoreAction expandRestoreAction;
	private Action copyAction;

	//ITEMS
	private ViewItem currentItem;

	//Lists
	private ArrayList expandRestoreList = new ArrayList();
	private ArrayList viewItemList = new ArrayList();

	//Composites
	protected Composite control;

	private Cursor busyCursor;
	
	// The page currently displayed, may be a CheatSheetPage, CompositeCheatSheetPage
	// or ErrorPage
	private Page currentPage;  
	private Label howToBegin;
	private boolean inDialog;
	private Listener listener;
	
	private ICheatSheetStateManager stateManager; // The state manager to use when saving
	private ICheatSheetStateManager preTrayManager; // The state manager in use before a tray was opened
	private String restorePath;
	
	private int dialogReturnCode;
	private boolean isRestricted;
	
	/**
	 * The constructor.
	 * 
	 * @param inDialog whether or not this viewer will be placed in a modal dialog
	 */
	public CheatSheetViewer(boolean inDialog) {
		currentItemNum = -1;
		this.inDialog = inDialog;
		saveHelper = new CheatSheetSaveHelper();
	}

	public void advanceIntroItem() {
		resetItemState();
		/* LP-item event */
		// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_DEACTIVATED, introItem);

		currentItemNum = 1;
		ViewItem nextItem = getViewItemAtIndex(currentItemNum);
		if (nextItem.item.isDynamic()) {
			nextItem.handleButtons();
		}
		nextItem.setAsCurrentActiveItem();
		/* LP-item event */
		// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_ACTIVATED, nextItem);
		collapseAllButCurrent(false);
		
		saveCurrentSheet();
	}

	/**
	 * Reset the state of all the items in this cheatsheet
	 */
	private void resetItemState() {
		IntroItem introItem = (IntroItem) getViewItemAtIndex(0);
		boolean isStarted = introItem.isCompleted();

		expandRestoreList = new ArrayList();
		if(expandRestoreAction != null)
			expandRestoreAction.setCollapsed(false);

		clearBackgrounds();
		clearIcons();
		collapseAllButtons();
		if(isStarted)
			initManager();

		for (Iterator iter = viewItemList.iterator(); iter.hasNext();) {
			ViewItem item = (ViewItem) iter.next();
			if (item instanceof CoreItem) {
				CoreItem c = (CoreItem) item;
				ArrayList l = c.getListOfSubItemCompositeHolders();
				if (l != null)
					for (int j = 0; j < l.size(); j++) {
						((SubItemCompositeHolder) l.get(j)).setSkipped(false);
						((SubItemCompositeHolder) l.get(j)).setCompleted(false);
					}
			}
		}

		if (isStarted)
			getManager().fireEvent(ICheatSheetEvent.CHEATSHEET_RESTARTED);
		else
			getManager().fireEvent(ICheatSheetEvent.CHEATSHEET_STARTED);

		isStarted = true;
		introItem.setAsNormalCollapsed();
		introItem.setComplete();
		introItem.setRestartImage();
	}

	/*package*/ 
	/*
	 * This function can do one of three things
	 * 1. If this item has a completion message which has not been displayed, display it
	 * 2. Otherwise if this is the final item return to the introduction
	 * 3. If neither condition 1 or 2 is satisfied move to the next item
	 */
	void advanceItem(ImageHyperlink link, boolean markAsCompleted) {
		currentItem = (ViewItem) link.getData();
		int indexNextItem = getIndexOfItem(currentItem) +1;
		boolean isFinalItem = indexNextItem >= viewItemList.size();
		
		if (markAsCompleted 
				&& currentItem.hasCompletionMessage() 
				&& !currentItem.isCompletionMessageExpanded()) {
			currentItem.setCompletionMessageExpanded(isFinalItem);
			currentItem.setComplete();
			if (isFinalItem) {
				getManager().fireEvent(ICheatSheetEvent.CHEATSHEET_COMPLETED);
			}
			saveCurrentSheet();
			return;
		}

		if (indexNextItem < currentItemNum) {
			ViewItem vi = getViewItemAtIndex(currentItemNum);
			vi.setAsNormalNonCollapsed();
		}
		if (currentItem != null) {
			//set that item to it's original color.
			currentItem.setAsNormalCollapsed();
			//set that item as complete.
			if (markAsCompleted) {
				if (!currentItem.isCompleted()) {
				    currentItem.setComplete();
				}
				/* LP-item event */
				// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_COMPLETED, currentItem);
				// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_DEACTIVATED, currentItem);
			} else {
				currentItem.setSkipped();
				/* LP-item event */
				// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_SKIPPED, currentItem);
				// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_DEACTIVATED, currentItem);
			}
		}
		if (!isFinalItem) {
			ViewItem nextItem = getViewItemAtIndex(indexNextItem);
			currentItemNum = indexNextItem;
			if (nextItem != null) {
				//Handle lazy button instantiation here.
				if (nextItem.item.isDynamic()) {
					((CoreItem) nextItem).handleButtons();
				}
				nextItem.setAsCurrentActiveItem();
				/* LP-item event */
				// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_ACTIVATED, nextItem);
				currentItem = nextItem;
			}

			FormToolkit.ensureVisible(currentItem.getMainItemComposite());
		} else if (indexNextItem == viewItemList.size()) {
			if (!currentItem.isCompletionMessageExpanded()) { // The event will already have been fired
			    getManager().fireEvent(ICheatSheetEvent.CHEATSHEET_COMPLETED);
			}
			showIntroItem();
		}

		saveCurrentSheet();
	}

	private void showIntroItem() {
		ViewItem item = getViewItemAtIndex(0);
		item.setAsCurrentActiveItem();
	}

	/*package*/ void advanceSubItem(ImageHyperlink link, boolean markAsCompleted, int subItemIndex) {
		Label l = null;
		ArrayList list = null;
		SubItemCompositeHolder sich = null;
		CoreItem ciws = null;

		currentItem = (ViewItem) link.getData();

		if (currentItem instanceof CoreItem)
			ciws = (CoreItem) currentItem;

		if (ciws != null) {
			list = ciws.getListOfSubItemCompositeHolders();
			sich = (SubItemCompositeHolder) list.get(subItemIndex);
			l = sich.getCheckDoneLabel();
		}

		if (l != null) {
			if (markAsCompleted) {
				sich.setCompleted(true);
				sich.setSkipped(false);
				/* LP-subitem event */
				// fireManagerSubItemEvent(ICheatSheetItemEvent.ITEM_COMPLETED, ciws, subItemID);
			} else {
				sich.setSkipped(true);
				sich.setCompleted(false);
				/* LP-subitem event */
				// fireManagerSubItemEvent(ICheatSheetItemEvent.ITEM_SKIPPED, ciws, subItemID);
			}
			ciws.refreshItem();
		}

		boolean allAttempted = checkAllAttempted(list);
		boolean anySkipped = checkContainsSkipped(list);

		if (allAttempted && !anySkipped) {
			advanceItem(link, true);
			return;
		} else if (allAttempted && anySkipped) {
			advanceItem(link, false);
			return;
		} 
		
		setFocus();
		saveCurrentSheet();
	}

	private boolean checkAllAttempted(ArrayList list) {
		for (int i = 0; i < list.size(); i++) {
			SubItemCompositeHolder s = (SubItemCompositeHolder) list.get(i);
			if (s.isCompleted() || s.isSkipped()) {
				continue;
			}
			return false;
		}
		return true;
	}

	private boolean checkContainsSkipped(ArrayList list) {
		for (int i = 0; i < list.size(); i++) {
			SubItemCompositeHolder s = (SubItemCompositeHolder) list.get(i);
			if (s.isSkipped()) {
				return true;
			}
		}
		return false;
	}

	private boolean loadState() {
		try {
			Properties props = stateManager.getProperties();

			manager = stateManager.getCheatSheetManager();
	
			// There is a bug which causes the background of the buttons to
			// remain white, even though the color is set. So instead of calling
			// clearBackgrounds() only the following line should be needed. D'oh!
			// ((ViewItem) viewItemList.get(0)).setOriginalColor();
			clearBackgrounds();
	
			if (props == null) {
				getViewItemAtIndex(0).setAsCurrentActiveItem();
				/* LP-item event */
				// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_ACTIVATED, items[0]);
				return true;
			}
	
			boolean buttonIsDown = (Integer.parseInt((String) props.get(IParserTags.BUTTON)) == 0) ? false : true;
			int itemNum = Integer.parseInt((String) props.get(IParserTags.CURRENT));
			ArrayList completedStatesList = (ArrayList) props.get(IParserTags.COMPLETED);
			ArrayList expandedStatesList = (ArrayList) props.get(IParserTags.EXPANDED);
			expandRestoreList = (ArrayList) props.get(IParserTags.EXPANDRESTORE);
			String cid = (String) props.get(IParserTags.ID);
			Hashtable completedSubItems = (Hashtable) props.get(IParserTags.SUBITEMCOMPLETED);
			Hashtable skippedSubItems = (Hashtable) props.get(IParserTags.SUBITEMSKIPPED);
	
			ArrayList completedSubItemsItemList = new ArrayList();
			ArrayList skippedSubItemsItemList = new ArrayList();
	
			Enumeration e = completedSubItems.keys();
			while (e.hasMoreElements())
				completedSubItemsItemList.add(e.nextElement());
	
			Enumeration e2 = skippedSubItems.keys();
			while (e2.hasMoreElements())
				skippedSubItemsItemList.add(e2.nextElement());
	
			if (cid != null)
				currentID = cid;
	
			if (itemNum >= 0) {
				currentItemNum = itemNum;
				
				currentItem = getViewItemAtIndex(itemNum);
	
				CheatSheetStopWatch.startStopWatch("CheatSheetViewer.checkSavedState()"); //$NON-NLS-1$
				for (int i = 0; i < viewItemList.size(); i++) {
	
					ViewItem item = getViewItemAtIndex(i);
					if (i > 0 && item.item.isDynamic() && i <= currentItemNum) {
						 item.handleButtons();
						 item.setOriginalColor();
					}
	
					if (completedStatesList.contains(Integer.toString(i))) {
						item.setComplete();
						item.setRestartImage();
					} else {
						if (i < currentItemNum) {
							item.setSkipped();
						}
					}
					if (expandedStatesList.contains(Integer.toString(i))) {
						item.setExpanded();
					} else {
						item.setCollapsed();
					}
					if (i > currentItemNum) {
						item.setButtonsVisible(false);
						item.setCompletionMessageCollapsed();
					} else {
						item.setButtonsVisible(true);
						if (i >currentItemNum || item.isCompleted()) {
						    item.setCompletionMessageExpanded(i + 1 >= viewItemList.size());
					    } else {
							item.setCompletionMessageCollapsed();
					    }
					}
					if (expandRestoreList.contains(Integer.toString(i))) {
						item.setCollapsed();
					}
					if (completedSubItemsItemList.contains(Integer.toString(i))) {
						String subItemNumbers = (String) completedSubItems.get(Integer.toString(i));
						StringTokenizer st = new StringTokenizer(subItemNumbers, ","); //$NON-NLS-1$
						if (item instanceof CoreItem) {
							CoreItem coreitemws = (CoreItem) item;
							ArrayList subItemCompositeHolders = coreitemws.getListOfSubItemCompositeHolders();
		                    if (subItemCompositeHolders != null) {
								while (st.hasMoreTokens()) {
									String token = st.nextToken();
									((SubItemCompositeHolder) subItemCompositeHolders.get(Integer.parseInt(token))).setCompleted(true);
									ArrayList l = subItemCompositeHolders;
									SubItemCompositeHolder s = (SubItemCompositeHolder) l.get(Integer.parseInt(token));
									if (s != null && s.getStartButton() != null) {
										s.getStartButton().setImage(CheatSheetPlugin.getPlugin().getImage(ICheatSheetResource.CHEATSHEET_ITEM_BUTTON_RESTART));
										s.getStartButton().setToolTipText(Messages.RESTART_TASK_TOOLTIP);
									}
		
								}
		                    }
						}
					}
					if (skippedSubItemsItemList.contains(Integer.toString(i))) {
						String subItemNumbers = (String) skippedSubItems.get(Integer.toString(i));
						StringTokenizer st = new StringTokenizer(subItemNumbers, ","); //$NON-NLS-1$
						if (item instanceof CoreItem) {
							CoreItem coreitemws = (CoreItem) item;
							while (st.hasMoreTokens()) {
								String token = st.nextToken();
								((SubItemCompositeHolder) coreitemws.getListOfSubItemCompositeHolders().get(Integer.parseInt(token))).setSkipped(true);
							}
						}
					}
					CheatSheetStopWatch.printLapTime("CheatSheetViewer.checkSavedState()", "Time in CheatSheetViewer.checkSavedState() after loop #"+i+": "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				}
				CheatSheetStopWatch.printLapTime("CheatSheetViewer.checkSavedState()", "Time in CheatSheetViewer.checkSavedState() after loop: "); //$NON-NLS-1$ //$NON-NLS-2$
	
				if (buttonIsDown) {
					if(expandRestoreAction != null)
						expandRestoreAction.setCollapsed(true);
				}
				
				// If the last item is the current one and it is complete then
				// we should collapse the last item and set the focus on intro.
				// For all other cases, set the current item as the active item.
				if(viewItemList.size()-1 == itemNum && currentItem.isCompleted()) {
					currentItem.setCollapsed();
					getViewItemAtIndex(0).getMainItemComposite().setFocus();
					
					// The cheat sheet has been restored but is also completed so fire both events
					getManager().fireEvent(ICheatSheetEvent.CHEATSHEET_RESTORED);
					getManager().fireEvent(ICheatSheetEvent.CHEATSHEET_COMPLETED);
				} else {
					currentItem.setAsCurrentActiveItem();
	
					// If the intro item is completed, than the cheat sheet has been restored.
					if(getViewItemAtIndex(0).isCompleted())
						getManager().fireEvent(ICheatSheetEvent.CHEATSHEET_RESTORED);
				}
	
				/* LP-item event */
				// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_ACTIVATED, currentItem);
			} else {
				getViewItemAtIndex(0).setAsCurrentActiveItem();
				/* LP-item event */
				// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_ACTIVATED, items[0]);
			}
	
			return true;
		} catch(Exception e) {
			// An exception while restoring the saved state data usually only occurs if
			// the cheat sheet has been modified since this previous execution. This most
			// often occurs during development of cheat sheets and as such an end user is
			// not as likely to encounter this.
			
			boolean reset = MessageDialog.openConfirm(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), 
					Messages.CHEATSHEET_STATE_RESTORE_FAIL_TITLE,
					Messages.CHEATSHEET_STATE_RESET_CONFIRM);

			if (reset) {
				restart();
				return true;
			} 
			
			// Log the exception
			String stateFile = saveHelper.getStateFile(currentID).toOSString();
			String message = NLS.bind(Messages.ERROR_APPLYING_STATE_DATA_LOG, (new Object[] {stateFile, currentID}));
			IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, message, e);
			CheatSheetPlugin.getPlugin().getLog().log(status);

			// Set the currentID to null so it is not saved during internalDispose()
			currentID = null;

			internalDispose();

			// Reinitialize a few variables because there is no currentItem or currentPage now
			parserInput = null;
			currentItem = null;
			currentItemNum = -1;
			currentPage = null;
			expandRestoreList = new ArrayList();
			viewItemList = new ArrayList();
			
			// Create the errorpage to show the user
			createErrorPage(Messages.ERROR_APPLYING_STATE_DATA);

			return false;
		}
	}

	private void clearBackgrounds() {
		for (Iterator iter = viewItemList.iterator(); iter.hasNext();) {
			ViewItem item = (ViewItem) iter.next();
			item.setOriginalColor();
		}
	}

	private void clearIcons() {
		for (Iterator iter = viewItemList.iterator(); iter.hasNext();) {
			ViewItem item = (ViewItem) iter.next();
			item.setOriginalColor();
			if (item.isCompleted() || item.isExpanded() || item.isSkipped())
					item.setIncomplete();
		}
	}

	private void collapseAllButCurrent(boolean fromAction) {
		expandRestoreList = new ArrayList();
		try {
			ViewItem current = getViewItemAtIndex(currentItemNum);
			for (ListIterator iter = viewItemList.listIterator(viewItemList.size()); iter.hasPrevious();) {
				ViewItem item = (ViewItem) iter.previous();
				if (item != current && item.isExpanded()) {
					item.setCollapsed();
					if (fromAction)
						expandRestoreList.add(Integer.toString(getIndexOfItem(item)));
				}
			}
		} catch (Exception e) {
		}
	}

	private void collapseAllButtons() {
		for (Iterator iter = viewItemList.listIterator(1); iter.hasNext();) {
			ViewItem item = (ViewItem) iter.next();
			item.setButtonsVisible(false);
			item.setCompletionMessageCollapsed();
		}
	}

	private void createErrorPage(String message) {
		setCollapseExpandButtonEnabled(false);
		if(message != null) {
			currentPage = new ErrorPage(message);
		} else {
			currentPage = new ErrorPage();
		}
		currentPage.createPart(control);
		control.layout(true);
	}
	
	private void showStartPage() {
		setCollapseExpandButtonEnabled(false);
		internalDispose();

		howToBegin = new Label(control, SWT.WRAP);
		howToBegin.setText(Messages.INITIAL_VIEW_DIRECTIONS);
		howToBegin.setLayoutData(new GridData(GridData.FILL_BOTH));
		currentPage = null;
		control.layout(true);
	}
	
	private void createErrorPage(IStatus status) {
		setCollapseExpandButtonEnabled(false);
		currentPage = new ErrorPage(status);
		currentPage.createPart(control);
		control.layout(true);
	}

	/**
	 * Creates the SWT controls for this workbench part.
	 * <p>
	 * Clients should not call this method (the workbench calls this method at
	 * appropriate times).
	 * </p>
	 * <p>
	 * For implementors this is a multi-step process:
	 * <ol>
	 *   <li>Create one or more controls within the parent.</li>
	 *   <li>Set the parent layout as needed.</li>
	 *   <li>Register any global actions with the <code>IActionService</code>.</li>
	 *   <li>Register any popup menus with the <code>IActionService</code>.</li>
	 *   <li>Register a selection provider with the <code>ISelectionService</code>
	 *     (optional). </li>
	 * </ol>
	 * </p>
	 *
	 * @param parent the parent control
	 */
	public void createPartControl(Composite parent) {
		control = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		layout.verticalSpacing = 0;
		layout.horizontalSpacing = 0;
		layout.numColumns = 1;
		control.setLayout(layout);

		control.addDisposeListener(new DisposeListener(){
			public void widgetDisposed(DisposeEvent e) {
				dispose();
			}
		});
		
		showStartPage();

		Display display = parent.getDisplay();

		busyCursor = new Cursor(display, SWT.CURSOR_WAIT);

		if(contentElement != null) {
			initCheatSheetView();
		}
	}

	/**
	 * Called when any TrayDialog is opened. The viewer must react by disabling
	 * itself and moving the cheat sheet to the dialog's tray if the current item
	 * was flagged as one that opens a modal dialog.
	 * 
	 * @param dialog the dialog that was opened
	 */
	private void dialogOpened(final TrayDialog dialog) {
		if (isActive()) {
			HelpTray tray = (HelpTray)dialog.getTray();
			if (tray == null) {
				tray = new HelpTray();
				dialog.openTray(tray);
			}
			ReusableHelpPart helpPart = tray.getHelpPart();
			IHelpPartPage page = helpPart.createPage(CheatSheetHelpPart.ID, null, null);
			page.setVerticalSpacing(0);
			page.setHorizontalMargin(0);
			ICheatSheetStateManager trayManager = new TrayStateManager();
			preTrayManager = stateManager;
			stateManager = trayManager;
			saveCurrentSheet();      // Save the state into the tray manager
			helpPart.addPart(CheatSheetHelpPart.ID, new CheatSheetHelpPart(helpPart.getForm().getForm().getBody(), helpPart.getForm().getToolkit(), page.getToolBarManager(), contentElement, trayManager));
			page.addPart(CheatSheetHelpPart.ID, true);
			helpPart.addPage(page);
			helpPart.showPage(CheatSheetHelpPart.ID);
			
			/*
			 * Disable the viewer until the tray is closed, then show it again.
			 */
			control.setVisible(false);
			Display.getCurrent().removeFilter(SWT.Show, listener);

			helpPart.getControl().addListener(SWT.Dispose, new Listener() {
				public void handleEvent(Event event) {
					control.setVisible(true);
					Display.getCurrent().addFilter(SWT.Show, listener);
					if (preTrayManager != null) {
						loadState();   // Load from the tray manager
						stateManager = preTrayManager;
						preTrayManager = null;
					}
					dialogReturnCode = dialog.getReturnCode();
				}
			});
		}
	}

	/**
	 * Disposes of this cheat sheet viewer.
	 */
	private void dispose() {
		internalDispose();
		if (busyCursor != null)
			busyCursor.dispose();
	}

	/*
	 * Returns the cheat sheet being viewed. 
	 */
	public ICheatSheet getCheatSheet() {
		return model;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.cheatsheets.ICheatSheetViewer#getCheatSheetID()
	 */
	public String getCheatSheetID() {
		if(getContent() != null) {
			return getContent().getID();
		}
		
		return null;
	}

	/**
	 * Returns the current content.
	 *
	 * @return CheatSheetElement
	 */
	/*package*/ CheatSheetElement getContent() {
		return contentElement;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.cheatsheets.ICheatSheetViewer#getControl()
	 */
	public Control getControl() {
		return control;
	}

	private int getIndexOfItem(ViewItem item) {
		int index = viewItemList.indexOf(item);
		if(index != -1) {
			return index;
		}
		return 0;
	}

	/*package*/ CheatSheetManager getManager() {
		if (manager == null) {
			getNewManager();
		}
		return manager;
	}

	private CheatSheetManager getNewManager(){
		manager = new CheatSheetManager(contentElement);
		return manager;
	}
	
	private CheatSheetManager initManager(){
		CheatSheetManager csManager = getManager();
		csManager.setData(new Hashtable());
		return csManager;
	}

	private ViewItem getViewItemAtIndex(int index) {
		if (viewItemList != null && !viewItemList.isEmpty()) {
			return (ViewItem) viewItemList.get(index);
		}
		return null;
	}
	
	/**
	 * Returns whether or not this viewer contains the given Control, which
	 * is currently in focus.
	 * 
	 * @param control the Control currently in focus
	 * @return whether this viewer contains the given Control or not
	 */
	public boolean hasFocusControl(Control control) {
		return (control == this.control) || (currentPage.getControl() == control);
	}
	
	/**
	 * If in a dialog-opening step, will add the appropriate listener for
	 * the cheatsheet to jump into the dialog's tray once opened.
	 * 
	 * Should be called before executing any action.
	 */
	private void hookDialogListener() {
		/*
		 * org.eclipse.help.ui is an optional dependency; only perform this
		 * step is this plugin is present.
		 */
		if (!inDialog && isInDialogItem() && (Platform.getBundle("org.eclipse.help.ui") != null)) { //$NON-NLS-1$
			listener = new Listener() {
				public void handleEvent(Event event) {
					if (isTrayDialog(event.widget)) {
						dialogOpened((TrayDialog)((Shell)event.widget).getData());
					}
				}
			};
			Display.getCurrent().addFilter(SWT.Show, listener);
		}
	}
	
	/**
	 * Removes the dialog-opening listener, if it was added.
	 * 
	 * Should be called after executing any action.
	 */
	private void unhookDialogListener() {
		if (listener != null) {
			Display.getCurrent().removeFilter(SWT.Show, listener);
		}
	}
	
	/*
	 * return true if a cheat sheet was opened successfully
	 */
	private boolean initCheatSheetView() {
		CheatSheetStopWatch.startStopWatch("CheatSheetViewer.initCheatSheetView()"); //$NON-NLS-1$
		//Re-initialize list to store items collapsed by expand/restore action on c.s. toolbar.
		expandRestoreList = new ArrayList();

		// re set that action to turned off.
		if(expandRestoreAction != null)
			expandRestoreAction.setCollapsed(false);

		//reset current item to be null; next item too.
		currentItem = null;
		currentItemNum = 0;
		viewItemList = new ArrayList();

		// Reset the page variable
		currentPage = null;
		
		if(howToBegin != null) {
			howToBegin.dispose();
			howToBegin = null;
		}
		
		// If a null cheat sheet id was specified, return leaving the cheat sheet empty.
		if(nullCheatSheetId) {
			return false;
		}
		
		if(invalidCheatSheetId) {
			createErrorPage(Messages.ERROR_CHEATSHEET_DOESNOT_EXIST);
			return false;
		}
		
		// read our contents, if there are problems reading the file an error page should be created.
		CheatSheetStopWatch.printLapTime("CheatSheetViewer.initCheatSheetView()", "Time in CheatSheetViewer.initCheatSheetView() before readFile() call: "); //$NON-NLS-1$ //$NON-NLS-2$
		IStatus parseStatus = readFile();
		CheatSheetStopWatch.printLapTime("CheatSheetViewer.initCheatSheetView()", "Time in CheatSheetViewer.initCheatSheetView() after readFile() call: "); //$NON-NLS-1$ //$NON-NLS-2$
		if (!parseStatus.isOK()) {
			CheatSheetPlugin.getPlugin().getLog().log(parseStatus);
		}
		if(parseStatus.getSeverity() == Status.ERROR){

			// Error during parsing.
			// Something is wrong with the Cheat sheet content file at the xml level.

			createErrorPage(parseStatus);
			return false;
		}
		
		control.setRedraw(false);
		if (model instanceof CheatSheet) {	
		    CheatSheet cheatSheetModel = (CheatSheet)model;

		    if (isRestricted && cheatSheetModel.isContainsCommandOrAction()) {
		    	boolean isOK = MessageDialog.openConfirm(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), 
						Messages.CHEATSHEET_FROM_URL_WITH_EXEC_TITLE,
						Messages.CHEATSHEET_FROM_URL_WITH_EXEC);

				if (!isOK) {
					control.setRedraw(true);
					showStartPage();
					return true;
				} 
		    }
		    
			currentPage = new CheatSheetPage(cheatSheetModel, viewItemList, this);
		    setCollapseExpandButtonEnabled(true);
		} else if (model instanceof CompositeCheatSheetModel) {
			CompositeCheatSheetModel compositeCheatSheetModel = ((CompositeCheatSheetModel)model);
			compositeCheatSheetModel.setId(currentID);
			currentPage = new CompositeCheatSheetPage(compositeCheatSheetModel, stateManager);
			compositeCheatSheetModel.setCheatSheetManager(initManager());
			setCollapseExpandButtonEnabled(false);
	    }
	    CheatSheetStopWatch.printLapTime("CheatSheetViewer.initCheatSheetView()", "Time in CheatSheetViewer.initCheatSheetView() after CheatSheetPage() call: "); //$NON-NLS-1$ //$NON-NLS-2$
	    currentPage.createPart(control);
	    CheatSheetStopWatch.printLapTime("CheatSheetViewer.initCheatSheetView()", "Time in CheatSheetViewer.initCheatSheetView() after CheatSheetPage.createPart() call: "); //$NON-NLS-1$ //$NON-NLS-2$

	    if (model instanceof CheatSheet) {	
			CheatSheetStopWatch.printLapTime("CheatSheetViewer.initCheatSheetView()", "Time in CheatSheetViewer.initCheatSheetView() after fireEvent() call: "); //$NON-NLS-1$ //$NON-NLS-2$
	
			if(!loadState()) {
				// An error occurred when apply the saved state data.
				control.setRedraw(true);
				control.layout();
				return true;
			}

			getManager().fireEvent(ICheatSheetEvent.CHEATSHEET_OPENED);
	    }
		CheatSheetStopWatch.printLapTime("CheatSheetViewer.initCheatSheetView()", "Time in CheatSheetViewer.initCheatSheetView() after checkSavedState() call: "); //$NON-NLS-1$ //$NON-NLS-2$

		currentPage.initialized();
		control.setRedraw(true);
		control.layout();
		CheatSheetStopWatch.printLapTime("CheatSheetViewer.initCheatSheetView()", "Time in CheatSheetViewer.initCheatSheetView() after layout() call: "); //$NON-NLS-1$ //$NON-NLS-2$

		if (currentItem != null && !currentItem.isCompleted())
			currentItem.setFocus();
		CheatSheetStopWatch.printLapTime("CheatSheetViewer.initCheatSheetView()", "Time in CheatSheetViewer.initCheatSheetView() at end of method: "); //$NON-NLS-1$ //$NON-NLS-2$
	    return true;
	}

	private void internalDispose() {
		if(manager != null)
			manager.fireEvent(ICheatSheetEvent.CHEATSHEET_CLOSED);
       
		saveCurrentSheet();

		for (Iterator iter = viewItemList.iterator(); iter.hasNext();) {
			ViewItem item = (ViewItem) iter.next();
			item.dispose();
		}

		if(currentPage != null) {
			currentPage.dispose();
		}
		manager = null;
	}

	/**
	 * Returns whether or not the cheat sheet viewer is currently active. This
	 * means it is visible to the user and enabled.
	 * 
	 * @return whether or not this viewer is active
	 */
	private boolean isActive() {
		Control control = getControl();
		if (control != null && !control.isDisposed()) {
			Control parent = control.getParent();
			return (parent != null && !parent.isDisposed() && parent.isVisible() && parent.isEnabled());
		}
		return false;
	}
	
	/*
	 * Show the collapse/expand button if we have access to the toolbar
	 */
	private void setCollapseExpandButtonEnabled(boolean enable) {
		if (expandRestoreAction != null) {
			expandRestoreAction.setEnabled(enable);
		}
	}

	/**
	 * Returns whether or not the currently active item requires opening a
	 * modal dialog.
	 * 
	 * @return whether the current item opens a modal dialog
	 */
	private boolean isInDialogItem() {
		ViewItem item = getViewItemAtIndex(currentItemNum);
		if (item != null) {
			return item.getItem().isDialog();
		}
		return false;
	}
	
	/**
	 * Returns whether or not this cheat sheet viewer is inside a modal
	 * dialog.
	 * 
	 * @return whether this viewer is inside a modal dialog
	 */
	public boolean isInDialogMode() {
		return inDialog;
	}
	
	/**
	 * Returns whether the given widget is a TrayDialog.
	 * 
	 * @param widget the widget to check
	 * @return whether or not the widget is a TrayDialog
	 */
	private boolean isTrayDialog(Widget widget) {
		return (widget instanceof Shell && ((Shell)widget).getData() instanceof TrayDialog);
	}

	/**
	* Read the contents of the cheat sheet file
	* @return true if the file was read and parsed without error
	*/
	private IStatus readFile() {
		if(parser == null)
			parser = new CheatSheetParser();
		// If the cheat sheet was registered then
		// search for a specific type - composite or simple
		int cheatSheetKind = CheatSheetParser.ANY;
		if (contentElement.isRegistered()) { 
			if (contentElement.isComposite()) {
				cheatSheetKind = CheatSheetParser.COMPOSITE_ONLY;
			} else {
				cheatSheetKind = CheatSheetParser.SIMPLE_ONLY;
			}
		}
	
		model = parser.parse(parserInput, cheatSheetKind);
		return parser.getStatus();
	}

	private void restoreExpandStates() {
		try {
			for (int i = 0; i < expandRestoreList.size(); i++) {
				int index = Integer.parseInt(((String) expandRestoreList.get(i)));
				ViewItem item = getViewItemAtIndex(index);
				if (!item.isExpanded()) {
					item.setExpanded();
				}
			}
			expandRestoreList = null;
		} catch (Exception e) {
		}
	}
	
	/*package*/ void runPerformExecutable(ImageHyperlink link) {
		link.setCursor(busyCursor);
		currentItem = (ViewItem) link.getData();
		CoreItem coreItem = (CoreItem) currentItem;

		if (coreItem != null) {
			try {
				hookDialogListener();
				dialogReturnCode = -1;
				IStatus status = coreItem.runExecutable(getManager());
				if (status.isOK() && dialogReturnCode != Window.CANCEL) {
					coreItem.setRestartImage();
					if (!coreItem.hasConfirm()) {
					    //set that item as complete.
					    advanceItem(link, true);
					    saveCurrentSheet();
					}
				}
				if ( status.getSeverity() == IStatus.ERROR) {
					CheatSheetPlugin.getPlugin().getLog().log(status);
				    org.eclipse.jface.dialogs.ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), null, null, status);								
				}
			}
			finally {
				unhookDialogListener();
			}
		}

		link.setCursor(null);
	}

	/*package*/ void runSubItemPerformExecutable(ImageHyperlink link, int subItemIndex) {
		CoreItem coreItem = null;
		link.setCursor(busyCursor);
		currentItem = (ViewItem) link.getData();
		coreItem = (CoreItem) currentItem;

		try {
			if (coreItem != null) {
				hookDialogListener();
				if (coreItem.runSubItemExecutable(getManager(), subItemIndex) == ViewItem.VIEWITEM_ADVANCE && !coreItem.hasConfirm(subItemIndex)) {
					ArrayList l = coreItem.getListOfSubItemCompositeHolders();
					SubItemCompositeHolder s = (SubItemCompositeHolder) l.get(subItemIndex);
					s.getStartButton().setImage(CheatSheetPlugin.getPlugin().getImage(ICheatSheetResource.CHEATSHEET_ITEM_BUTTON_RESTART));
					s.getStartButton().setToolTipText(Messages.RESTART_TASK_TOOLTIP);
					advanceSubItem(link, true, subItemIndex);
					saveCurrentSheet();
				}
			}
		} catch (RuntimeException e) {
			IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, Messages.ERROR_RUNNING_ACTION, e);
			CheatSheetPlugin.getPlugin().getLog().log(status);
			org.eclipse.jface.dialogs.ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), null, null, status);
		} finally {
			unhookDialogListener();
			link.setCursor(null);
		}
	}

	/*package*/ void saveCurrentSheet() {
		if(currentID != null) {
			if (currentPage instanceof CheatSheetPage) {
				Properties properties = saveHelper.createProperties(currentItemNum, viewItemList, getExpandRestoreActionState(), expandRestoreList, currentID, restorePath);
			    IStatus status = stateManager.saveState(properties, getManager());
			    if (!status.isOK()) {
			    	CheatSheetPlugin.getPlugin().getLog().log(status);
			    }
			} else if (currentPage instanceof CompositeCheatSheetPage) {
				((CompositeCheatSheetPage)currentPage).saveState();
			}
		}
	}
	
	private boolean getExpandRestoreActionState() {
		boolean expandRestoreActionState = false;
		if(expandRestoreAction != null)
			expandRestoreActionState = expandRestoreAction.isCollapsed();
		return expandRestoreActionState;	
	}

	/*package*/ void setContent(CheatSheetElement element, ICheatSheetStateManager inputStateManager) {
		CheatSheetStopWatch.startStopWatch("CheatSheetViewer.setContent(CheatSheetElement element)"); //$NON-NLS-1$
		
		// Cleanup previous contents
		internalDispose();

		// Set the current content to new content
		contentElement = element;
		stateManager = inputStateManager;	
		stateManager.setElement(element);

		currentID = null;
		parserInput = null;
		if (element != null) {
			initInputFields(element);
		}

		CheatSheetStopWatch.printLapTime("CheatSheetViewer.setContent(CheatSheetElement element)", "Time in CheatSheetViewer.setContent() before initCheatSheetView() call: "); //$NON-NLS-1$ //$NON-NLS-2$
		// Initialize the view with the new contents
		boolean cheatSheetOpened = false;
		if (control != null) {
			cheatSheetOpened = initCheatSheetView();
		}
		if (!cheatSheetOpened) {
			contentElement = null;
			stateManager = null;
		}
		// If the cheat sheet failed to open clear the content element so we don't see an 
		CheatSheetStopWatch.printLapTime("CheatSheetViewer.setContent(CheatSheetElement element)", "Time in CheatSheetViewer.setContent() after initCheatSheetView() call: "); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private void initInputFields(CheatSheetElement element) {
		currentID = element.getID();
		String contentXml = element.getContentXml();
		URL contentURL = null;
		restorePath = element.getRestorePath();
		
		if (contentXml != null) {
			parserInput = new ParserInput(contentXml, element.getHref());
			return;		
		}

		// The input was not an XML string, find the content URL
		Bundle bundle = null;
		if(element != null && element.getConfigurationElement() != null)
			try{
				String pluginId = element.getConfigurationElement().getContributor().getName();
				bundle = Platform.getBundle(pluginId);
			} catch (Exception e) {
				// do nothing
			}
		if (bundle != null) {
			contentURL = FileLocator.find(bundle, new Path(element.getContentFile()), null);
		}

		if (contentURL == null) {
			try {
				contentURL = new URL(element.getHref());
			} catch (MalformedURLException mue) {
			}
		}
		parserInput = new ParserInput(contentURL, bundle != null ? bundle.getSymbolicName() : null);
	}
	
	
	/*package*/ void setExpandRestoreAction(CheatSheetExpandRestoreAction action) {
		expandRestoreAction = action;
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		//need this to have current item selected. (Assumes that when you reactivate the view you will work with current item.)
		if (currentItem != null) {
			currentItem.setFocus();
		} else {
			getControl().setFocus();
		}
	}
	

	/* (non-Javadoc)
	 * @see org.eclipse.ui.cheatsheets.ICheatSheetViewer#setInput(java.lang.String)
	 */
	public void setInput(String id) {
		setInput(id, new DefaultStateManager());
	}

	public void setInput(String id, ICheatSheetStateManager inputStateManager) {
		CheatSheetStopWatch.startStopWatch("CheatSheetViewer.setInput(String id)"); //$NON-NLS-1$

		CheatSheetElement element = null;

		if(id == null) {
			nullCheatSheetId = true;
		} else {
			nullCheatSheetId = false;

			element = CheatSheetRegistryReader.getInstance().findCheatSheet(id);
			if(element == null) {
				String message = NLS.bind(Messages.ERROR_INVALID_CHEATSHEET_ID, (new Object[] {id}));
				IStatus status = new Status(IStatus.ERROR, ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK, message, null);
				CheatSheetPlugin.getPlugin().getLog().log(status);
				invalidCheatSheetId = true;
			} else {
				invalidCheatSheetId = false;
				this.isRestricted = false;
			}
		}

		CheatSheetStopWatch.printLapTime("CheatSheetViewer.setInput(String id)", "Time in CheatSheetViewer.setInput(String id) before setContent() call: "); //$NON-NLS-1$ //$NON-NLS-2$
		setContent(element, inputStateManager);
		CheatSheetStopWatch.printLapTime("CheatSheetViewer.setInput(String id)", "Time in CheatSheetViewer.setInput(String id) after setContent() call: "); //$NON-NLS-1$ //$NON-NLS-2$

		// Update most recently used cheat sheets list.
		CheatSheetPlugin.getPlugin().getCheatSheetHistory().add(element);
		CheatSheetStopWatch.printLapTime("CheatSheetViewer.setInput(String id)", "Time in CheatSheetViewer.setInput(String id) after getCheatSheetHistory() call: "); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.cheatsheets.ICheatSheetViewer#setInput(java.lang.String, java.lang.String, java.net.URL)
	 */
	public void setInput(String id, String name, URL url) {
		setInput(id, name, url, new DefaultStateManager(), false);
	}
	
	public void setInputFromXml(String id, String name, String xml, String basePath) {
		if (id == null || name == null || xml == null) {
			throw new IllegalArgumentException();
		}
		CheatSheetElement element = new CheatSheetElement(name);
		element.setID(id);
		element.setContentXml(xml);
		element.setHref(basePath);

		nullCheatSheetId = false;
		invalidCheatSheetId = false;
		isRestricted = false;
		setContent(element, new NoSaveStateManager());
	}

	public void setInput(String id, String name, URL url, 
			ICheatSheetStateManager inputStateManager, boolean isRestricted) {
		if (id == null || name == null || url == null) {
			throw new IllegalArgumentException();
		}
		CheatSheetElement element = new CheatSheetElement(name);
		element.setID(id);
		element.setHref(url.toString());

		nullCheatSheetId = false;
		invalidCheatSheetId = false;
		this.isRestricted = isRestricted;
		setContent(element, inputStateManager);
	}
	
    /*package*/ void toggleExpandRestore() {
		if(expandRestoreAction == null)
			return;

		if (expandRestoreAction.isCollapsed()) {
			restoreExpandStates();
			expandRestoreAction.setCollapsed(false);
		} else {
			collapseAllButCurrent(true);
			expandRestoreAction.setCollapsed(true);
		}

	}

	public Action getCopyAction() {
		return copyAction;
	}

	public void setCopyAction(Action copyAction) {
		this.copyAction = copyAction;
	}
	
	public void copy() {
		if (currentItem!=null)
			currentItem.copy();
	}

	public void addListener(CheatSheetListener listener) {
		if (contentElement != null ) {
			getManager().addListener(listener);		
		}
	}

	public int contributeToViewMenu(Menu menu, int index) {
		if (currentPage instanceof IMenuContributor) {
			return ((IMenuContributor)currentPage).contributeToViewMenu(menu, index);
		}
		return index;
	}
	
	public void restart() {
		resetItemState();
		currentItemNum = 0;
		collapseAllButCurrent(false);
		IntroItem introItem = (IntroItem) getViewItemAtIndex(0);
		introItem.setIncomplete();
		showIntroItem();		
	}

	public void saveState(IMemento memento) {
		if (currentPage instanceof CheatSheetPage) {
			Properties properties = saveHelper.createProperties(currentItemNum, viewItemList, getExpandRestoreActionState(), expandRestoreList, currentID, restorePath);
		    saveHelper.saveToMemento(properties, getManager(), memento);
		}
	}

	public void reset(Map cheatSheetData) {
		if (currentPage instanceof CheatSheetPage) {
			restart();
			getManager().setData(cheatSheetData);
		} else if (currentPage instanceof CompositeCheatSheetPage) {
			((CompositeCheatSheetPage)currentPage).restart(cheatSheetData);
		}		
	}
	
	public void showError(String message) {
		internalDispose();
		if(howToBegin != null) {
			howToBegin.dispose();
			howToBegin = null;
		}
		createErrorPage(message);	
	}

}