/*
* Copyright (c) 2002 IBM Corporation and others.
* All rights reserved.   This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
* 
* Contributors:
*   IBM - Initial API and implementation
*   Jens Lukowski/Innoopract - initial renaming/restructuring
* 
*/
package org.eclipse.wst.xml.core.internal.contentmodel.util;

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

import org.eclipse.wst.xml.core.internal.contentmodel.CMAnyElement;
import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMContent;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
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.CMGroup;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNodeList;
import org.eclipse.wst.xml.core.internal.contentmodel.ContentModelManager;
import org.eclipse.wst.xml.core.internal.contentmodel.internal.util.CMDataTypeValueHelper;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;

                   
/**
 * todo... common up this code with 'ContentBuilder'
 */
public class DOMContentBuilderImpl extends CMVisitor implements DOMContentBuilder
{
  protected int buildPolicy = BUILD_ALL_CONTENT;
  protected Hashtable propertyTable = new Hashtable();

  protected boolean alwaysVisit = false;
  protected List resultList;
  protected Document document;
  protected Node currentParent;  
  protected Node topParent;
  protected Vector visitedCMElementDeclarationList = new Vector();
  protected boolean attachNodesToParent = true;
  protected NamespaceTable namespaceTable;
          
  protected List namespaceInfoList;
  protected Element rootElement; // this is used only teporarily via createDefaultRootContent
  protected ExternalCMDocumentSupport externalCMDocumentSupport;

  public boolean supressCreationOfDoctypeAndXMLDeclaration;

  protected CMDataTypeValueHelper valueHelper = new CMDataTypeValueHelper();
  
  protected int numOfRepeatableElements = 1;
  protected Stack cmGroupStack = new Stack();

  public interface ExternalCMDocumentSupport
  {
    public CMDocument getCMDocument(Element element, String uri);
  }

  public void setExternalCMDocumentSupport(ExternalCMDocumentSupport externalCMDocumentSupport)
  {
    this.externalCMDocumentSupport = externalCMDocumentSupport;
  }

  public DOMContentBuilderImpl(Document document)
  {
    this.document = document;
    namespaceTable = new NamespaceTable(document);
  }
         
  public void setBuildPolicy(int buildPolicy)
  {
    this.buildPolicy = buildPolicy;
  }

  public int getBuildPolicy()
  {
    return buildPolicy;
  }

  protected boolean buildAllContent(int policy)
  {
    return (policy & BUILD_ALL_CONTENT) == BUILD_ALL_CONTENT;
  }
    
  protected boolean buildOptionalElements(int policy)
  {
    return (policy & BUILD_OPTIONAL_ELEMENTS) == BUILD_OPTIONAL_ELEMENTS;
  }
  
  protected boolean buildOptionalAttributes(int policy)
  {
    return (policy & BUILD_OPTIONAL_ATTRIBUTES) == BUILD_OPTIONAL_ATTRIBUTES;
  }

  protected boolean buildFirstChoice(int policy)
  {
    return (policy & BUILD_FIRST_CHOICE) == BUILD_FIRST_CHOICE;
  }
  
  protected boolean buildTextNodes(int policy)
  {
    return (policy & BUILD_TEXT_NODES) == BUILD_TEXT_NODES;
  }
  
  protected boolean buildFirstSubstitution(int policy)
  {
    return (policy & BUILD_FIRST_SUBSTITUTION) == BUILD_FIRST_SUBSTITUTION;
  }
      
  public List getResult()
  {
    return resultList;
  }

  public void setProperty(String propertyName, Object value)
  {                         
    propertyTable.put(propertyName, value);
  }

  public Object getProperty(String propertyName)
  {
    return propertyTable.get(propertyName);
  }

  public void build(Node parent, CMNode child)
  {      
    resultList = new Vector();
    topParent = parent;
    currentParent = parent;          
    if (parent instanceof Element)
    {
      namespaceTable.addElementLineage((Element)parent);
    }
    attachNodesToParent = false;
    alwaysVisit = true;
    visitCMNode(child);
  }

  public void createDefaultRootContent(CMDocument cmDocument, CMElementDeclaration rootCMElementDeclaration, List namespaceInfoList) throws Exception
  {                    
    this.namespaceInfoList = namespaceInfoList;
    createDefaultRootContent(cmDocument, rootCMElementDeclaration);
  }

  public void createDefaultRootContent(CMDocument cmDocument, CMElementDeclaration rootCMElementDeclaration) throws Exception
  {
    String grammarFileName = cmDocument.getNodeName();
    if (!supressCreationOfDoctypeAndXMLDeclaration)
    {                                 
      // TODO cs... investigate to see if this code path is ever used, doesn't seem to be
      // for now I'm setting the encoding to UTF-8 just incase this code path is used somewhere
      //
      String piValue = "version=\"1.0\""; //$NON-NLS-1$
      String encoding = "UTF-8";           
      piValue += " encoding=\"" + encoding + "\""; //$NON-NLS-1$ //$NON-NLS-2$      
      ProcessingInstruction pi = document.createProcessingInstruction("xml", piValue); //$NON-NLS-1$
      document.appendChild(pi);

      // if we have a 'dtd' then add a DOCTYPE tag
      //
      if (grammarFileName != null && grammarFileName.endsWith("dtd")) //$NON-NLS-1$
      {
        DOMImplementation domImpl = document.getImplementation();
        DocumentType documentType = domImpl.createDocumentType(rootCMElementDeclaration.getElementName(), grammarFileName, grammarFileName);
        document.appendChild(documentType);
      }
    }                       
    
    // if we have a schema add an xsi:schemaLocation attribute
    //
    if (grammarFileName != null && grammarFileName.endsWith("xsd") && namespaceInfoList != null) //$NON-NLS-1$
    {              
      DOMNamespaceInfoManager manager = new DOMNamespaceInfoManager();    
      String name = rootCMElementDeclaration.getNodeName();
      if (namespaceInfoList.size() > 0)
      {
        NamespaceInfo info = (NamespaceInfo)namespaceInfoList.get(0);
        if (info.prefix != null && info.prefix.length() > 0)
        {
          name = info.prefix + ":" + name; //$NON-NLS-1$
        }
      }
      rootElement = createElement(rootCMElementDeclaration, name, document);
      manager.addNamespaceInfo(rootElement, namespaceInfoList, true);   
    }
    createDefaultContent(document, rootCMElementDeclaration);    
  }

  public void createDefaultContent(Node parent, CMElementDeclaration ed)
  {
    currentParent = parent;
    alwaysVisit = true;           
    visitCMElementDeclaration(ed);
  }   

  public String computeName(CMNode cmNode, Node parent)
  {                   
    String prefix = null;           
    return DOMNamespaceHelper.computeName(cmNode, parent, prefix, namespaceTable);
  }     

  // overide the following 'create' methods to control how nodes are created
  //
  protected Element createElement(CMElementDeclaration ed, String name, Node parent)
  {
    return  document.createElement(name);
  }

  protected Attr createAttribute(CMAttributeDeclaration ad, String name, Node parent)
  {
    return  document.createAttribute(name);
  }

  protected Text createTextNode(CMDataType dataType, String value, Node parent)
  {
    return document.createTextNode(value);
  }        
                 
  protected void handlePushParent(Element parent, CMElementDeclaration ed)
  {
  }   

  protected void handlePopParent(Element element, CMElementDeclaration ed)
  {
  }
  
  // The range must be between 1 and 99.
  public void setNumOfRepeatableElements(int i)
  {
  	numOfRepeatableElements = i;
  }
     
  protected int getNumOfRepeatableElements()
  {
  	return numOfRepeatableElements;
  }
        
  public void visitCMElementDeclaration(CMElementDeclaration ed)
  {
    int forcedMin = (buildOptionalElements(buildPolicy) || alwaysVisit) ? 1 : 0;
    int min = Math.max(ed.getMinOccur(), forcedMin);
    
    // Correct the min value if the element is contained in
    // a group.
    if (!cmGroupStack.isEmpty())
    {
      CMGroup group = (CMGroup)cmGroupStack.peek();
      int gmin = group.getMinOccur();
      if (gmin == 0)
        if (buildOptionalElements(buildPolicy))
          ; // min = min
        else
          min = min * gmin; // min = 0
      else
          min = min * gmin;
    }
    
    int max = Math.min(ed.getMaxOccur(), getNumOfRepeatableElements());
    if (max < min)
      max = min;
    	                          
    alwaysVisit = false;

    // Note - ed may not be abstract but has substitutionGroups
    // involved.
    if (buildFirstSubstitution(buildPolicy) 
        || isAbstract(ed)) // leave this for backward compatibility for now
    {
      // Note - To change so that if ed is optional, we do not 
      // generate anything here.  
      ed = getSubstitution(ed);
      
      // Note - the returned ed may be an abstract element in
      // which case the xml will be invalid.
    }

    if (min > 0 && !visitedCMElementDeclarationList.contains(ed))
    {
      visitedCMElementDeclarationList.add(ed);
      for (int i = 1; i <= max; i++)
      {
        // create an Element for each
        Element element = null;
        if (rootElement != null)                                                 
        {
          element = rootElement;
          rootElement = null;
        }                       
        else
        {
          element = createElement(ed, computeName(ed, currentParent), currentParent);
        }

        // visit the children of the GrammarElement
        Node oldParent = currentParent;
        currentParent = element;
        handlePushParent(element, ed);

        namespaceTable.addElement(element);
    
        boolean oldAttachNodesToParent = attachNodesToParent;
        attachNodesToParent = true;

        // instead of calling super.visitCMElementDeclaration()
        // we duplicate the code with some minor modifications
        CMNamedNodeMap nodeMap = ed.getAttributes();
        int size = nodeMap.getLength();
        for (int j = 0; j < size; j++)
        {
          visitCMNode(nodeMap.item(j));
        }

        CMContent content = ed.getContent();
        if (content != null)
        {
          visitCMNode(content);
        }

        if (ed.getContentType() == CMElementDeclaration.PCDATA)
        {
          CMDataType dataType = ed.getDataType();
          if (dataType != null)
          {
            visitCMDataType(dataType);
          }
        }
        // end duplication
        attachNodesToParent = oldAttachNodesToParent;
        handlePopParent(element, ed);
        currentParent = oldParent;    
        linkNode(element);
      }
      int size = visitedCMElementDeclarationList.size();
      visitedCMElementDeclarationList.remove(size - 1);
    }
  }


  public void visitCMDataType(CMDataType dataType)
  {
    Text text = null;
    String value = null;

    // For backward compatibility:
    //   Previous code uses a property value but new one uses
    //   buildPolicy.   
    if (getProperty(PROPERTY_BUILD_BLANK_TEXT_NODES) != null
        && getProperty(PROPERTY_BUILD_BLANK_TEXT_NODES).equals("true")) //$NON-NLS-1$
      buildPolicy = buildPolicy ^ BUILD_TEXT_NODES;
          
    if (buildTextNodes(buildPolicy))
    {
      value = valueHelper.getValue(dataType);
      if (value == null)
      {
        if (currentParent != null && currentParent.getNodeType() == Node.ELEMENT_NODE)
        {
          value = currentParent.getNodeName();
        }
        else
        {
          value = "pcdata"; //$NON-NLS-1$
        }
      }
    }  
    else
    {
      value = ""; //$NON-NLS-1$
    }
    text = createTextNode(dataType, value, currentParent);
    linkNode(text);
  }


  public void visitCMGroup(CMGroup e)
  {
  	cmGroupStack.push(e);
  	 
    int forcedMin = (buildOptionalElements(buildPolicy) || alwaysVisit) ? 1 : 0;
    int min = Math.max(e.getMinOccur(), forcedMin);

    int max = 0;
    if (e.getMaxOccur() == -1) // unbounded
      max = getNumOfRepeatableElements();
    else 
      max = Math.min(e.getMaxOccur(), getNumOfRepeatableElements());
    
    if (max < min)
      max = min;
                                
    alwaysVisit = false;

    for (int i = 1; i <= max; i++)
    {   
      if (e.getOperator() == CMGroup.CHOICE
          && buildFirstChoice(buildPolicy))
      {
        CMNode hintNode = null; 

        // todo... the CMGroup should specify the hint... but it seems as though
        // the Yamato guys are making the CMElement specify the hint.
        // I do it that way for now until... we should fix this post GA
        //    
        int listSize = visitedCMElementDeclarationList.size();                                                              
        if (listSize > 0)
        {                                                                                                                                          
          CMElementDeclaration ed = (CMElementDeclaration)visitedCMElementDeclarationList.get(listSize - 1);
          Object contentHint = ed.getProperty("contentHint"); //$NON-NLS-1$
          if (contentHint instanceof CMNode)
          {        
            hintNode = (CMNode)contentHint;
          }
        }
   
        // see if this hint corresponds to a valid choice
        //
        CMNode cmNode = null;

        if (hintNode != null)
        {
          CMNodeList nodeList = e.getChildNodes();
          int nodeListLength = nodeList.getLength();
          for (int j = 0; j < nodeListLength; j++)
          {
            if (hintNode == nodeList.item(j))
            { 
              cmNode = hintNode;
            }
          }
        }
        
        // if no cmNode has been determined from the hint, just use the first choice
        //
        if (cmNode == null)
        {
          CMNodeList nodeList = e.getChildNodes();
          if (nodeList.getLength() > 0)
          {
            cmNode = nodeList.item(0);
          }
        }

        if (cmNode != null)
        {
          visitCMNode(cmNode);
        }
      }
      else if (e.getOperator() == CMGroup.ALL          // ALL
                || e.getOperator() == CMGroup.SEQUENCE) // SEQUENCE 
      {
        // visit all of the content
        super.visitCMGroup(e);
      }
    }
    
    cmGroupStack.pop();
  }

  static int count = 0;

  public void visitCMAttributeDeclaration(CMAttributeDeclaration ad)
  {                                            
    if (alwaysVisit ||
        buildOptionalAttributes(buildPolicy) ||
        ad.getUsage() == CMAttributeDeclaration.REQUIRED)
    {                                                              
      alwaysVisit = false;                    
      String name = computeName(ad, currentParent);         
      String value = valueHelper.getValue(ad, namespaceTable);
      Attr attr = createAttribute(ad, name, currentParent);      
      attr.setValue(value != null ? value : ""); //$NON-NLS-1$
      linkNode(attr);
    }
  }                     
                
  protected boolean isAbstract(CMNode ed)
  {
    boolean result = false;
    if (ed != null)
    {
      Object value = ed.getProperty("Abstract"); //$NON-NLS-1$
      result = (value ==  Boolean.TRUE);
    }
    return result;
  }

  protected CMElementDeclaration getSubstitution(CMElementDeclaration ed)
  {
    CMElementDeclaration result = ed;
    CMNodeList l = (CMNodeList)ed.getProperty("SubstitutionGroup"); //$NON-NLS-1$
    if (l != null)
    {
      for (int i=0; i < l.getLength(); i++)
      {
        CMNode candidate = l.item(i);
        if (!isAbstract(candidate) && (candidate instanceof CMElementDeclaration))
        {
          result = (CMElementDeclaration)candidate;
          break;
        }
      }
    }
    return result;
  }

  protected CMElementDeclaration getParentCMElementDeclaration()
  {   
    CMElementDeclaration ed = null;
    int listSize = visitedCMElementDeclarationList.size();                                                              
    if (listSize > 0)
    {                                                                                                                                          
      ed = (CMElementDeclaration)visitedCMElementDeclarationList.get(listSize - 1);    
    } 
    return ed;
  }

  public void visitCMAnyElement(CMAnyElement anyElement)
  {                            
    // ingnore buildPolicy for ANY elements... only create elements if absolutely needed
    //
    int forcedMin = alwaysVisit ? 1 : 0;
    int min = Math.max(anyElement.getMinOccur(), forcedMin);                          
    alwaysVisit = false;
      
    String uri = anyElement.getNamespaceURI();  
    String targetNSProperty = "http://org.eclipse.wst/cm/properties/targetNamespaceURI"; //$NON-NLS-1$
    CMDocument parentCMDocument = (CMDocument)anyElement.getProperty("CMDocument"); //$NON-NLS-1$
    CMElementDeclaration ed = null;                          

    //System.out.println("parentCMDocument = " + parentCMDocument); //$NON-NLS-1$
    if (parentCMDocument != null)
    {          
      if (uri == null || uri.startsWith("##") || uri.equals(parentCMDocument.getProperty(targetNSProperty))) //$NON-NLS-1$
      {                               
        ed = getSuitableElement(getParentCMElementDeclaration(), parentCMDocument);
      }
    }          


    if (ed == null && externalCMDocumentSupport != null && uri != null && !uri.startsWith("##") && currentParent instanceof Element) //$NON-NLS-1$
    {
      CMDocument externalCMDocument = externalCMDocumentSupport.getCMDocument((Element)currentParent, uri);
      if (externalCMDocument != null)
      { 
        ed = getSuitableElement(null, externalCMDocument);
      }
    }

    for (int i = 1; i <= min; i++)
    {         
      if (ed != null)
      {                        
        visitCMElementDeclaration(ed); 
      }  
      else
      {                       
        Element element = document.createElement("ANY-ELEMENT");                    //$NON-NLS-1$
        linkNode(element);
      }              
    }               
  }    

  protected CMElementDeclaration getSuitableElement(CMNamedNodeMap nameNodeMap)
  {       
    CMElementDeclaration result = null;
    int size = nameNodeMap.getLength();             
    for (int i = 0; i < size; i++)
    {           
      CMElementDeclaration candidate = (CMElementDeclaration)nameNodeMap.item(i);
      if (!visitedCMElementDeclarationList.contains(candidate))
      {
        result = candidate;
        break;
      }
    }
    return result;
  }

  protected CMElementDeclaration getSuitableElement(CMElementDeclaration ed, CMDocument cmDocument)
  {       
    CMElementDeclaration result = null;

    if (ed != null)
    {
      result = getSuitableElement(ed.getLocalElements());
    }

    if (result == null && cmDocument != null)
    {
      result = getSuitableElement(cmDocument.getElements());
    } 

    return result;
  }


  public void linkNode(Node node)
  {
    if (attachNodesToParent && currentParent != null)
    {
      if (node.getNodeType() == Node.ATTRIBUTE_NODE)
      {
        ((Element)currentParent).setAttributeNode((Attr)node);
      }
      else
      {
        currentParent.appendChild(node);
      }
    }
    else if (resultList != null)
    {
      resultList.add(node);
    }
  }

  public static void testPopulateDocumentFromGrammarFile(Document document, String grammarFileName, String rootElementName, boolean hack)
  {
    try
    {
      CMDocument cmDocument = ContentModelManager.getInstance().createCMDocument(grammarFileName, null);
      CMNamedNodeMap elementMap = cmDocument.getElements();
      CMElementDeclaration element = (CMElementDeclaration)elementMap.getNamedItem(rootElementName);

      DOMContentBuilderImpl contentBuilder = new DOMContentBuilderImpl(document);
      contentBuilder.supressCreationOfDoctypeAndXMLDeclaration = hack;
      contentBuilder.createDefaultRootContent(cmDocument, element);

      System.out.println();
      System.out.println("-----------------------------"); //$NON-NLS-1$
      DOMWriter writer = new DOMWriter();
      if (hack)
      {
        writer.print(document, grammarFileName);
      }
      else
      {
        writer.print(document);
      }
      System.out.println("-----------------------------"); //$NON-NLS-1$
    }
    catch (Exception e)
    {
      System.out.println("Error: " + e); //$NON-NLS-1$
      e.printStackTrace();
    }
  }

  // test
  //
  /*
  public static void main(String arg[])
  {
    if (arg.length >= 2)
    {
      try
      {
        CMDocumentFactoryRegistry.getInstance().registerCMDocumentBuilderWithClassName("org.eclipse.wst.xml.core.internal.contentmodel.mofimpl.CMDocumentBuilderImpl");

        String grammarFileName = arg[0];
        String rootElementName = arg[1];

        Document document = (Document)Class.forName("org.apache.xerces.dom.DocumentImpl").newInstance();
        testPopulateDocumentFromGrammarFile(document, grammarFileName, rootElementName, true);
      }
      catch (Exception e)
      {
        System.out.println("DOMContentBuilderImpl error");
        e.printStackTrace();
      }
    }
    else
    {
      System.out.println("Usage : java org.eclipse.wst.xml.util.DOMContentBuildingCMVisitor grammarFileName rootElementName");
    }
  }*/
}
