/*******************************************************************************
 * Copyright (c) 2001, 2006 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.wsdl.ui.internal.actions;

import java.util.HashMap;
import java.util.List;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.wst.sse.core.internal.encoding.CommonEncodingPreferenceNames;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.WSDLElement;
import org.eclipse.wst.wsdl.ui.internal.Messages;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin;
import org.eclipse.wst.wsdl.ui.internal.dialogs.NewComponentDialog;
import org.eclipse.wst.wsdl.ui.internal.util.WSDLEditorUtil;
import org.eclipse.wst.wsdl.util.WSDLConstants;
import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


public class AddElementAction extends BaseNodeAction {
	protected Node parentNode;
	protected String prefix;
	protected String nodeName;
	protected Element newElement;
	protected Node relativeNode = null;
	protected IEditorPart editorPart;
	protected Definition definition;
	protected Document document;
	protected boolean computeTopLevelRefChild;

	protected boolean selectNewlyCreatedObject = true; // We should not be
														// selecting the
														// object in the
														// action..... TODO

	public AddElementAction(String text, String imageDescriptorKey, Node parentNode, String nodeName) {
		setText(text);
		setImageDescriptor(WSDLEditorPlugin.getImageDescriptor(imageDescriptorKey));
		this.parentNode = parentNode;
		this.nodeName = nodeName;
	}

	public AddElementAction(String text, String imageDescriptorKey, Node parentNode, String prefix, String localName) {
		setText(text);
		setImageDescriptor(WSDLEditorPlugin.getImageDescriptor(imageDescriptorKey));
		this.parentNode = parentNode;
		this.prefix = prefix;
		this.nodeName = localName;
	}

	public AddElementAction(String text, Node parentNode, String prefix, String localName) {
		setText(text);
		setImageDescriptor(null);
		this.parentNode = parentNode;
		this.prefix = prefix;
		this.nodeName = localName;
	}

	public AddElementAction(Node parentNode, String prefix, String localName, Node relativeNode) {
		this.parentNode = parentNode;
		this.prefix = prefix;
		this.nodeName = localName;
		this.relativeNode = relativeNode;
	}

	public void setComputeTopLevelRefChild(boolean isEnabled) {
		computeTopLevelRefChild = isEnabled;
	}

	protected void setEditorPart(IEditorPart editorPart) {
		this.editorPart = editorPart;
	}

	protected boolean showDialog() {
		return true;
	}

	public void run() {
		boolean ok = showDialog();
		if (ok) {
			beginRecording();
			performAddElement();
			endRecording();
		}
	}

	protected void performAddElement() {
		if (parentNode != null) {
			newElement = createElement(nodeName);
			addAttributes(newElement);
			if (relativeNode == null && computeTopLevelRefChild) {
				relativeNode = computeTopLevelRefChild(newElement);
			}

			if (relativeNode == null) {
				parentNode.appendChild(newElement);
			}
			else {
				parentNode.insertBefore(newElement, relativeNode);
			}
			// format(parentNode);
			format(newElement);
			// Ugly..... We should not be selecting the object in the graph
			// view in the Action.
			// This should be refactored out. We add this boolean check
			// because WSDLSetTypeDialog.java
			// uses AddImportAction.java but we should not be selecting the
			// newly created import....
			if (selectNewlyCreatedObject) {
				selectObjectForNewElement();
			}
		}
	}

	// Ugly..... We should not be selecting the object in the graph view in
	// the Action.
	// This should be refactored out. We add this boolean check because
	// WSDLSetTypeDialog.java
	// uses AddImportAction.java but we should not be selecting the newly
	// created import....
	// We should call this method before calling run()
	public void selectObjectForNewElement(boolean select) {
		selectNewlyCreatedObject = select;
	}

	public Node getNode() {
		if (parentNode != null) {
			return parentNode;
		}
		else {
			return document;
		}
	}


	public String getUndoDescription() {
		return Messages._UI_ACTION_ADD; //$NON-NLS-1$
	}


	protected Element createElement(String nodeName) {
		Document document = parentNode.getOwnerDocument();

		Element element = (prefix != null && prefix.length() > 0) ? document.createElement(prefix + ":" + nodeName) : document.createElement(nodeName); //$NON-NLS-1$

		return element;
	}

	protected void addAttributes(Element newElement) {
	}


	protected void format(Node parentNode) {
		if (parentNode instanceof IDOMNode) {
			// format selected node
			FormatProcessorXML formatProcessorXML = new FormatProcessorXML();
			formatProcessorXML.formatNode((IDOMNode) parentNode);

		}
	}

	protected Element getDefinitionElement(Element parentElement) {
		Element definitionElement = null;

		for (Node node = parentElement.getOwnerDocument().getFirstChild(); node != null; node = node.getNextSibling()) {
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				Element element = (Element) node;
				if (WSDLEditorUtil.getInstance().getWSDLType(element) == WSDLConstants.DEFINITION) {
					definitionElement = element;
					break;
				}
			}
		}
		return definitionElement;
	}

	public Element getNewElement() {
		return newElement;
	}

	public void setDefinition(Definition definition) {
		this.definition = definition;
	}

	public void selectObjectForNewElement() {
		if (editorPart == null) {
			editorPart = WSDLEditorPlugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
		}
		if (editorPart != null && definition != null) {
			Object object = WSDLEditorUtil.getInstance().findModelObjectForElement(definition, newElement);
			if (object != null) {
				ISelectionProvider selectionProvider = (ISelectionProvider) editorPart.getAdapter(ISelectionProvider.class);
				if (selectionProvider != null) {
					selectionProvider.setSelection(new StructuredSelection(object));
				}
			}
		}
	}

	public void selectObject(WSDLElement object) {
		if (editorPart == null) {
			editorPart = WSDLEditorPlugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
		}
		if (editorPart != null && definition != null) {
			if (object != null) {
				ISelectionProvider selectionProvider = (ISelectionProvider) editorPart.getAdapter(ISelectionProvider.class);
				if (selectionProvider != null) {
					selectionProvider.setSelection(new StructuredSelection(object));
				}
			}
		}
	}

	public String showDialogHelper(String title, String defaultName, List usedNames) {
		String result = defaultName;
		NewComponentDialog dialog = new NewComponentDialog(WSDLEditorPlugin.getShell(), title, defaultName, usedNames);
		int rc = dialog.createAndOpen();
		if (rc == IDialogConstants.OK_ID) {
			result = dialog.getName();
		}
		else {
			result = null;
		}
		return result;
	}

	protected Node computeTopLevelRefChild(Node nodeToAdd) {
		Node result = null;
		int a = getPrecedence(nodeToAdd);

		for (Node node = parentNode.getFirstChild(); node != null; node = node.getNextSibling()) {
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				int b = getPrecedence(node);
				if (b > a) {
					result = node;
					break;
				}
			}
		}
		return result;
	}

	protected void createDefinitionStub() {
		if (document != null) {
			// Create the Definitions element with proper namespace
			Preferences preference = XMLCorePlugin.getDefault().getPluginPreferences();
			String charSet = preference.getString(CommonEncodingPreferenceNames.OUTPUT_CODESET);
			if (charSet == null || charSet.trim().equals("")) { //$NON-NLS-1$
				charSet = "UTF-8"; //$NON-NLS-1$
			}
			document.appendChild(document.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"" + charSet + "\"")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			Element root = document.createElement("wsdl:definitions"); //$NON-NLS-1$
			document.appendChild(root);

			// Add various namespace attributes here.
			root.setAttribute("xmlns:soap", "http://schemas.xmlsoap.org/wsdl/soap/"); //$NON-NLS-1$ //$NON-NLS-2$
			root.setAttribute("xmlns:tns", getDefaultNamespace()); //$NON-NLS-1$
			root.setAttribute("xmlns:wsdl", "http://schemas.xmlsoap.org/wsdl/"); //$NON-NLS-1$ //$NON-NLS-2$
			root.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); //$NON-NLS-1$ //$NON-NLS-2$
			root.setAttribute("name", getFileName()); //$NON-NLS-1$
			root.setAttribute("targetNamespace", getDefaultNamespace()); //$NON-NLS-1$

			definition.setElement(root);
			parentNode = root;
			prefix = definition.getPrefix(WSDLConstants.WSDL_NAMESPACE_URI);
		}
	}

	private String getDefaultNamespace() {
		String namespace = WSDLEditorPlugin.getInstance().getPreferenceStore().getString(Messages._UI_PREF_PAGE_DEFAULT_TARGET_NAMESPACE); //$NON-NLS-1$
		if (!namespace.endsWith("/")) { //$NON-NLS-1$
			namespace = namespace.concat("/"); //$NON-NLS-1$
		}

		namespace += getFileName() + "/"; //$NON-NLS-1$

		return namespace;
	}

	private String getFileName() {
		String fileLocation = definition.getLocation();
		IPath filePath = new Path(fileLocation);
		return filePath.removeFileExtension().lastSegment().toString();
	}

	protected static HashMap precedenceMap = createPrecedenceMap();

	protected static int getPrecedence(Node node) {
		int result = 2;
		String localName = node.getLocalName();
		if (localName != null) {
			Integer integer = (Integer) precedenceMap.get(localName);
			if (integer != null) {
				result = integer.intValue();
			}
		}
		return result;
	}

	protected static HashMap createPrecedenceMap() {
		HashMap hashMap = new HashMap();
		hashMap.put(WSDLConstants.DOCUMENTATION_ELEMENT_TAG, new Integer(1));
		hashMap.put(WSDLConstants.IMPORT_ELEMENT_TAG, new Integer(3));
		hashMap.put(WSDLConstants.TYPES_ELEMENT_TAG, new Integer(4));
		hashMap.put(WSDLConstants.MESSAGE_ELEMENT_TAG, new Integer(5));
		hashMap.put(WSDLConstants.PORT_TYPE_ELEMENT_TAG, new Integer(6));
		hashMap.put(WSDLConstants.BINDING_ELEMENT_TAG, new Integer(7));
		hashMap.put(WSDLConstants.SERVICE_ELEMENT_TAG, new Integer(8));
		return hashMap;
	}
}