/*******************************************************************************
 * Copyright (c) 2001, 2009 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.util;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.xml.namespace.QName;

import org.eclipse.swt.SWT;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.ExtensibleElement;
import org.eclipse.wst.wsdl.MessageReference;
import org.eclipse.wst.wsdl.Operation;
import org.eclipse.wst.wsdl.PortType;
import org.eclipse.wst.wsdl.Types;
import org.eclipse.wst.wsdl.ui.internal.extensions.ExtensibleTypeSystemProvider;
import org.eclipse.wst.wsdl.ui.internal.extensions.ITypeSystemProvider;
import org.eclipse.wst.wsdl.util.WSDLConstants;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class WSDLEditorUtil extends WSDLConstants {
	protected static WSDLEditorUtil instance;
	protected NodeAssociationManager nodeAssociationManager = new NodeAssociationManager();

	protected HashMap elementNameToTypeMap = new HashMap();

	public static final int ELEMENT = 14;
	public static final int TYPE = 15;

	public static WSDLEditorUtil getInstance() {
		if (instance == null) {
			instance = new WSDLEditorUtil();
		}
		return instance;
	}

	public WSDLEditorUtil() {
		elementNameToTypeMap.put(BINDING_ELEMENT_TAG, new Integer(BINDING));
		elementNameToTypeMap.put(DEFINITION_ELEMENT_TAG, new Integer(DEFINITION));
		elementNameToTypeMap.put(DOCUMENTATION_ELEMENT_TAG, new Integer(DOCUMENTATION));
		elementNameToTypeMap.put(FAULT_ELEMENT_TAG, new Integer(FAULT));
		elementNameToTypeMap.put(IMPORT_ELEMENT_TAG, new Integer(IMPORT));
		elementNameToTypeMap.put(INPUT_ELEMENT_TAG, new Integer(INPUT));
		elementNameToTypeMap.put(MESSAGE_ELEMENT_TAG, new Integer(MESSAGE));
		elementNameToTypeMap.put(OPERATION_ELEMENT_TAG, new Integer(OPERATION));
		elementNameToTypeMap.put(OUTPUT_ELEMENT_TAG, new Integer(OUTPUT));
		elementNameToTypeMap.put(PART_ELEMENT_TAG, new Integer(PART));
		elementNameToTypeMap.put(PORT_ELEMENT_TAG, new Integer(PORT));
		elementNameToTypeMap.put(PORT_TYPE_ELEMENT_TAG, new Integer(PORT_TYPE));
		elementNameToTypeMap.put(SERVICE_ELEMENT_TAG, new Integer(SERVICE));
		elementNameToTypeMap.put(TYPES_ELEMENT_TAG, new Integer(TYPES));
	}

	public int getWSDLType(Element element) {
		int result = -1;

		Integer integer = (Integer) elementNameToTypeMap.get(element.getLocalName());
		if (integer != null) {
			result = integer.intValue();
		}
		return result;
	}

	protected List getParentElementChain(Element element) {
		List list = new ArrayList();
		while (element != null) {
			list.add(0, element);
			Node node = element.getParentNode();
			element = (node != null && node.getNodeType() == Node.ELEMENT_NODE) ? (Element) node : null;
		}
		return list;
	}

	public Object findModelObjectForElement(Definition definition, Element targetElement) {
		Object o = nodeAssociationManager.getModelObjectForNode(definition, targetElement);
		return o;
	}

	public Element getElementForObject(Object o) {
		return ((org.eclipse.wst.wsdl.WSDLElement) o).getElement();
	}

	public Node getNodeForObject(Object o) {
		return nodeAssociationManager.getNode(o);
	}

	// Provide a mapping between Definitions and ITypeSystemProviders
// private Hashtable typeSystemProviders = new Hashtable();
	private ITypeSystemProvider typeSystemProvider;

	public ITypeSystemProvider getTypeSystemProvider(Definition definition) {
		if (typeSystemProvider == null) {
			typeSystemProvider = new ExtensibleTypeSystemProvider();
		}
		return typeSystemProvider;
	}

	public void setTypeSystemProvider(Definition definition, ITypeSystemProvider typeSystemProvider) {
		// typeSystemProviders.put(definition,typeSystemProvider);
	}

	public static QName createQName(Definition definition, String prefixedName) {
		QName qname = null;
		if (prefixedName != null) {
			int index = prefixedName.indexOf(":"); //$NON-NLS-1$
// String prefix = (index == -1) ? null : prefixedName.substring(0, index);
			String prefix = (index == -1) ? "" : prefixedName.substring(0, index);
			if (prefix != null) {
				String namespace = definition.getNamespace(prefix);
				if (namespace != null) {
					String localPart = prefixedName.substring(index + 1);
					qname = new QName(namespace, localPart);
				}
			}
		}
		return qname;
	}

	public List getExtensibilityElementNodes(ExtensibleElement extensibleElement) {
		// For Types, I need to get all the schemas
		if (extensibleElement instanceof Types) {
			Types xsdEE = (Types) extensibleElement;
			return xsdEE.getSchemas();
		}
		/*
		 * List childList = new ArrayList();
		 * 
		 * Element parentElement = getElementForObject(extensibleElement); if
		 * (parentElement != null) {
		 * 
		 * NodeList nodeList = parentElement.getChildNodes(); int
		 * nodeListLength = nodeList.getLength(); for (int i = 0; i <
		 * nodeListLength; i++) { childList.add(nodeList.item(i)); } HashMap
		 * extensibleElementTable = new HashMap(); for (Iterator i =
		 * extensibleElement.getEExtensibilityElements().iterator();
		 * i.hasNext();) { ExtensibilityElement extensibilityElement =
		 * (ExtensibilityElement)i.next(); if (extensibilityElement != null) {
		 * Element element = getElementForObject(extensibilityElement); if
		 * (element != null) { extensibleElementTable.put(element, element); } } }
		 * 
		 * for (Iterator i = childList.iterator(); i.hasNext();) { Object o =
		 * i.next(); if (extensibleElementTable.get(o) == null) { i.remove(); } } }
		 * return childList;
		 */
		return extensibleElement.getEExtensibilityElements();
	}

	public static boolean isOrientationRightToLeft()
	{
	  int defaultOrientation = SWT.NONE;
	  IWorkbench workbench = PlatformUI.getWorkbench();
	  if (workbench != null)
	  {
	    IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();

	    // We could not find any known API to retrieve the active workbench
	    // window orientation without using the internal class.

	    if (activeWorkbenchWindow instanceof WorkbenchWindow)
	    {
	      WorkbenchWindow workbenchWindow = (WorkbenchWindow)activeWorkbenchWindow;
	      defaultOrientation = workbenchWindow.getDefaultOrientation();
	    }
	  }      
	  boolean isRightToLeft = SWT.RIGHT_TO_LEFT == defaultOrientation;
	  return isRightToLeft;
	}

  /*
	 * Returns a list of 'children' of the given object model (WSDLElement).
	 */
	public static List getModelGraphViewChildren(Object object) {
		List childList = new ArrayList();

		if (object instanceof PortType) {
			PortType portType = (PortType) object;
			childList.addAll(portType.getOperations());
		}
		else if (object instanceof Operation) {
			Operation operation = (Operation) object;

			if (operation.getEInput() != null) {
				childList.add(operation.getEInput());
			}
			if (operation.getEOutput() != null) {
				childList.add(operation.getEOutput());
			}
			childList.addAll(operation.getFaults().values());
		}
		else if (object instanceof MessageReference) {
			MessageReference messageReference = (MessageReference) object;
			childList.add(messageReference.getEMessage());
		}

		return childList;
	}

	public static String getTargetNamespaceURIForSchema(String uri) {
		String result = null;
		try {
			URL url = new URL(uri);
			InputStream inputStream = url.openStream();
			result = WSDLEditorUtil.getTargetNamespaceURIForSchema(inputStream);
		}
		catch (Exception e) {
		}
		return result;
	}

	public static String getTargetNamespaceURIForSchema(InputStream input) {
		TargetNamespaceURIContentHandler handler = new TargetNamespaceURIContentHandler();
		ClassLoader prevClassLoader = Thread.currentThread().getContextClassLoader();
		Thread.currentThread().setContextClassLoader(WSDLEditorUtil.class.getClassLoader());
		try {
			XMLReader reader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
			reader.setContentHandler(handler);
			reader.parse(new InputSource(input));
		}
		catch (StopParseException e) {
			// this is a normal exception to stop parsing early,
			// when info is found, so we can safely ignore
		}
		catch (SAXException e) {
			// TODO: these should be logged, but the obvious choice,
			// WSDLEditorPlugin.logMessage(message) is an empy implementation,
			// so, for now, we'll at least print out.
			e.printStackTrace();
		}
		catch (IOException e) {
			// TODO: this should be logged, but the obvious choice,
			// WSDLEditorPlugin.logMessage(message) is an empy implementation,
			// so, for now, we'll at least print out.
			e.printStackTrace();
		}
		finally {
			Thread.currentThread().setContextClassLoader(prevClassLoader);
		}
		return handler.targetNamespaceURI;
	}

	/**
	 * This is a special exception that is used to stop parsing when required
	 * information is found.
	 */
	static class StopParseException extends org.xml.sax.SAXException {
		static final long serialVersionUID = 1L;

		/**
		 * Constructor StopParseException.
		 */
		StopParseException() {
			super("targetnamespace found, no need to continue the parse");
		}
	}

	protected static class TargetNamespaceURIContentHandler extends DefaultHandler {


		public String targetNamespaceURI;

		public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
			if (localName.equals("schema") || localName.equals("definitions")) //$NON-NLS-1$ //$NON-NLS-2$
			{
				int nAttributes = attributes.getLength();
				for (int i = 0; i < nAttributes; i++) {
					if (attributes.getLocalName(i).equals("targetNamespace")) //$NON-NLS-1$
					{
						targetNamespaceURI = attributes.getValue(i);
						break;
					}
				}
			}
			throw new StopParseException();
		}
	}
}
