/***************************************************************************************************
 * Copyright (c) 2003, 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.wst.common.frameworks.internal.ui;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.Vector;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelPausibleOperation;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelPausibleOperationEvent;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelPausibleOperationListener;
import org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelWizard;
import org.eclipse.wst.common.frameworks.internal.datamodel.ui.IDMPageGroup;
import org.eclipse.wst.common.frameworks.internal.datamodel.ui.IDMPageGroupHandler;
import org.eclipse.wst.common.frameworks.internal.datamodel.ui.IDMPageHandler;
import org.eclipse.wst.common.frameworks.internal.operation.extensionui.CommonUIPluginConstants;

public class PageGroupManager {
	private IDataModelPausibleOperation rootOperation;
	private IDMPageGroup rootPageGroup;
	private HashMap groupTable;
	private HashSet operationsRun;
	private Stack pageGroupStack;
	private IDataModel dataModel;
	private StackEntry savedTopEntry;
	private int savedStackSize;

	private IConfigurationElement[] elements;

	private final String ELEMENT_PAGE_GROUP = "wizardPageGroup"; //$NON-NLS-1$

	private String pauseAfterExecution = null;

	public PageGroupManager(IDataModelPausibleOperation rootOperation, IDMPageGroup rootPageGroup) {
		this.rootOperation = rootOperation;
		dataModel = rootOperation.getDataModel();
		groupTable = new HashMap();
		operationsRun = new HashSet();
		pageGroupStack = new Stack();
		this.rootPageGroup = rootPageGroup;


		PageGroupEntry rootPageGroupEntry = new PageGroupEntry(rootPageGroup);
		IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CommonUIPluginConstants.PLUGIN_ID, ELEMENT_PAGE_GROUP);
		elements = point.getConfigurationElements();
		groupTable.put(this.rootPageGroup.getPageGroupID(), rootPageGroupEntry);

		if (this.rootPageGroup.getAllowsExtendedPages()) {
			// Find all the page groups that follow this root page group.
			loadExtendedPages(rootPageGroup);
		}

		rootOperation.addOperationListener(new IDataModelPausibleOperationListener() {
			public int notify(IDataModelPausibleOperationEvent event) {
				switch (event.getExecutionType()) {
					case IDataModelPausibleOperationEvent.ROLLBACK :
						if (event.getOperationType() == IDataModelPausibleOperationEvent.MAIN_FINISHED) {
							operationsRun.remove(event.getOperation().getID());
						}
						break;
					case IDataModelPausibleOperationEvent.EXECUTE :
						if (event.getOperationType() == IDataModelPausibleOperationEvent.MAIN_FINISHED) {
							operationsRun.add(event.getOperation().getID());
							if (null != pauseAfterExecution && event.getOperation().getID().equals(pauseAfterExecution)) {
								return IDataModelPausibleOperationListener.PAUSE;
							}
						}
						
						break;

				}
				return IDataModelPausibleOperationListener.CONTINUE;
			}
		});

	}

	public void addGroupAfter(String pageGroupID, IDMPageGroup pageInsertGroup) {
		PageGroupEntry pageGroupEntry = (PageGroupEntry) groupTable.get(pageGroupID);

		if (pageGroupEntry.pageGroup.getAllowsExtendedPages()) {
			addPageGroup(pageGroupEntry.pageGroup, pageInsertGroup);
		}
	}

	public void moveForwardOnePage() {
		boolean pageFound = false;

		if (pageGroupStack.empty()) {
			PageGroupEntry rootEntry = (PageGroupEntry) groupTable.get(rootPageGroup.getPageGroupID());
			pageGroupStack.push(new StackEntry(rootEntry, -1));
		}

		saveStackInfo();

		try {
			pageFound = findNextPage(true);
		} catch (Throwable exc) {
			Logger.getLogger().logError(exc);
			try {
				rootOperation.rollBack(null, null);
			} catch (ExecutionException e) {
				Logger.getLogger().logError(e);
			}
			pageFound = false;
		}

		if (pageFound == false) {
			// If we moved forward and there wasn't a page then we will restore the stack.
			// Normally, this wouldn't happen since a call to hasNextPage would have indicated
			// that there wasn't a page.
			restoreStackInfo();
		}
	}

	public void moveBackOnePage() {
		if (pageGroupStack.empty())
			return;

		StackEntry topEntry = (StackEntry) pageGroupStack.peek();

		// Pop the last page.
		if (!topEntry.pagesReturned.empty())
			topEntry.pagesReturned.pop();

		// Now find the previous page.
		boolean foundPreviousPage = findPreviousPageInGroup();

		while (!foundPreviousPage && !pageGroupStack.empty()) {
			if (topEntry.ranOperations) {
				try {
					rootOperation.rollBack(null, null);
				} catch (ExecutionException e) {
					Logger.getLogger().logError(e);
				}
			}

			pageGroupStack.pop();

			if (!pageGroupStack.empty()) {
				foundPreviousPage = findPreviousPageInGroup();
				topEntry = (StackEntry) pageGroupStack.peek();
			}
		}
	}

	public void reset() {
		pageGroupStack.clear();
	}

	public IWizardPage getCurrentPage() {
		IWizardPage page = null;

		if (!pageGroupStack.empty()) {
			StackEntry topEntry = (StackEntry) pageGroupStack.peek();
			int pageIndex = topEntry.getTopPageIndex();

			page = pageIndex == -1 ? null : (IWizardPage) topEntry.pageGroupEntry.getPages().get(pageIndex);
		}

		return page;
	}

	private Boolean hasMulitplePages;

	public boolean hasMultiplePages() {
		if (null == hasMulitplePages) {
			int pageCount = 0;
			PageGroupEntry rootEntry = (PageGroupEntry) groupTable.get(rootPageGroup.getPageGroupID());
			pageCount += rootEntry.getPages().size();
			for (int i = 0; pageCount < 2 && i < rootEntry.groupsThatFollow.size(); i++) {
				pageCount += ((PageGroupEntry) rootEntry.groupsThatFollow.get(i)).getPages().size();
			}
			hasMulitplePages = pageCount > 1 ? Boolean.TRUE : Boolean.FALSE;
		}
		return hasMulitplePages.booleanValue();
	}

	public boolean hasNextPage() {
		boolean pageFound = false;

		saveStackInfo();

		if (pageGroupStack.empty()) {
			PageGroupEntry rootEntry = (PageGroupEntry) groupTable.get(rootPageGroup.getPageGroupID());
			pageGroupStack.push(new StackEntry(rootEntry, -1));
		}

		pageFound = findNextPage(false);
		restoreStackInfo();

		return pageFound;
	}

	public void undoAllCurrentOperations() {
		while (!pageGroupStack.empty()) {
			moveBackOnePage();
		}
	}

	private boolean findPreviousPageInGroup() {
		StackEntry topEntry = (StackEntry) pageGroupStack.peek();
		boolean pageFound = false;

		if (!topEntry.pagesReturned.empty()) {
			topEntry.pagesComplete = false;
			pageFound = true;
		}

		return pageFound;
	}

	private boolean findNextPage(boolean runOperations) {
		StackEntry topEntry = (StackEntry) pageGroupStack.peek();
		int newPageIndex = topEntry.findNextPageIndex();
		boolean pageFound = false;

		if (newPageIndex == -1) {
			// Our page handler didn't find a page so we will see if there is a page group that
			// follows this page group that can find a page.
			topEntry.pagesComplete = true;

			StackEntry nextStackEntry = findNextPageGroup(pageGroupStack);

			if (nextStackEntry != null) {
				IDMPageGroup pageGroup = nextStackEntry.pageGroupEntry.pageGroup;
				String requiresOperationsId = pageGroup.getRequiredDataOperationToRun();

				// If this group requires an operation and it has not already been run
				// then we need to run it.
				if (runOperations && requiresOperationsId != null && !operationsRun.contains(requiresOperationsId)) {
					pauseAfterExecution = requiresOperationsId;
					IStatus status = null; 
					
					try {
						status = rootOperation.resume(null, null);
					} catch (ExecutionException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

					nextStackEntry.ranOperations = true;
					if (status.getSeverity() == IStatus.ERROR) {
						// TODO need a better error feedback mechanism here.
						throw new IllegalArgumentException(status.getMessage());
					}
				}

				pageGroupStack.push(nextStackEntry);
				pageFound = findNextPage(runOperations);
			}
		} else {
			// We found a new page in the page handler.
			pageFound = true;
			topEntry.pagesReturned.push(new Integer(newPageIndex));
		}

		return pageFound;
	}



	private void saveStackInfo() {
		if (!pageGroupStack.empty()) {
			savedTopEntry = new StackEntry((StackEntry) pageGroupStack.peek());
		}

		savedStackSize = pageGroupStack.size();
	}

	private void restoreStackInfo() {
		if (savedStackSize == 0) {
			pageGroupStack.removeAllElements();
		} else {
			pageGroupStack.setSize(savedStackSize - 1);
			pageGroupStack.push(savedTopEntry);
		}
	}

	private void loadExtendedPages(IDMPageGroup pageGroup) {
		String wizardId = rootPageGroup.getWizardID();
		String pageGroupId = pageGroup.getPageGroupID();
		int length = elements.length;

		for (int index = 0; index < length; index++) {
			DMPageGroupElementImpl pageInsertGroup = new DMPageGroupElementImpl(elements[index]);
			String pageInsertGroupId = pageInsertGroup.getPageGroupInsertionID();
			if (pageInsertGroup.getWizardID().equals(wizardId) && (null == pageInsertGroupId || pageInsertGroupId.equals(pageGroupId))) {
				addPageGroup(pageGroup, pageInsertGroup);

				// If this page group has page then add them
				if (pageInsertGroup.getAllowsExtendedPages()) {
					loadExtendedPages(pageInsertGroup);
				}
			}
		}
	}

	private void addPageGroup(IDMPageGroup pageGroup, IDMPageGroup insertedPageGroup) {
		PageGroupEntry pageGroupEntry = (PageGroupEntry) groupTable.get(pageGroup.getPageGroupID());
		PageGroupEntry nextGroupEntry = (PageGroupEntry) groupTable.get(insertedPageGroup.getPageGroupID());

		if (pageGroupEntry == null) {
			pageGroupEntry = new PageGroupEntry(pageGroup);
			groupTable.put(pageGroup.getPageGroupID(), pageGroupEntry);
		}

		if (nextGroupEntry == null) {
			nextGroupEntry = new PageGroupEntry(insertedPageGroup);
			groupTable.put(insertedPageGroup.getPageGroupID(), nextGroupEntry);
		}

		pageGroupEntry.groupsThatFollow.add(nextGroupEntry);
	}

	public StackEntry findNextPageGroup(Stack stack) {
		StackEntry topEntry = (StackEntry) stack.peek();
		PageGroupEntry nextPageGroup = topEntry.getNextPageGroup(null);
		int parentIndex = topEntry.parentGroupIndex;
		int prevParentIndex = stack.size() - 1;

		// Recurse up through the parents to find the next group if needed.
		while (parentIndex != -1 && nextPageGroup == null) {
			StackEntry parentStackEntry = (StackEntry) stack.elementAt(parentIndex);

			nextPageGroup = parentStackEntry.getNextPageGroup(topEntry.getId());
			prevParentIndex = parentIndex;
			parentIndex = parentStackEntry.parentGroupIndex;
			topEntry = parentStackEntry;
		}

		return nextPageGroup == null ? null : new StackEntry(nextPageGroup, prevParentIndex);
	}

	private class StackEntry {
		public PageGroupEntry pageGroupEntry;
		public Stack pagesReturned; // Element = Interger of page indexes.
		public boolean pagesComplete;
		public int parentGroupIndex;
		public boolean ranOperations;

		public StackEntry(PageGroupEntry newPageGroupEntry, int parentIndex) {
			pageGroupEntry = newPageGroupEntry;
			pagesReturned = new Stack();
			pagesComplete = false;
			parentGroupIndex = parentIndex;
			ranOperations = false;
		}

		public StackEntry(StackEntry stackEntry) {
			pageGroupEntry = stackEntry.pageGroupEntry;
			pagesReturned = new Stack();
			pagesComplete = stackEntry.pagesComplete;
			parentGroupIndex = stackEntry.parentGroupIndex;
			ranOperations = stackEntry.ranOperations;
			pagesReturned.addAll(stackEntry.pagesReturned);
		}

		public String getId() {
			return pageGroupEntry.pageGroup.getPageGroupID();
		}

		public int findNextPageIndex() {
			int result = -1;

			if (!pagesComplete) {
				List pages = pageGroupEntry.getPages();

				int pageIndex = getTopPageIndex();
				String pageId = pageIndex == -1 ? null : ((IWizardPage) pages.get(pageIndex)).getName();
				String expectedId = pageIndex + 1 >= pages.size() ? null : ((IWizardPage) pages.get(pageIndex + 1)).getName();
				String newPageId = null;

				try {
					newPageId = pageGroupEntry.getPageHandler().getNextPage(pageId, expectedId);
				} catch (Throwable exc) {
					Logger.getLogger().logError(exc);
				}

				if (newPageId != null && newPageId.equals(IDMPageHandler.SKIP_PAGE) && pageIndex >= 0 && pageIndex < pages.size() - 2) {
					result = pageIndex + 2;
				} else {
					result = pageGroupEntry.checkForSpecialIds(newPageId);
				}
			}

			return result;
		}

		public PageGroupEntry getNextPageGroup(String afterId) {
			PageGroupEntry result = null;
			String nextGroupID = null;
			String[] groupIDList = getGroupIDList();

			try {
				nextGroupID = pageGroupEntry.getPageGroupHandler().getNextPageGroup(afterId, groupIDList);
			} catch (Throwable exc) {
				Logger.getLogger().logError(exc);
			}

			if (nextGroupID != null) {
				// Find this string in the list.
				for (int index = 0; index < groupIDList.length; index++) {
					if (groupIDList[index].equals(nextGroupID)) {
						result = (PageGroupEntry) pageGroupEntry.groupsThatFollow.elementAt(index);
						break;
					}
				}
			}

			return result;
		}

		private String[] getGroupIDList() {
			String[] result = new String[pageGroupEntry.groupsThatFollow.size()];

			for (int index = 0; index < pageGroupEntry.groupsThatFollow.size(); index++) {
				PageGroupEntry entry = (PageGroupEntry) pageGroupEntry.groupsThatFollow.elementAt(index);

				result[index] = entry.pageGroup.getPageGroupID();
			}

			return result;
		}

		private int getTopPageIndex() {
			return pagesReturned.empty() ? -1 : ((Integer) pagesReturned.peek()).intValue();
		}
	}

	private class PageGroupEntry {
		public IDMPageGroup pageGroup;
		public Vector groupsThatFollow;
		private IDMPageHandler pageHandler;
		private IDMPageGroupHandler pageGroupHandler;
		private boolean initialized;

		public PageGroupEntry(IDMPageGroup newPageGroup) {
			pageGroup = newPageGroup;
			groupsThatFollow = new Vector();
			initialized = false;
		}

		public IDMPageHandler getPageHandler() {
			if (!initialized)
				init();

			return pageHandler;
		}

		public IDMPageGroupHandler getPageGroupHandler() {
			if (!initialized)
				init();

			return pageGroupHandler;
		}

		public List getPages() {
			if (!initialized)
				init();

			return pageGroup.getPages(dataModel);
		}

		public PageGroupEntry(PageGroupEntry originalEntry) {
			pageGroup = originalEntry.pageGroup;
			groupsThatFollow = originalEntry.groupsThatFollow;
			pageHandler = originalEntry.pageHandler;
			pageGroupHandler = originalEntry.pageGroupHandler;
		}

		private void init() {
			try {
				pageHandler = pageGroup.getPageHandler(dataModel);
				pageGroupHandler = pageGroup.getPageGroupHandler(dataModel);
			} catch (Throwable exc) {
				Logger.getLogger().logError(exc);
			}

			if (pageHandler == null)
				pageHandler = new SimplePageHandler();

			if (pageGroupHandler == null)
				pageGroupHandler = new SimplePageGroupHandler();

			initialized = true;
		}

		private int checkForSpecialIds(String pageId) {
			int result = -1;

			List pages = getPages();

			if (pages.isEmpty() || pageId == null)
				return -1;

			if (pageId.startsWith(IDMPageHandler.PAGE_AFTER)) {
				String afterID = pageId.substring(IDMPageHandler.PAGE_AFTER.length(), pageId.length());
				result = getIndexOf(afterID);
				result = result >= 0 && result < pages.size() - 1 ? result + 1 : -1;
			} else if (pageId.startsWith(IDMPageHandler.PAGE_BEFORE)) {
				String beforeID = pageId.substring(IDMPageHandler.PAGE_BEFORE.length(), pageId.length());
				result = getIndexOf(beforeID);
				result = result >= 1 && result < pages.size() ? result - 1 : -1;
			} else {
				result = getIndexOf(pageId);
			}

			return result;
		}

		private int getIndexOf(String pageId) {
			int result = -1;

			List pages = getPages();
			for (int index = 0; index < pages.size(); index++) {
				if (((IWizardPage) pages.get(index)).getName().equals(pageId)) {
					result = index;
					break;
				}
			}

			return result;
		}

		public boolean isInitialized() {
			return initialized;
		}
	}

	public void storeDefaultSettings(DataModelWizard wizard) {
		Iterator pageGroups = groupTable.values().iterator();
		while (pageGroups.hasNext()) {
			PageGroupEntry pageGroup = (PageGroupEntry) pageGroups.next();
			if (pageGroup.isInitialized()) {
				Iterator pages = pageGroup.getPages().iterator();
				while (pages.hasNext()) {
					IWizardPage page = (IWizardPage) pages.next();
					wizard.storeDefaultSettings(page);
				}
			}
		}

	}
}
