/*******************************************************************************
 * Copyright (c) 2002, 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.ws.internal.explorer.platform.wsdl.fragment.impl;

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

import org.eclipse.emf.common.util.EList;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.fragment.IXSDAttributeFragment;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.fragment.IXSDComplexFragment;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.fragment.IXSDFragment;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.fragment.XSDToFragmentConfiguration;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.fragment.XSDToFragmentController;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.fragment.util.XSDTypeDefinitionUtil;
import org.eclipse.xsd.XSDAttributeGroupContent;
import org.eclipse.xsd.XSDAttributeGroupDefinition;
import org.eclipse.xsd.XSDAttributeUse;
import org.eclipse.xsd.XSDComplexFinal;
import org.eclipse.xsd.XSDComplexTypeContent;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDModelGroup;
import org.eclipse.xsd.XSDModelGroupDefinition;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDParticleContent;
import org.eclipse.xsd.XSDTypeDefinition;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public abstract class XSDComplexFragment extends XSDMapFragment implements IXSDComplexFragment
{
  public XSDComplexFragment(String id, String name, XSDToFragmentConfiguration config, XSDToFragmentController controller)
  {
    super(id, name, config, controller);
  }

  public boolean setParameterValuesFromInstanceDocuments(Element[] instanceDocuments)
  {
    Element[] instanceDocumentsCopy = getInstanceDocumentsByTagName(instanceDocuments, getName());
    boolean paramsValid = internalEquals(instanceDocumentsCopy, instanceDocuments);
    XSDComplexTypeDefinition complexType = (XSDComplexTypeDefinition)getXSDTypeDefinition();
    XSDComplexTypeContent complexTypeContent = XSDTypeDefinitionUtil.getXSDComplexTypeContent(complexType);
    if (complexTypeContent instanceof XSDTypeDefinition)
      setParamsForXSDTypeDef(instanceDocumentsCopy);
    else
      setParamsForXSDParticle(instanceDocumentsCopy); 
    return setParamsForAttributes(instanceDocumentsCopy) && paramsValid;
  }

  private boolean setParamsForAttributes(Element[] instanceDocuments){
  	boolean paramsValid = true;
  	
  	IXSDAttributeFragment[] attributeFragments = getAllAttributeFragments();
  	for (int i = 0; i < instanceDocuments.length; i++){
  	  
  	  NamedNodeMap nodeMap = instanceDocuments[i].getAttributes();	
  	  for (int k = 0; k < attributeFragments.length; k++){
    	
  	  	String name = ((XSDAttributeUse)attributeFragments[k].getXSDToFragmentConfiguration().getXSDComponent()).getAttributeDeclaration().getName();
  	    paramsValid = attributeFragments[k].getXSDDelegationFragment().setAttributeParamsFromInstanceDocuments(nodeMap.getNamedItem(name));	
      }
  	}
    return paramsValid;
  }
  
  private boolean setParamsForXSDTypeDef(Element[] instanceDocuments)
  {
    boolean paramsValid = true;
    removeAllFragments();
    removeAllAttributeFragments();
    for (int i = 0; i < instanceDocuments.length; i++) {
      IXSDFragment childFrag = getFragment(createInstance());
      Element[] childInstanceDocuments = new Element[1];
      childInstanceDocuments[0] = instanceDocuments[i];
      if (!childFrag.setParameterValuesFromInstanceDocuments(setElementsTagName(childInstanceDocuments, childFrag.getName())))
        paramsValid = false;
    }
    return paramsValid;
  }

  private boolean setParamsForXSDParticle(Element[] instanceDocuments)
  {
    boolean paramsValid = true;
    removeAllFragments();
    removeAllAttributeFragments();
    for (int i = 0; i < instanceDocuments.length; i++) {
      IXSDFragment childFrag = getFragment(createInstance());
      Vector instancesVector = new Vector();
      NodeList nl = instanceDocuments[i].getChildNodes();
      for (int j = 0; j < nl.getLength(); j++)
      {
        Node node = nl.item(j);
        if (node instanceof Element)
          instancesVector.add(node);
        else
          paramsValid = false;
      }
      Element[] childInstanceDocuments = new Element[instancesVector.size()];
      instancesVector.copyInto(childInstanceDocuments);
      if (!childFrag.setParameterValuesFromInstanceDocuments(childInstanceDocuments))
        paramsValid = false;
    }
    return paramsValid;
  }

  public Element[] genInstanceDocumentsFromParameterValues(boolean genXSIType, Hashtable namespaceTable, Document doc)
  {
    XSDComplexTypeDefinition complexType = (XSDComplexTypeDefinition)getXSDTypeDefinition();
    XSDComplexTypeContent complexTypeContent = XSDTypeDefinitionUtil.getXSDComplexTypeContent(complexType);
    Element[] instanceDocuments;
    String tagName = getInstanceDocumentTagName(namespaceTable);
    if (complexTypeContent instanceof XSDTypeDefinition)
      instanceDocuments = genInstancesForXSDTypeDef(genXSIType, namespaceTable, tagName, doc);
    else
      instanceDocuments = genInstancesForXSDParticle(genXSIType, namespaceTable, tagName, doc);
      if(genXSIType) addXSIType(instanceDocuments, namespaceTable);
      instanceDocuments = addAttributes(instanceDocuments);
	return instanceDocuments;
  }

  private Element[] addAttributes(Element[] instanceDocuments){
  	
  	for (int i = 0;i< instanceDocuments.length;i++){
  	  IXSDAttributeFragment[] attributeFragments = getAllAttributeFragments();
      for (int k = 0; k < attributeFragments.length; k++){
    	String name = ((XSDAttributeUse)attributeFragments[k].getXSDToFragmentConfiguration().getXSDComponent()).getAttributeDeclaration().getName();
    	attributeFragments[k].getXSDDelegationFragment().setAttributesOnInstanceDocuments(instanceDocuments[i],name);	
      }
   	}
   	return instanceDocuments;
  }
  
  private Element[] genInstancesForXSDTypeDef(boolean genXSIType, Hashtable namespaceTable, String tagName, Document doc)
  {
    IXSDFragment[] fragments = getAllFragments();
    Vector instanceDocumentsCopy = new Vector();
    for (int i = 0; i < fragments.length; i++)
    {
      Element[] fragmentInstances = fragments[i].genInstanceDocumentsFromParameterValues(genXSIType, namespaceTable, doc);
      if (fragmentInstances.length > 0)
        instanceDocumentsCopy.add(fragmentInstances[0]);
    }
    Element[] instanceDocuments = new Element[instanceDocumentsCopy.size()];
    for (int i = 0; i < instanceDocuments.length; i++)
    {
      instanceDocuments[i] = (Element)instanceDocumentsCopy.get(i);
    }
    return setElementsTagName(instanceDocuments, tagName);
  }

  private Element[] genInstancesForXSDParticle(boolean genXSIType, Hashtable namespaceTable, String tagName, Document doc)
  {
    IXSDFragment[] childFrags = getAllFragments();
    Element[] instanceDocuments = new Element[childFrags.length];
    for (int i = 0; i < instanceDocuments.length; i++)
    {
      Element[] childInstances = childFrags[i].genInstanceDocumentsFromParameterValues(genXSIType, namespaceTable, doc);
      Element instanceDocument = doc.createElement(tagName);
      for (int j = 0; j < childInstances.length; j++)
      {
        if (childInstances[j] != null)
          instanceDocument.appendChild(childInstances[j]);
      }
      instanceDocuments[i] = instanceDocument;
    }
    return instanceDocuments;
  }

  private XSDModelGroup getXSDModelGroup(XSDParticle xsdParticle)
  {
    if (xsdParticle != null)
    {
      XSDParticleContent xsdParticleContent = xsdParticle.getContent();
      if (xsdParticleContent != null)
      {
        if (xsdParticleContent instanceof XSDModelGroupDefinition)
        {
          XSDModelGroupDefinition xsdModelGroupDef = (XSDModelGroupDefinition)xsdParticleContent;
          if (xsdModelGroupDef.isModelGroupDefinitionReference())
            xsdModelGroupDef = xsdModelGroupDef.getResolvedModelGroupDefinition();
          return xsdModelGroupDef.getModelGroup();
        }
        else if (xsdParticleContent instanceof XSDModelGroup)
          return (XSDModelGroup)xsdParticleContent;
      }
    }
    return null;
  }

  private List getInheritedParticles(XSDComplexTypeDefinition complexType)
  {
    Vector v = new Vector();
    if (complexType.getDerivationMethod().getValue() == XSDComplexFinal.EXTENSION)
    {
      XSDTypeDefinition extType = complexType.getBaseType();
      if (extType != null && !(extType instanceof XSDComplexTypeDefinition))
      {
        String namespace = extType.getTargetNamespace();
        String localname = extType.getName();
        if (namespace != null && localname != null)
        {
          XSDNamedComponent xsdNamedComp = getXSDToFragmentController().getWSDLPartsToXSDTypeMapper().getXSDTypeFromSchema(namespace, localname, false);
          if (xsdNamedComp instanceof XSDComplexTypeDefinition)
          {
            extType = (XSDComplexTypeDefinition)xsdNamedComp;
          }
        }
      }
      if (extType != null && extType != complexType && extType instanceof XSDComplexTypeDefinition)
      {
        XSDComplexTypeContent extTypeContent = XSDTypeDefinitionUtil.getXSDComplexTypeContent((XSDComplexTypeDefinition)extType);
        if (extTypeContent instanceof XSDParticle)
        {
          XSDModelGroup xsdModelGroup = getXSDModelGroup((XSDParticle)extTypeContent);
          if (xsdModelGroup != null)
          {
            v.addAll(getInheritedParticles((XSDComplexTypeDefinition)extType));
            v.addAll(xsdModelGroup.getParticles());
          }
        }
      }
    }
    return v;
  }

  private void gatherInheritedParticles(XSDComplexTypeDefinition complexType)
  {
    if (complexType.getDerivationMethod().getValue() == XSDComplexFinal.EXTENSION)
    {
      XSDComplexTypeContent complexTypeContent = XSDTypeDefinitionUtil.getXSDComplexTypeContent(complexType);
      if (complexTypeContent instanceof XSDParticle)
      {
        XSDModelGroup xsdModelGroup = getXSDModelGroup((XSDParticle)complexTypeContent);
        if (xsdModelGroup != null)
        {
          List inheritedParticles = getInheritedParticles(complexType);
          List particles = xsdModelGroup.getParticles();
          particles.addAll(0, inheritedParticles);
        }
      }
    }
  }

  
  
  public IXSDAttributeFragment[] getAllAttributeFragments()
  {
  	return super.getAllAttributeFragments();		
  
  }
  
  public void createAttributeFragments(String complexChildID)
  {
  	XSDComplexTypeDefinition complexType = (XSDComplexTypeDefinition)getXSDTypeDefinition();
  	EList atContentList = complexType.getAttributeContents();
  	Iterator iterator = atContentList.iterator();
  	while(iterator.hasNext()){
  	  Object object = (Object)iterator.next();
  	  if(object instanceof XSDAttributeGroupDefinition){
  		XSDAttributeGroupDefinition xsdAGD = (XSDAttributeGroupDefinition)object;
  		XSDAttributeGroupDefinition resolved = xsdAGD.getResolvedAttributeGroupDefinition();
  		EList aList = resolved.getContents();
  		Iterator iterator2 = aList.iterator();
  		while(iterator2.hasNext()){
  			createAttributeHelper((XSDAttributeUse)iterator2.next(),complexChildID);
  		}
  	  }
  	  else{
  	    XSDAttributeUse attUse =  (XSDAttributeUse)object;
  	    createAttributeHelper(attUse,complexChildID);
  	  }
  	  
  	}
  }
  
  private void createAttributeHelper(XSDAttributeUse attUse,String complexChildID){
	  XSDToFragmentConfiguration thisConfig = getXSDToFragmentConfiguration();
      XSDToFragmentConfiguration xsdConfig = new XSDToFragmentConfiguration();
      xsdConfig.setXSDComponent(attUse);
      xsdConfig.setStyle(thisConfig.getStyle());
      xsdConfig.setPartEncoding(thisConfig.getPartEncoding());
      xsdConfig.setWSDLPartName(thisConfig.getWSDLPartName());
      String newID = genID();
      addAttributeFragment(complexChildID + newID, getXSDToFragmentController().getFragment(xsdConfig,complexChildID + newID, complexChildID + newID));
  	  
  }
  
  
  public String createComplexInstance()
  {
    XSDComplexTypeDefinition complexType = (XSDComplexTypeDefinition)getXSDTypeDefinition();
    gatherInheritedParticles(complexType);
    XSDComplexTypeContent complexTypeContent = XSDTypeDefinitionUtil.getXSDComplexTypeContent(complexType);
    XSDToFragmentConfiguration thisConfig = getXSDToFragmentConfiguration();
    XSDToFragmentConfiguration xsdConfig = new XSDToFragmentConfiguration();
    xsdConfig.setXSDComponent(complexTypeContent);
    xsdConfig.setStyle(thisConfig.getStyle());
    xsdConfig.setPartEncoding(thisConfig.getPartEncoding());
    xsdConfig.setWSDLPartName(thisConfig.getWSDLPartName());
    String newID = genID();
    addFragment(newID, getXSDToFragmentController().getFragment(xsdConfig, newID, newID));
    createAttributeFragments(newID);
    return newID;
  }

  public String createInstance()
  {
    return createComplexInstance();
  }
}
