/*******************************************************************************
 * Copyright (c) 2004 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.xml.ui.internal.tabletree;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.wst.sse.core.IStructuredModel;
import org.eclipse.wst.sse.ui.internal.StructuredTextEditor;
import org.eclipse.wst.xml.core.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl.CMDocumentLoader;
import org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl.InferredGrammarBuildingCMDocumentLoader;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.internal.ui.IDesignViewer;
import org.eclipse.wst.xml.internal.ui.IDesignViewerActionBarContributor;
import org.eclipse.wst.xml.internal.ui.XMLEditorResourceHandler;
import org.eclipse.wst.xml.internal.ui.XMLMultiPageEditorPart;
import org.eclipse.wst.xml.ui.util.SharedXMLEditorPluginImageHelper;
import org.w3c.dom.Document;

/**
 *  
 */
public class XMLTableTreeActionBarContributor implements IDesignViewerActionBarContributor {

	protected IEditorPart editorPart;
	protected final static String DESIGN_VIEWER_SEPARATOR_1_ID = "sed.tabletree.separator.1"; //$NON-NLS-1$
	protected final static String DESIGN_VIEWER_SEPARATOR_2_ID = "sed.tabletree.separator.2"; //$NON-NLS-1$
	protected final static String VALIDATE_XML_ID = "sed.tabletree.validateXML"; //$NON-NLS-1$
	protected final static String RELOAD_GRAMMAR_ID = "sed.tabletree.reloadGrammar"; //$NON-NLS-1$
	protected final static String TOGGLE_EDIT_MODE_ID = "sed.tabletree.toggleEditMode"; //$NON-NLS-1$
	protected final static String EXPAND_ALL_ID = "sed.tabletree.expandAll"; //$NON-NLS-1$
	protected final static String COLLAPSE_ALL_ID = "sed.tabletree.collapseAll"; //$NON-NLS-1$

	protected ToggleEditModeAction toggleAction;
	protected ReloadGrammarAction reloadGrammarAction;
	//	protected ValidateXMLAction validateXMLAction;
	protected ViewerExpandCollapseAction expandAction;
	protected ViewerExpandCollapseAction collapseAction;
	protected ViewerExpandCollapseAction xmlMenuExpandAction;
	protected ViewerExpandCollapseAction xmlMenuCollapseAction;

	public XMLTableTreeActionBarContributor() {
	}

	protected void removeContributions(IContributionManager manager) {
		try {
			doRemove(manager, DESIGN_VIEWER_SEPARATOR_1_ID);
			doRemove(manager, DESIGN_VIEWER_SEPARATOR_2_ID);
			doRemove(manager, VALIDATE_XML_ID);
			doRemove(manager, RELOAD_GRAMMAR_ID);
			doRemove(manager, TOGGLE_EDIT_MODE_ID);
			doRemove(manager, EXPAND_ALL_ID);
			doRemove(manager, COLLAPSE_ALL_ID);
		} catch (Exception e) {
		}
	}

	protected void doRemove(IContributionManager manager, String id) {
		try {
			if (manager.find(id) != null) {
				manager.remove(id);
			}
		} catch (Exception e) {
		}
	}

	public void init(IActionBars bars, IWorkbenchPage page) {
		init(bars);
	}

	public void init(IActionBars bars) {
		IToolBarManager tbm = bars.getToolBarManager();

		IMenuManager xmlMenu = bars.getMenuManager().findMenuUsingPath("com.ibm.etools.sed.editor.xmlmenu"); //$NON-NLS-1$

		if (xmlMenu == null) {
			xmlMenu = new MenuManager(XMLEditorResourceHandler.getResourceString("%XMLTableTreeActionBarContributor.0"), "com.ibm.etools.sed.editor.xmlmenu"); //$NON-NLS-1$ //$NON-NLS-2$
			bars.getMenuManager().insertBefore(IWorkbenchActionConstants.M_WINDOW, xmlMenu);
		} else {
			removeContributions(xmlMenu);
		}

		tbm.add(new Separator("DESIGN_VIEWER_SEPARATOR_1_ID")); //$NON-NLS-1$

		// ValidateXMLAction
		//                        
		// ugly hack ... we don't contribute the generic XML validator if we
		// already
		// have a DAD validator contribution (in the case of the DAD editor).
		// This hack will be removed when defect 212448 is fixed.
		//
		//		if (tbm.find("validate.dad.validateDAD") == null) {
		//			validateXMLAction = new ValidateXMLAction();
		//			tbm.add(validateXMLAction);
		//			xmlMenu.add(validateXMLAction);
		//		}

		// ToggleEditModeAction
		//           
		toggleAction = new ToggleEditModeAction();
		toggleAction.setId(TOGGLE_EDIT_MODE_ID);
		xmlMenu.add(toggleAction);
		tbm.add(toggleAction);

		// ReloadGrammarAction
		//
		reloadGrammarAction = new ReloadGrammarAction();
		reloadGrammarAction.setId(RELOAD_GRAMMAR_ID);
		tbm.add(reloadGrammarAction);
		xmlMenu.add(reloadGrammarAction);

		xmlMenu.add(new Separator());

		// ExpandCollapseAction
		//
		xmlMenuExpandAction = new ViewerExpandCollapseAction(true);
		xmlMenuExpandAction.setId(EXPAND_ALL_ID);
		xmlMenuExpandAction.setText(XMLEditorResourceHandler.getResourceString("%XMLTableTreeActionBarContributor.1")); //$NON-NLS-1$
		xmlMenu.add(xmlMenuExpandAction);

		xmlMenuCollapseAction = new ViewerExpandCollapseAction(false);
		xmlMenuCollapseAction.setId(COLLAPSE_ALL_ID);
		xmlMenuCollapseAction.setId(EXPAND_ALL_ID);
		xmlMenuCollapseAction.setText(XMLEditorResourceHandler.getResourceString("%XMLTableTreeActionBarContributor.2")); //$NON-NLS-1$
		xmlMenu.add(xmlMenuCollapseAction);
	}

	protected void addActionWithId(IMenuManager menuManager, Action action, String id) {
		action.setId(id);
		menuManager.add(action);
	}

	public void initViewerSpecificContributions(IActionBars bars) {
		IToolBarManager tbm = bars.getToolBarManager();
		tbm.add(new Separator(DESIGN_VIEWER_SEPARATOR_2_ID));

		expandAction = new ViewerExpandCollapseAction(true);
		expandAction.setId(EXPAND_ALL_ID);
		tbm.add(expandAction);

		collapseAction = new ViewerExpandCollapseAction(false);
		collapseAction.setId(COLLAPSE_ALL_ID);
		tbm.add(collapseAction);
	}

	public void setViewerSpecificContributionsEnabled(boolean enabled) {
		if (expandAction != null) {
			expandAction.setEnabled(enabled);
			xmlMenuExpandAction.setEnabled(enabled);
		}

		if (collapseAction != null) {
			collapseAction.setEnabled(enabled);
			xmlMenuCollapseAction.setEnabled(enabled);
		}
	}

	public void setActiveEditor(IEditorPart targetEditor) {
		editorPart = targetEditor;

		IStructuredModel model = getModelForEditorPart(targetEditor);
		reloadGrammarAction.setModel(model);
		toggleAction.setModelQuery(ModelQueryUtil.getModelQuery(model));

		XMLTableTreeViewer tableTreeViewer = getTableTreeViewerForEditorPart(editorPart);
		if (tableTreeViewer != null) {
			expandAction.setViewer(tableTreeViewer);
			collapseAction.setViewer(tableTreeViewer);

			xmlMenuExpandAction.setViewer(tableTreeViewer);
			xmlMenuCollapseAction.setViewer(tableTreeViewer);
		}

		if (editorPart instanceof XMLMultiPageEditorPart) {
			IWorkbenchPartSite site = editorPart.getSite();
			if (site instanceof IEditorSite) {
				ITextEditor textEditor = ((XMLMultiPageEditorPart) editorPart).getTextEditor();
				IActionBars actionBars = ((IEditorSite) site).getActionBars();
				actionBars.setGlobalActionHandler(ITextEditorActionConstants.UNDO, getAction(textEditor, ITextEditorActionConstants.UNDO));
				actionBars.setGlobalActionHandler(ITextEditorActionConstants.REDO, getAction(textEditor, ITextEditorActionConstants.REDO));
			}
		}

		// TODO... uncomment this and investigate NPE
		//
		// add the cut/copy/paste for text fields
		// ActionHandlerPlugin.connectPart(editorPart);
	}

	protected final IAction getAction(ITextEditor editor, String actionId) {
		return (editor == null ? null : editor.getAction(actionId));
	}

	protected IStructuredModel getModelForEditorPart(IEditorPart targetEditor) {
		IStructuredModel result = null;
		if (editorPart instanceof XMLMultiPageEditorPart) {
			StructuredTextEditor textEditor = ((XMLMultiPageEditorPart) targetEditor).getTextEditor();
			result = (textEditor != null) ? textEditor.getModel() : null;
		}
		return result;
	}

	protected XMLTableTreeViewer getTableTreeViewerForEditorPart(IEditorPart targetEditor) {
		XMLTableTreeViewer result = null;
		Object object = targetEditor.getAdapter(IDesignViewer.class);
		if (object instanceof XMLTableTreeViewer) {
			result = (XMLTableTreeViewer) object;
		}
		return result;
	}

	/**
	 *  
	 */
	public class ToggleEditModeAction extends Action {
		protected ImageDescriptor onImage = SharedXMLEditorPluginImageHelper.getImageDescriptor(SharedXMLEditorPluginImageHelper.IMG_ETOOL_CONSTRAINON);
		protected ImageDescriptor offImage = SharedXMLEditorPluginImageHelper.getImageDescriptor(SharedXMLEditorPluginImageHelper.IMG_ETOOL_CONSTRAINOFF);
		protected ModelQuery modelQuery;

		public ToggleEditModeAction() {
			setAppearanceForEditMode(ModelQuery.EDIT_MODE_CONSTRAINED_STRICT);
		}

		public void run() {
			if (modelQuery != null) {
				int newState = getNextState(modelQuery.getEditMode());
				modelQuery.setEditMode(newState);
				setAppearanceForEditMode(newState);
			}
		}

		public void setModelQuery(ModelQuery newModelQuery) {
			modelQuery = newModelQuery;
			if (modelQuery != null) {
				setAppearanceForEditMode(modelQuery.getEditMode());
			}
		}

		public void setAppearanceForEditMode(int editMode) {
			if (editMode == ModelQuery.EDIT_MODE_CONSTRAINED_STRICT) {
				setToolTipText(XMLEditorResourceHandler.getResourceString("%XMLTableTreeActionBarContributor.3")); //$NON-NLS-1$
				setText(XMLEditorResourceHandler.getResourceString("%XMLTableTreeActionBarContributor.4")); //$NON-NLS-1$
				setImageDescriptor(onImage);
			} else {
				setToolTipText(XMLEditorResourceHandler.getResourceString("%XMLTableTreeActionBarContributor.5")); //$NON-NLS-1$
				setText(XMLEditorResourceHandler.getResourceString("%XMLTableTreeActionBarContributor.6")); //$NON-NLS-1$
				setImageDescriptor(offImage);
			}
		}

		public int getNextState(int editMode) {
			int result = -1;
			if (editMode == ModelQuery.EDIT_MODE_CONSTRAINED_STRICT) {
				result = ModelQuery.EDIT_MODE_UNCONSTRAINED;
			} else {
				result = ModelQuery.EDIT_MODE_CONSTRAINED_STRICT;
			}
			return result;
		}
	}

	/**
	 *  
	 */
	public class ReloadGrammarAction extends Action {
		protected IStructuredModel model;

		public ReloadGrammarAction() {
			setDisabledImageDescriptor(SharedXMLEditorPluginImageHelper.getImageDescriptor(SharedXMLEditorPluginImageHelper.IMG_DTOOL_RLDGRMR));
			setImageDescriptor(SharedXMLEditorPluginImageHelper.getImageDescriptor(SharedXMLEditorPluginImageHelper.IMG_ETOOL_RLDGRMR));
			setToolTipText(XMLEditorResourceHandler.getResourceString("%XMLTableTreeActionBarContributor.7")); //$NON-NLS-1$
			setText(XMLEditorResourceHandler.getResourceString("%XMLTableTreeActionBarContributor.8")); //$NON-NLS-1$
		}

		public void setModel(IStructuredModel newModel) {
			this.model = newModel;
		}

		public void run() {
			if (model != null) {
				ModelQuery modelQuery = ModelQueryUtil.getModelQuery(model);
				Document document = ((IDOMModel) model).getDocument();
				if (modelQuery != null && modelQuery.getCMDocumentManager() != null) {
					modelQuery.getCMDocumentManager().getCMDocumentCache().clear();
					// TODO... need to figure out how to access the
					// DOMObserver via ModelQuery
					//  ...why?
					CMDocumentLoader loader = new InferredGrammarBuildingCMDocumentLoader(document, modelQuery);
					loader.loadCMDocuments();
				}
			}
		}
	}

	/**
	 * @see org.eclipse.ui.IEditorActionBarContributor#dispose()
	 */
	public void dispose() {
	}
}