/*
* 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.internal.util;

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

import org.eclipse.wst.xml.core.internal.contentmodel.CMAnyElement;
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.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNodeList;
import org.eclipse.wst.xml.core.internal.contentmodel.util.CMVisitor;
import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMNamespaceHelper;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;


/**
 * A special CMValidator that knows about DOMs
 */
public class DOMValidator extends CMValidator
{               
  protected String getNamespaceURI(Node node)
  {   
    return DOMNamespaceHelper.getNamespaceURI(node);
    //return node.getNamespaceURI();
  }
          

  //
  // This is a temporary hack!!
  //
  protected String getFallbackNamepaceURI(CMElementDeclaration ed)
  {   
    String fallbackNamepaceURI = null;
    CMDocument cmDocument = (CMDocument)ed.getProperty("CMDocument");
    if (cmDocument != null)
    {
      fallbackNamepaceURI = (String)cmDocument.getProperty("http://org.eclipse.wst/cm/properties/targetNamespaceURI");  
    }  
    return fallbackNamepaceURI;
  }

  /**
   * Encode the Element's NodeList as a List of strings that the validator recognizes
   */
  public List createContentSpecificationList(Element element, CMElementDeclaration ed)
  {                                                                    
    boolean isNamespaceAware = isNamespaceAware(ed);
    Vector v = new Vector();         
    for (Node childNode = element.getFirstChild(); childNode != null; childNode = childNode.getNextSibling())
    { 
      v.add(createContentSpecification(childNode, isNamespaceAware, isNamespaceAware ? getFallbackNamepaceURI(ed) : null));
    }
    return v;
  }


  public List createContentSpecificationList(List nodeList, CMElementDeclaration ed)
  {             
    boolean isNamespaceAware = isNamespaceAware(ed);
    Vector v = new Vector();            
 
    for (Iterator i = nodeList.iterator(); i.hasNext(); )
    {
      Node node = (Node)i.next();
      v.add(createContentSpecification(node, isNamespaceAware, getFallbackNamepaceURI(ed)));
    }
    return v;
  }


  /**
   * Encode the Node as a string that the validator recognizes
   */
  public String createContentSpecification(Node node, boolean isNamespaceAware, String fallbackNamepaceURI)
  {
    String result = "!";
    switch (node.getNodeType())
    {
      case Node.ELEMENT_NODE :
      {  
        String nodeName = node.getNodeName();  
        if (nodeName.startsWith("jsp:"))
        {  
          result = "!"; // treat it as a comment so that it's ignored by the validator
        }
        else
        {
          if (isNamespaceAware)
          {
            result = DOMNamespaceHelper.getUnprefixedName(nodeName);
            String uri = getNamespaceURI(node);
            if (uri != null)
            {
              result = "[" + uri + "]" + result;   
            } 
            else if (fallbackNamepaceURI != null)
            {
              result = "[" + fallbackNamepaceURI + "]" + result;  
            }
          }  
          else
          {
            result = nodeName;
          }
        }        
        //ContentModelManager.println("result " + result);
        break;
      }
      case Node.PROCESSING_INSTRUCTION_NODE :
      {
        result = "?";
        break;
      }
      case Node.COMMENT_NODE :
      {
        result = "!";
        break;
      }
      case Node.CDATA_SECTION_NODE :
      {
        result = "\"" + node.getNodeName() + "\"";
        break;
      }
      case Node.TEXT_NODE :
      {
        String data = ((Text)node).getData();
        // here we test to see if the test node is 'ignorable'
        if (data != null && data.trim().length() > 0)
        {
          result = "\"" + node.getNodeName() + "\"";
        }
        else
        {
          result = "!"; // todo... use another symbol?
        }
        break;
      }
    }
    return result;
  }


  /**
   *
   */
  public List createContentSpecificationList(CMNode cmNode)
  {
    List list = new Vector();
    switch (cmNode.getNodeType())
    {
      case CMNode.ELEMENT_DECLARATION :
      {         
        list.add(createContentSpecificationForCMElementDeclaration((CMElementDeclaration)cmNode));   
        break;
      }
      case CMNode.DATA_TYPE :
      {
        list.add("\"" + cmNode.getNodeName() + "\"");
        break;
      }
      case CMNode.GROUP :
      {
        createContentSpecificationListForCMGroup((CMGroup)cmNode, list);
        break;
      }
      case CMNode.ANY_ELEMENT :
      {
        list.add("*");
        break;
      }
      default :
      {
        list.add("!");
      }
    }
    return list;
  }
     

  /**
   * 
   */              
  protected String createContentSpecificationForCMElementDeclaration(CMElementDeclaration ed)
  {  
    CMDocument document = (CMDocument)ed.getProperty("CMDocument");
    String uri = document != null ? (String)document.getProperty("http://org.eclipse.wst/cm/properties/targetNamespaceURI") : null;
    String string = ed.getNodeName();
    if (uri != null)
    {            
      string = "[" + uri + "]" + string;
    }
    return string;
  }
  
  /**
   *
   */
  protected void createContentSpecificationListForCMGroup(CMGroup group, List list)
  {         
    CMGroupContentVisitor visitor = new CMGroupContentVisitor(group, list);
    visitor.visitCMNode(group);
  } 
     
  protected class CMGroupContentVisitor extends CMVisitor
  {  
    protected CMGroup root;                             
    protected List list;

    public CMGroupContentVisitor(CMGroup root, List list)
    {                                        
      this.root = root;        
      this.list = list;
    }

    public void visitCMElementDeclaration(CMElementDeclaration ed)
    {           
      if (ed.getMinOccur() > 0)
      {
        list.add(createContentSpecificationForCMElementDeclaration(ed));
      }
    }       

    public void visitCMAnyElement(CMAnyElement anyElement)
    {   
      list.add("*");
    }

    public void visitCMGroup(CMGroup group)
    {                              
      if (group == root || group.getMinOccur() > 0)
      {
        int op = group.getOperator();
        if (op == CMGroup.SEQUENCE)
        {
          super.visitCMGroup(group);
        }
        else if (op == CMGroup.CHOICE)
        {
          CMNodeList nodeList = group.getChildNodes();
          if (nodeList.getLength() > 0)
          {
            visitCMNode(nodeList.item(0));
          }      
        }
      }
    }
  }

  public boolean isNamespaceAware(CMElementDeclaration ed)
  { 
    return ed != null ? ed.getProperty("http://org.eclipse.wst/cm/properties/isNameSpaceAware") != null : false;
  }
     
  /**
   *
   */
  public CMNode[] getOriginArray(CMElementDeclaration ed, Element element)
  {
    ElementPathRecordingResult result = new ElementPathRecordingResult();
    getOriginArray(ed, createContentSpecificationList(element, ed), stringContentComparitor, result);
    return result.getOriginArray();
  }
                   
  /**
   *
   */
  public MatchModelNode getMatchModel(CMElementDeclaration ed, Element element)
  {
    MatchModelNode matchModelNode = null;
    PathRecordingResult result = new PathRecordingResult();
    validate(ed, createContentSpecificationList(element, ed), stringContentComparitor, result);
    if (result.isValid)
    {
      matchModelNode = result.getMatchModel();
    }
    return matchModelNode;
  }
                           

  public List clone(List list)
  {   
    List result = new Vector(list.size());
    result.addAll(list);
    return result;
  }
 
  /**
   *
   */
  public boolean canInsert(CMElementDeclaration ed, List contentSpecificationList, int insertIndex, CMNode cmNode)
  {           
    List clonedList = clone(contentSpecificationList);
    insert(clonedList, insertIndex, cmNode);
    return isValid(ed, clonedList);
  }  

  /**
   *
   */
  public boolean canInsert(CMElementDeclaration ed, List contentSpecificationList, int insertIndex, List cmNodeList)
  {              
    List clonedList = clone(contentSpecificationList);
    insert(clonedList, insertIndex, cmNodeList);
    return isValid(ed, clonedList);
  }  

  /**
   *
   */
  public boolean canRemove(CMElementDeclaration ed, List contentSpecificationList, int startRemoveIndex)
  {
    return canRemove(ed, contentSpecificationList, startRemoveIndex, startRemoveIndex);
  }

  /**
   *
   */
  public boolean canRemove(CMElementDeclaration ed, List contentSpecificationList, int startRemoveIndex, int endRemoveIndex)
  {
    List clonedList = clone(contentSpecificationList);
    remove(clonedList, startRemoveIndex, endRemoveIndex);
    return isValid(ed, clonedList);
  }
                        
  /**
   *
   */
  public boolean canReplace(CMElementDeclaration ed, List contentSpecificationList, int startRemoveIndex, int endRemoveIndex, CMNode cmNode)
  {
    List clonedList = clone(contentSpecificationList);
    remove(clonedList, startRemoveIndex, endRemoveIndex); 
    insert(clonedList, startRemoveIndex, cmNode);
    return isValid(ed, clonedList);
  }

  /**
   *
   */                      
  public boolean isValid(CMElementDeclaration ed, List contentSpecificationList)
  {
    Result result = new Result();
    validate(ed, contentSpecificationList, stringContentComparitor, result);
    return result.isValid;
  }
            

  protected Result validate(CMElementDeclaration ed, Element element)
  {
    Result result = new Result();
    validate(ed, createContentSpecificationList(element, ed), stringContentComparitor, result);
    return result;
  }


  protected void remove(List stringList, int startRemoveIndex, int endRemoveIndex)
  {
    if (startRemoveIndex != -1)
    {
      for (int i = startRemoveIndex; i <= endRemoveIndex; i++)
      {
        stringList.remove(i);
      }
    }
  }

  protected void insert(List stringList, int insertIndex, CMNode cmNode)
  {
    if (insertIndex != -1)
    {
      stringList.addAll(insertIndex, createContentSpecificationList(cmNode));
    }
  }

  protected void insert(List stringList, int insertIndex, List cmNodeList)
  {
    if (insertIndex != -1)
    {
      int insertListSize = cmNodeList.size();
      for (int i = insertListSize - 1; i >= 0; i--)
      {
        CMNode cmNode = (CMNode)cmNodeList.get(i);
        stringList.addAll(insertIndex, createContentSpecificationList(cmNode));
      }
    }
  }
}
