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

import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.internal.annotation.AnnotationFileParser;


/**
 * AnnotationMap
 */
public class AnnotationMap
{                  
  protected List list = new Vector();
  protected Hashtable hashtable = new Hashtable();     
  protected boolean isCaseSensitive = true;

  public AnnotationMap()
  {
  } 

  public void setCaseSensitive(boolean isCaseSensitive)
  {
    this.isCaseSensitive = isCaseSensitive;
  }

  public void addAnnotation(Annotation annotation)
  {                  
    String spec = annotation.getSpec();
    if (spec != null)
    {                
      list.add(annotation);
      StringTokenizer st = new StringTokenizer(spec, "[]|\t\n\r\f ");                    //$NON-NLS-1$
      while (st.hasMoreTokens())
      {
        String cmNodeSpec = st.nextToken();
        addAnnotationForCMNodeSpec(cmNodeSpec, annotation);
      }
    }
  }                

  protected void addAnnotationForCMNodeSpec(String cmNodeSpec, Annotation annotation)
  {    
    String key = isCaseSensitive ? cmNodeSpec : cmNodeSpec.toLowerCase();
    List list = (List)hashtable.get(key);
    if (list == null)
    {       
      list = new Vector();

      hashtable.put(key, list);
    }
    list.add(annotation);
  }
                                         
  public String getProperty(String cmNodeSpec, String propertyName)
  {  
    String result = null;  
    String key = isCaseSensitive ? cmNodeSpec : cmNodeSpec.toLowerCase();
    List annotationList = (List)hashtable.get(key);
    if (annotationList != null)
    {
      for (Iterator i = annotationList.iterator(); i.hasNext(); )
      {
        Annotation annotation = (Annotation)i.next();
        result = annotation.getProperty(propertyName);
        if (result != null)
        {
          break;
        }
      }
    }                               
    return result;
  }

  public String getProperty(CMNode cmNode, String propertyName)
  {                                          
    String result = null;
    String cmNodeSpec = (String)cmNode.getProperty("spec"); //$NON-NLS-1$
    if (cmNodeSpec == null)
    {
      cmNodeSpec = cmNode.getNodeName();
    }                                    
    if (cmNodeSpec != null)
    {                      
      result = getProperty(cmNodeSpec, propertyName);
    }                                                     
    return result;
  }  

  public List getAnnotations()
  {
    return list;
  }

  public void load(String uri) throws Exception
  {                                   
    AnnotationFileParser parser = new AnnotationFileParser();
    parser.parse(this, uri);
  }
}
