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

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.wst.common.ui.properties.internal.provisional.ITabbedPropertySheetPageContributor;
import org.eclipse.wst.sse.ui.internal.StructuredTextEditor;
import org.eclipse.wst.sse.ui.internal.view.events.INodeSelectionListener;
import org.eclipse.wst.sse.ui.internal.view.events.NodeSelectionChangedEvent;
import org.eclipse.wst.wsdl.ui.internal.extension.IModelQueryContributor;
import org.eclipse.wst.wsdl.ui.internal.extension.WSDLEditorExtension;
import org.eclipse.wst.wsdl.ui.internal.filter.ExtensiblityElementFilter;
import org.eclipse.wst.wsdl.ui.internal.outline.WSDLContentOutlinePage;
import org.eclipse.wst.wsdl.ui.internal.properties.section.WSDLTabbedPropertySheetPage;
import org.eclipse.wst.wsdl.ui.internal.util.ComponentReferenceUtil;
import org.eclipse.wst.wsdl.ui.internal.util.OpenOnSelectionHelper;
import org.eclipse.wst.wsdl.ui.internal.util.SelectionAdapter;
import org.eclipse.wst.wsdl.ui.internal.util.WSDLEditorUtil;
import org.eclipse.wst.wsdl.util.WSDLConstants;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.extension.DataTypeValueExtension;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.extension.ElementContentFilterExtension;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


public class WSDLTextEditor extends StructuredTextEditor implements INodeSelectionListener, ISelectionChangedListener, ITabbedPropertySheetPageContributor
{
  protected WSDLEditor wsdlEditor;
  protected WSDLContentOutlinePage outlinePage;
  protected WSDLSelectionManager wsdlSelectionManager;
  protected InternalSelectionProvider internalSelectionProvider = new InternalSelectionProvider();
  protected ModelQueryExtensionHelper modelQueryExtensionHelper;
  protected List modelQueryContributorList = new ArrayList();

  public WSDLTextEditor(WSDLEditor wsdlEditor)
  {
    this.wsdlEditor = wsdlEditor;
    wsdlSelectionManager = wsdlEditor.getSelectionManager();
    wsdlSelectionManager.addSelectionChangedListener(this);

    WSDLEditorExtension[] extensions = WSDLEditorPlugin.getInstance().getWSDLEditorExtensionRegistry().getRegisteredExtensions(WSDLEditorExtension.MODEL_QUERY_CONTRIBUTOR);
    for (int i = 0; i < extensions.length; i++)
    {
      Object o = extensions[i].createExtensionObject(WSDLEditorExtension.MODEL_QUERY_CONTRIBUTOR, wsdlEditor);
      if (o != null)
      {
        modelQueryContributorList.add(o);
      }
    }
  }

  public void createPartControl(Composite arg0)
  {
    super.createPartControl(arg0);
    addOpenOnSelectionListener();
  }

  protected void addOpenOnSelectionListener()
  {
    KeyAdapter keyAdapter = new KeyAdapter()
    {
      public void keyReleased(KeyEvent arg0)
      {
        if (arg0.keyCode == SWT.F3)
        {
          List list = getViewerSelectionManager().getSelectedNodes();
          if (list.size() > 0)
          {
            Object object = list.get(0);
            if (object instanceof Node)
            {
              OpenOnSelectionHelper helper = new OpenOnSelectionHelper(wsdlEditor.getDefinition());   
              helper.openEditor((Node)object);
            }
          }
        }
      }
    };
    getTextViewer().getTextWidget().addKeyListener(keyAdapter);
  }

 
  /*
   * @see StructuredTextEditor#setModel(IFileEditorInput)
   */
  public void setModel(IFileEditorInput input)
  {
    if (modelQueryExtensionHelper != null)
    {
      modelQueryExtensionHelper.dispose();
      modelQueryExtensionHelper = null;
    }

    super.setModel(input);

    for (Iterator i = modelQueryContributorList.iterator(); i.hasNext();)
    {
      IModelQueryContributor modelQueryContributor = (IModelQueryContributor)i.next();
      modelQueryContributor.setModel((IDOMModel)getModel());
    }

    // contribute the ModelQueryExtensionHelper as an extension too
    //
    modelQueryExtensionHelper = new ModelQueryExtensionHelper((IDOMModel)getModel());
  }

  
  public Object getAdapter(Class required)
  {
		if (IContentOutlinePage.class.equals(required))
		{
		  return getContentOutlinePage();
		}    
		if (IPropertySheetPage.class.equals(required))
		{
			if (fPropertySheetPage == null || fPropertySheetPage.getControl() == null || fPropertySheetPage.getControl().isDisposed())
			{
//			  System.out.println("Create WSDL Property Sheet");
//        PropertySheetConfiguration cfg = createPropertySheetConfiguration();
//        if (cfg != null)
//        {
//            if (cfg instanceof StructuredPropertySheetConfiguration)
//            {
//                ((StructuredPropertySheetConfiguration) cfg).setEditor(this);
//            }
//            ConfigurablePropertySheetPage propertySheetPage = new ConfigurablePropertySheetPage();
//            propertySheetPage.setConfiguration(cfg);
//            propertySheetPage.setModel(getModel());
//            fPropertySheetPage = propertySheetPage;
//        }

//  	    fPropertySheetPage = new WSDLPropertySheetPage(getModel(), getEditorPart());
//  	    ((WSDLPropertySheetPage) fPropertySheetPage).setSelectionManager(getWSDLEditor().getSelectionManager()); //getViewerSelectionManager());
////	  	  ((WSDLPropertySheetPage) fPropertySheetPage).setPropertySourceProvider((WSDLPropertySheetPage) fPropertySheetPage);
//  	    ((WSDLPropertySheetPage)fPropertySheetPage).setPropertySourceProvider(new ExtensiblePropertySourceProvider(getWSDLEditor()));
////  	    getWSDLEditor().getSelectionManager().addSelectionChangedListener((WSDLPropertySheetPage)fPropertySheetPage);

  	    fPropertySheetPage = new WSDLTabbedPropertySheetPage(this, getWSDLEditor());
  	    ((WSDLTabbedPropertySheetPage)fPropertySheetPage).setSelectionManager(getWSDLEditor().getSelectionManager());

			}
			return fPropertySheetPage;
		}
	
		return super.getAdapter(required);
  }

  public String[] getPropertyCategories()
  {
    return new String[] { "general", "namespace", "other", "attributes", "documentation", "facets" };
  }

	/**
	 * @see org.eclipse.wst.common.ui.properties.internal.provisional.ITabbedPropertySheetPageContributor#getContributorId()
	 */
	public String getContributorId()
	{
    return "org.eclipse.wst.wsdl.ui.internal.WSDLTextEditor";
	//	 return getSite().getId();
  }
  
  /*
   * @see StructuredTextEditor#getContentOutlinePage()
   */
  public IContentOutlinePage getContentOutlinePage()
  {
    if ((outlinePage == null) || outlinePage.getControl() == null || (outlinePage.getControl().isDisposed()))
    {
      outlinePage = new WSDLContentOutlinePage(wsdlEditor);
      outlinePage.setContentProvider(wsdlEditor.getExtensibleOutlineProvider());
      outlinePage.setLabelProvider(wsdlEditor.getExtensibleOutlineProvider());
      outlinePage.setModel(wsdlEditor.getDefinition()); //XMLDocument());

      getViewerSelectionManager().addNodeSelectionListener(this);
      internalSelectionProvider.addSelectionChangedListener(getViewerSelectionManager());
      internalSelectionProvider.setEventSource(outlinePage);
    }
    return outlinePage;
  }

  public WSDLEditor getWSDLEditor()
  {
    return (WSDLEditor)getEditorPart();
  }

  // used to map selections from the outline view to the source view
  // this class thinks of selections in terms of DOM element
  class InternalSelectionProvider extends SelectionAdapter
  {
    protected Object getObjectForOtherModel(Object object)
    {
      Node node = null;

      if (object instanceof Node)
      {
        node = (Node)object;
      }
      else
      {
        node = WSDLEditorUtil.getInstance().getNodeForObject(object);
      }

      // the text editor can only accept sed nodes!
      //
      if (!(node instanceof IDOMNode))
      {
        node = null;
      }
      return node;
    }
  }

  public void selectionChanged(SelectionChangedEvent event)
  {
    // here we convert the model selection to a node selection req'd for the source view
    //
    internalSelectionProvider.setSelection(event.getSelection());
  }

  public void nodeSelectionChanged(NodeSelectionChangedEvent event)
  {
    // here we convert an node seleciton to a model selection as req'd by the other views
    //
    if (!event.getSource().equals(internalSelectionProvider))
    {
      Element element = null;
      List list = event.getSelectedNodes();
      for (Iterator i = list.iterator(); i.hasNext();)
      {
        Node node = (Node)i.next();
        if (node != null)
        {
	        if (node.getNodeType() == Node.ELEMENT_NODE)
	        {
	          element = (Element)node;
	          break;
	        }
	        else if (node.getNodeType() == Node.ATTRIBUTE_NODE)
	        {
	          element = ((Attr)node).getOwnerElement();
	          break;
	        }
        }
      }

      Object o = element;
      if (element != null)
      {
        Object modelObject = WSDLEditorUtil.getInstance().findModelObjectForElement(wsdlEditor.getDefinition(), element);
        if (modelObject != null)
        {
          o = modelObject;
        }
      }

      if (o != null)
      {
        wsdlSelectionManager.setSelection(new StructuredSelection(o), internalSelectionProvider);
      }
      else
      {
        wsdlSelectionManager.setSelection(new StructuredSelection(), internalSelectionProvider);
      }
    }
  }

  public void update()
  {
    super.update();
    if (outlinePage != null)
      outlinePage.setModel(getModel());
  }

  public class ModelQueryExtensionHelper
  {
    protected ModelQuery modelQuery;
    protected DataTypeValueExtension dataTypeValueExtension;
    protected ElementContentFilterExtension elementContentFilterExtension;

    public ModelQueryExtensionHelper(IDOMModel xmlModel)
    {
      dataTypeValueExtension = new WSDLDataTypeValueExtension();
      elementContentFilterExtension = new WSDLElementContentFilterExtension();

      modelQuery = ModelQueryUtil.getModelQuery(xmlModel.getDocument());
      if (modelQuery != null && modelQuery.getExtensionManager() != null)
      {
        modelQuery.getExtensionManager().addExtension(dataTypeValueExtension);
        modelQuery.getExtensionManager().addExtension(elementContentFilterExtension);
      }
    }

    protected void dispose()
    {
      if (modelQuery != null && modelQuery.getExtensionManager() != null)
      {
        modelQuery.getExtensionManager().removeExtension(dataTypeValueExtension);
        modelQuery.getExtensionManager().removeExtension(elementContentFilterExtension);
      }
    }
  }

  /**
   * This class is used to extend the ModelQuery behaviour so that we can contribute our own
   * 'allowed values' for attributes or elements (e.g. the 'type' attribute).
   */
  public class WSDLDataTypeValueExtension implements DataTypeValueExtension
  {
    public int getType()
    {
      return DATA_TYPE_VALUE_EXTENSION;
    }

    public String getId()
    {
      return "WSDLDataTypeValueExtension";
    }

    public java.util.List getDataTypeValues(Element element, CMNode cmNode)
    {
      java.util.List list = new Vector();
      if (cmNode.getNodeType() == CMNode.ATTRIBUTE_DECLARATION)
      {
        ComponentReferenceUtil util = new ComponentReferenceUtil(getWSDLEditor().getDefinition());
        String name = cmNode.getNodeName();
        String currentElementName = element.getLocalName();
        Node parentNode = element.getParentNode();
        String parentName = "";
        if (parentNode != null)
        {
          parentName = parentNode.getLocalName();
        }

        if (checkName(name, "message"))
        {
          list.addAll(util.getMessageNames());
        }
        else if (checkName(name, "binding"))
        {
          list.addAll(util.getBindingNames());
        }
        else if (checkName(name, "type"))
        {
          if (checkName(currentElementName, "binding"))
          {
            list.addAll(util.getPortTypeNames());
          }
          else if (checkName(currentElementName, "part"))
          {
            list.addAll(util.getComponentNameList(true));
          }
        }
        else if (checkName(name, "element"))
        {
          if (checkName(currentElementName, "part"))
          {
            list.addAll(util.getComponentNameList(false));
          }
        }
      }
      return list;
    }

    protected boolean checkName(String localName, String token)
    {
      if (localName != null && localName.trim().equals(token))
      {
        return true;
      }
      return false;
    }
  }

  /**
   * This class performs some filtering for some known extensiblity elements to enable
   * smarter suggestions than those provided by the 'dumb' wsdl schema 
   */
  public class WSDLElementContentFilterExtension implements ElementContentFilterExtension
  {
    public int getType()
    {
      return ELEMENT_CONTENT_FILTER;
    }

    public String getId()
    {
      return "WSDLElementContentFilterExtension";
    }

    protected boolean isParentElementMessageReference(String parentElementName)
    {
      return parentElementName.equals("input") || parentElementName.equals("output") || parentElementName.equals("fault");
    }

    protected boolean isCMNodeMessageReferenceContent(String cmNodeName)
    {
      return cmNodeName.equals("body") || cmNodeName.equals("header") || cmNodeName.equals("fault") || cmNodeName.equals("urlReplacement") || cmNodeName.equals("urlEncoded");
    }

    public void filterAvailableElementContent(List list, Element element, CMElementDeclaration ed)
    {
      String parentElementNamespaceURI = element.getNamespaceURI();
      String parentElementName = element.getLocalName();

      // only filter children for 'non-schema' elements
      //     	
      if (!WSDLConstants.XSD_NAMESPACE_URI.equals(parentElementNamespaceURI))
      {
        for (int i = list.size() - 1; i >= 0; i--)
        {
          boolean include = true;
          CMNode cmNode = (CMNode)list.get(i);
          String cmNodeName = cmNode.getNodeName();
          if (parentElementName != null && cmNodeName != null && cmNode.getNodeType() == CMNode.ELEMENT_DECLARATION)
          {
            CMDocument cmDocument = (CMDocument)cmNode.getProperty("CMDocument");
            if (cmDocument != null)
            {
              String namespaceURI = (String)cmDocument.getProperty("http://org.eclipse.wst/cm/properties/targetNamespaceURI");
              if (namespaceURI != null)
              {
                // TODO... provide a list of namespaces that should always get filtered out 
                //
                if (namespaceURI.equals("http://schemas.xmlsoap.org/soap/encoding/") || namespaceURI.equals(WSDLConstants.XSD_NAMESPACE_URI))
                {
                  // exclude soap-enc elements
                  //
                  include = false;
                }
                else
                {
                  ExtensiblityElementFilter filter = (ExtensiblityElementFilter)WSDLEditorPlugin.getInstance().getExtensiblityElementFilterRegistry().get(namespaceURI);
                  if (filter != null)
                  {
                    include = filter.isValidContext(element, cmNodeName);
                  }
                }
              }
            }
          }
          if (!include)
          {
            list.remove(i);
          }
        }
      }
    }
  }
  
  public InternalSelectionProvider getInternalSelectionProvider() {
	return internalSelectionProvider;
  }
}
