package org.example.emfgmf.topicmap.presentation;

import java.util.Map;

import org.eclipse.jface.action.ContributionManager;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.ICoolBarManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.SubCoolBarManager;
import org.eclipse.jface.action.ToolBarContributionItem;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IActionBars2;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.SubActionBars2;

/**
 * An extended sub cool bar manager for used by the <code>TopicmapMultipageActionBarContributor</code>.
 * @see TopicmapMultipageActionBarContributor
 */
public class SubActionBarsExt extends SubActionBars2 {

	private IEditorActionBarContributor myContributor;

	private String myType;

	private IToolBarManager myToolBarManager;

	private ToolBarContributionItem myToolBarContributionItem;

	private PartListener myPartListener;

	/**
	 * Default constructor.
	 * @param page
	 * @param parent
	 * @param subContributor
	 * @param type
	 */
	public SubActionBarsExt(IWorkbenchPage page, IActionBars2 parent,
			IEditorActionBarContributor subContributor, String type) {
		super(parent, parent.getServiceLocator());
		assert type != null;
		myType = type;
		assert page != null;
		myPartListener = new PartListener(page);
		assert subContributor != null;
		myContributor = subContributor;
		myContributor.init(this, page);
	}

	/**
	 * @return the action bar contributor
	 */
	public IEditorActionBarContributor getContributor() {
		return myContributor;
	}

	/**
	 * Changes the active editor part.
	 * @param editorPart
	 */
	public void setEditorPart(IEditorPart editorPart) {
		myContributor.setActiveEditor(editorPart);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.SubActionBars#getToolBarManager()
	 */
	public IToolBarManager getToolBarManager() {
		if (myToolBarManager == null) {
			ICoolBarManager parentCoolBarManager = getTopCoolBarManager();
			if (parentCoolBarManager == null) {
				return null;
			}
			IContributionItem foundItem = parentCoolBarManager.find(myType);
			if (foundItem instanceof ToolBarContributionItem
					&& ((ToolBarContributionItem) foundItem)
							.getToolBarManager() != null) {
				myToolBarContributionItem = (ToolBarContributionItem) foundItem;
				myToolBarManager = myToolBarContributionItem
						.getToolBarManager();
			} else {
				if (false == parentCoolBarManager instanceof ContributionManager) {
					return null;
				}
				myToolBarManager = new ToolBarManager(SWT.FLAT | SWT.RIGHT);
				myToolBarContributionItem = new ToolBarContributionItem(
						myToolBarManager, myType);
				if (!((ContributionManager) parentCoolBarManager).replaceItem(
						myType, myToolBarContributionItem)) {
					parentCoolBarManager.add(myToolBarContributionItem);
				}
			}
			myToolBarContributionItem.setVisible(getActive());
			myToolBarManager.markDirty();
		}

		return myToolBarManager;
	}

	/**
	 * @return the top-level cool bar manager instance
	 */
	private ICoolBarManager getTopCoolBarManager() {
		ICoolBarManager coolBarManager = getCastedParent().getCoolBarManager();
		while (coolBarManager instanceof SubCoolBarManager
				&& ((SubCoolBarManager) coolBarManager).getParent() instanceof ICoolBarManager) {
			coolBarManager = (ICoolBarManager) ((SubCoolBarManager) coolBarManager)
					.getParent();
		}
		return coolBarManager;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.SubActionBars2#dispose()
	 */
	@Override
	public void dispose() {
		super.dispose();
		myContributor.dispose();
		myContributor = null;

		if (myToolBarContributionItem != null) {
			myToolBarContributionItem.dispose();
			myToolBarContributionItem = null;
		}

		if (myToolBarManager != null) {
			myToolBarManager.removeAll();
			myToolBarManager = null;
		}

		myPartListener.dispose();
		myPartListener = null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.SubActionBars2#setActive(boolean)
	 */
	@Override
	protected void setActive(boolean value) {
		if (getActive() == value) {
			return;
		}
		super.setActive(value);

		ICoolBarManager parentCoolBarManager = getTopCoolBarManager();
		if (parentCoolBarManager != null) {
			parentCoolBarManager.markDirty();
		}
		if (myToolBarManager != null && parentCoolBarManager != null) {
			IContributionItem[] items = myToolBarManager.getItems();
			for (int i = 0; i < items.length; i++) {
				IContributionItem item = items[i];
				item.setVisible(value);
			}
			myToolBarManager.markDirty();
			myToolBarManager.update(false);
		}

		if (value) {
			@SuppressWarnings("unchecked")
			Map<String, IAction> globals = getGlobalActionHandlers();
			for (Map.Entry<String, IAction> nextEntry : globals.entrySet()) {
				getParent().setGlobalActionHandler(nextEntry.getKey(),
						nextEntry.getValue());
			}
		} else {
			getParent().clearGlobalActionHandlers();
		}
		getParent().updateActionBars();
	}

	/**
	 * Inner class to be able to be notified when parts are activated.
	 */
	private class PartListener implements IPartListener {

		private IWorkbenchPage myPage;

		/**
		 * Default constructor.
		 * @param page
		 */
		public PartListener(IWorkbenchPage page) {
			myPage = page;
			myPage.addPartListener(this);
		}

		/**
		 * Default cleanup method.
		 */
		public void dispose() {
			myPage.removePartListener(this);
			myPage = null;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ui.IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partActivated(IWorkbenchPart part) {
			if (part instanceof IEditorPart) {
				IEditorPart editorPart = (IEditorPart) part;
				if (editorPart.getEditorSite().getActionBars() != getParent()
						&& getActive()) {
					deactivate();
					updateActionBars();
				}
			}
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ui.IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partBroughtToTop(IWorkbenchPart part) {
			// not required
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partClosed(IWorkbenchPart part) {
			// not required
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ui.IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partDeactivated(IWorkbenchPart part) {
			// not required
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ui.IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partOpened(IWorkbenchPart part) {
			// not required
		}

	}

}
