/*******************************************************************************
 * Copyright (c) 2003, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Kaloyan Raev, kaloyan.raev@sap.com - bug 213927
 *******************************************************************************/
package org.eclipse.wst.common.frameworks.internal.ui;

import java.util.ArrayList;
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.jface.wizard.IWizardPage;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.datamodel.IDataModelPausibleOperation;
import org.eclipse.wst.common.frameworks.internal.datamodel.IDataModelPausibleOperationEvent;
import org.eclipse.wst.common.frameworks.internal.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(IDataModel dataModel, IDMPageGroup rootPageGroup) {

		this.dataModel = dataModel;
		this.groupTable = new HashMap();
		this.pageGroupStack = new Stack();
		this.rootPageGroup = rootPageGroup;


		PageGroupEntry rootPageGroupEntry = new PageGroupEntry(rootPageGroup);
		elements = getPageGroupExtensions();
		groupTable.put(this.rootPageGroup.getPageGroupID(), rootPageGroupEntry);

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

	public PageGroupManager(IDataModelPausibleOperation rootOperation, IDMPageGroup rootPageGroup) {
		this(rootOperation.getDataModel(), rootPageGroup);
		this.operationsRun = new HashSet();

		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 (Exception exc) {
			WTPUIPlugin.logError(exc);
			if (rootOperation != null) {
				try {
					rootOperation.rollBack(null, null);
				} catch (ExecutionException e) {
					WTPUIPlugin.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 (rootOperation != null) {
				if (topEntry.ranOperations) {
					try {
						rootOperation.rollBack(null, null);
					} catch (ExecutionException e) {
						WTPUIPlugin.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 IConfigurationElement[] getPageGroupExtensions() {
		List result = new ArrayList();
		
		IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CommonUIPluginConstants.PLUGIN_ID, ELEMENT_PAGE_GROUP);
		IConfigurationElement[] allElements = point.getConfigurationElements();
		for (int i = 0; i < allElements.length; i++) {
			IConfigurationElement element = (IConfigurationElement) allElements[i];
			if (ELEMENT_PAGE_GROUP.equals(element.getName())) {
				result.add(element);
			}
		}
		
		return (IConfigurationElement[]) result.toArray(new IConfigurationElement[] { });
	}

	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 (rootOperation != null && runOperations && requiresOperationsId != null && !operationsRun.contains(requiresOperationsId)) {
					pauseAfterExecution = requiresOperationsId;
					IStatus status = null;
					try {
						status = rootOperation.resume(null, null);
					} catch (ExecutionException e) {
						WTPUIPlugin.logError(e);
					}
					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 (Exception exc) {
					WTPUIPlugin.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 (Exception exc) {
				WTPUIPlugin.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 (Exception exc) {
				WTPUIPlugin.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);
				}
			}
		}
	}
}
