/*
* 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.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


public class NamespaceTable extends NamespaceAttributeVisitor
{                   
  public Hashtable hashtable = new Hashtable();

  public NamespaceTable(Document document)
  {                     
    //DOMExtension domExtension = DOMExtensionProviderRegistry.getInstance().getDOMExtension(document);
    //if (domExtension != null)
    //{                          
    //  addNamespaceInfoList(domExtension.getImplictNamespaceInfoList(), true);
    // }
  }   

  private NamespaceTable()
  {        
  }  

  public boolean isNamespaceEncountered()
  {
    return hashtable.values().size() > 0;
  }

  public String getPrefixForURI(String uri)
  {           
    String result = null;
    NamespaceInfo entry = getNamespaceInfoForURI(uri, true);
    if (entry != null) 
    {
      result = entry.prefix;
    }                         
    return result;
  }
      

  public String getURIForPrefix(String prefix)
  {           
    String result = null;
    NamespaceInfo info = getNamespaceInfoForPrefix(prefix);
    if (info != null) 
    {
      result = info.uri;
    }                         
    return result;
  }    

          
  protected boolean isMatchingString(String a, String b)
  {
    return ((a == null && b == null) || (a != null && b != null && a.equals(b)));
  }
   

  public NamespaceInfo getNamespaceInfoForURI(String uri)
  {                                                     
    return getNamespaceInfoForURI(uri, false);
  }


  public NamespaceInfo getNamespaceInfoForURI(String uri, boolean testImplied)
  {
    NamespaceInfo result = null;
    for (Iterator i = hashtable.values().iterator(); i.hasNext(); )
    {                    
      NamespaceInfo nsInfo = (NamespaceInfo)i.next(); 
      if (isMatchingString(nsInfo.uri, uri))
      {                 
        result = nsInfo;
        if (testImplied && nsInfo.getProperty("isImplied") != null)
        {
          // continue
        }            
        else
        {
          break;
        }
      }
    }
    return result;
  } 


  public void setLocationHintForURI(String uri, String locationHint)
  {      
   // List list = new Vector();
    for (Iterator i = hashtable.values().iterator(); i.hasNext(); )
    {                    
      NamespaceInfo nsInfo = (NamespaceInfo)i.next(); 
      if (isMatchingString(nsInfo.uri, uri))
      {                                               
        nsInfo.locationHint = locationHint;
      }
    }
  }
    

  public NamespaceInfo getNamespaceInfoForPrefix(String prefix)
  {                                      
    prefix = prefix != null ? prefix : "";
    return (NamespaceInfo)hashtable.get(prefix);
  }   


  public void visitXMLNamespaceAttribute(Attr attr, String namespacePrefix, String namespaceURI)
  {                                 
    NamespaceInfo nsInfo = new NamespaceInfo();      
    nsInfo.prefix = namespacePrefix;
    nsInfo.uri = namespaceURI;      
   
    NamespaceInfo matchingNamespaceInfo = getNamespaceInfoForURI(namespaceURI);
    if (matchingNamespaceInfo != null)
    {                           
      nsInfo.locationHint = matchingNamespaceInfo.locationHint;
    }                                      

    internalAddNamespaceInfo(namespacePrefix, nsInfo);

    super.visitXMLNamespaceAttribute(attr, namespacePrefix, namespaceURI);
  } 
                 
  public void visitXSISchemaLocationValuePair(String uri, String locationHint)
  {
    setLocationHintForURI(uri, locationHint);
  }   

  public void addNamespaceInfo(NamespaceInfo info)
  {                           
    String key  = (info.prefix != null) ? info.prefix : "";
    internalAddNamespaceInfo(key, info);
  }

  protected void internalAddNamespaceInfo(String key, NamespaceInfo info)
  {
    hashtable.put(key, info);
  }

  protected void addNamespaceInfoList(List list, boolean isImplied)
  {       
    if (list != null)
    {
      for (Iterator i = list.iterator(); i.hasNext(); )
      {
        NamespaceInfo info = (NamespaceInfo)i.next();
        NamespaceInfo clone = new NamespaceInfo(info);    
        if (isImplied)
        {
          clone.setProperty("isImplied", "true");
        }
        addNamespaceInfo(clone);
      }
    }
  }

  public void addNamespaceInfoList(List list)
  {  
    addNamespaceInfoList(list, false);  
  }

  public void visitXSINoNamespaceSchemaLocationAttribute(Attr attr, String locationHint)
  {
    addNoNamespaceSchemaLocation(locationHint);
  } 

  public void addNoNamespaceSchemaLocation(String locationHint)
  {
    NamespaceInfo nsInfo = new NamespaceInfo();      
    nsInfo.prefix = null;
    nsInfo.uri = "";      
    nsInfo.locationHint = locationHint;  
    internalAddNamespaceInfo("", nsInfo);
  } 

  public void addNamespaceInfo(String prefix, String uri, String locationHint)
  {
    NamespaceInfo nsInfo = new NamespaceInfo();      
    nsInfo.prefix = prefix;
    nsInfo.uri = uri;      
    nsInfo.locationHint = locationHint;  
    internalAddNamespaceInfo(prefix != null ? prefix : "", nsInfo);
  } 

  public void addElement(Element element)
  {   
    visitElement(element);  
  }      
         
  public void addElementLineage(Element targetElement)
  {
    List list = NamespaceTable.getElementLineage(targetElement);                 
    for (Iterator i = list.iterator(); i.hasNext(); )
    {
      Element element = (Element)i.next();
      addElement(element);
    }            
  }

  public static List getElementLineage(Element element)
  {          
    List result = new ArrayList();             
    for (Node node = element; node != null; node = node.getParentNode())
    {                               
      if (node.getNodeType() == Node.ELEMENT_NODE)
      {
        result.add(0, node);                      
      }
      else
      {
        break;
      }
    }  
    return result;
  }    

  public Collection getNamespaceInfoCollection()
  {              
    return hashtable.values();
  } 

  public List getNamespaceInfoList()
  {                               
    List list = new Vector();
    list.addAll(hashtable.values());
    return list;
  }
} 
