/* IIOMetadataFormatImpl.java --
   Copyright (C) 2004  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.imageio.metadata;

import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.w3c.dom.TypeInfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
import javax.imageio.ImageTypeSpecifier;

public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat
{
  /**
   * The standard metadata format name constant set to
   * "javax_imageio_1.0".
   */
  public static final String standardMetadataFormatName = "javax_imageio_1.0";

  private String rootName;

  // These maps assume that each element name is unique.

  private Map nodes = new HashMap();

  // A mapping from element name to child policy.
  private Map childPolicies = new HashMap();

  // A mapping from element name to the permissible number of
  // children.  Values in this map are length-two integer arrays; the
  // first index is the minimum bound, the second index is the maximum
  // bound.
  private Map childRanges = new HashMap();

  private String resourceBaseName;

  // Package-private so that it may be used in IIOMetadataNode.
  static class IIOMetadataNodeAttr extends IIOMetadataNode
    implements Attr
  {
    protected Element owner;
    protected String name;
    protected int dataType;
    protected boolean required;
    protected String defaultValue;

    public IIOMetadataNodeAttr (Element owner,
                                String name,
                                String defaultValue)
    {
      this (owner, name, IIOMetadataFormat.DATATYPE_STRING,
            true, defaultValue);
    }

    public IIOMetadataNodeAttr (Element owner,
                                String name,
                                int dataType,
                                boolean required,
                                String defaultValue)
    {
      this.owner = owner;
      this.name = name;
      this.dataType = dataType;
      this.required = required;
      this.defaultValue = defaultValue;
    }

    public String getName ()
    {
      return name;
    }

    public Element getOwnerElement ()
    {
      return owner;
    }

    public int getDataType ()
    {
      return dataType;
    }

    public TypeInfo getSchemaTypeInfo ()
    {
      return null;
    }

    public boolean getSpecified ()
    {
      return false;
    }

    public String getValue ()
    {
      return defaultValue;
    }

    public boolean isId()
    {
      return false;
    }

    public void setValue (String value)
    {
    }

    // new methods

    public boolean isRequired ()
    {
      return required;
    }
  }

  private class IIOMetadataNodeAttrEnumerated extends IIOMetadataNodeAttr
  {
    protected List enumeratedValues;

    public IIOMetadataNodeAttrEnumerated (Element owner,
                                          String name,
                                          int dataType,
                                          boolean required,
                                          String defaultValue,
                                          List enumeratedValues)
    {
      super (owner, name, dataType, required, defaultValue);
      this.enumeratedValues = new ArrayList (enumeratedValues);
    }

    public Object[] getEnumerations ()
    {
      return enumeratedValues.toArray ();
    }
  }

  private class IIOMetadataNodeAttrBounded extends IIOMetadataNodeAttr
  {
    protected String minValue;
    protected String maxValue;
    protected boolean minInclusive;
    protected boolean maxInclusive;

    public IIOMetadataNodeAttrBounded (Element owner,
                                       String name,
                                       int dataType,
                                       boolean required,
                                       String defaultValue,
                                       String minValue,
                                       String maxValue,
                                       boolean minInclusive,
                                       boolean maxInclusive)
    {
      super (owner, name, dataType, required, defaultValue);
      this.minValue = minValue;
      this.maxValue = maxValue;
      this.minInclusive = minInclusive;
      this.maxInclusive = maxInclusive;
    }

    public String getMinValue ()
    {
      return minValue;
    }

    public String getMaxValue ()
    {
      return maxValue;
    }
  }

  private class IIOMetadataNodeAttrList extends IIOMetadataNodeAttr
  {
    protected int listMinLength;
    protected int listMaxLength;

    public IIOMetadataNodeAttrList (Element owner,
                                    String name,
                                    int dataType,
                                    boolean required,
                                    int listMinLength,
                                    int listMaxLength)
    {
      super (owner, name, dataType, required, null);
      this.listMinLength = listMinLength;
      this.listMaxLength = listMaxLength;
    }

    public int getListMinLength ()
    {
      return listMinLength;
    }

    public int getListMaxLength ()
    {
      return listMaxLength;
    }
  }

  private class NodeObject
  {
    protected Element owner;
    protected Class classType;
    protected boolean required;
    protected Object defaultValue;
    protected int valueType;

    public NodeObject (Element owner,
                       Class classType,
                       boolean required,
                       Object defaultValue)
    {
      this.owner = owner;
      this.classType = classType;
      this.required = required;
      this.defaultValue = defaultValue;
      valueType = IIOMetadataFormat.VALUE_ARBITRARY;
    }

    public int getValueType ()
    {
      return valueType;
    }

    public Class getClassType ()
    {
      return classType;
    }

    public Element getOwnerElement ()
    {
      return owner;
    }

    public Object getDefaultValue ()
    {
      return defaultValue;
    }

    public boolean isRequired ()
    {
      return required;
    }
  }

  private class NodeObjectEnumerated extends NodeObject
  {
    protected List enumeratedValues;

    public NodeObjectEnumerated (Element owner,
                                 Class classType,
                                 boolean required,
                                 Object defaultValue,
                                 List enumeratedValues)
    {
      super (owner, classType, false, defaultValue);
      this.enumeratedValues = enumeratedValues;
      valueType = IIOMetadataFormat.VALUE_ENUMERATION;
    }

    public Object[] getEnumerations ()
    {
      return enumeratedValues.toArray();
    }
  }

  private class NodeObjectBounded extends NodeObject
  {
    protected Comparable minValue;
    protected Comparable maxValue;
    protected boolean minInclusive;
    protected boolean maxInclusive;

    public NodeObjectBounded (Element owner,
                              Class classType,
                              Object defaultValue,
                              Comparable minValue,
                              Comparable maxValue,
                              boolean minInclusive,
                              boolean maxInclusive)
    {
      super (owner, classType, false, defaultValue);
      this.minValue = minValue;
      this.maxValue = maxValue;
      this.minInclusive = minInclusive;
      this.maxInclusive = maxInclusive;
      if (minInclusive)
        {
          if (maxInclusive)
            valueType = IIOMetadataFormat.VALUE_RANGE_MIN_MAX_INCLUSIVE;
          else
            valueType = IIOMetadataFormat.VALUE_RANGE_MIN_INCLUSIVE;
        }
      else
        {
          if (maxInclusive)
            valueType = IIOMetadataFormat.VALUE_RANGE_MAX_INCLUSIVE;
          else
            valueType = IIOMetadataFormat.VALUE_RANGE;
        }
    }

    public Comparable getMinValue ()
    {
      return minValue;
    }

    public Comparable getMaxValue ()
    {
      return maxValue;
    }
  }

  private class NodeObjectArray extends NodeObject
  {
    protected Integer arrayMinLength;
    protected Integer arrayMaxLength;

    public NodeObjectArray (Element owner,
                            Class classType,
                            int arrayMinLength,
                            int arrayMaxLength)
    {
      super (owner, classType, false, null);
      this.arrayMinLength = new Integer (arrayMinLength);
      this.arrayMaxLength = new Integer (arrayMaxLength);
      valueType = IIOMetadataFormat.VALUE_LIST;
    }

    public Comparable getArrayMinLength ()
    {
      return arrayMinLength;
    }

    public Comparable getArrayMaxLength ()
    {
      return arrayMaxLength;
    }
  }

  /**
   * Construct a blank IIOMetadataFormatImpl with the given root name
   * and child policy.
   *
   * @param rootName the root element name
   * @param childPolicy the child policy of the root element
   *
   * @exception IllegalArgumentException if rootName is null
   * @exception IllegalArgumentException if childPolicy is
   * CHILD_POLICY_REPEAT or if childPolicy is not a CHILD_POLICY
   * constant
   */
  public IIOMetadataFormatImpl (String rootName, int childPolicy)
  {
    if (rootName == null)
      throw new IllegalArgumentException ("null argument");

    if (childPolicy < IIOMetadataFormat.CHILD_POLICY_ALL
        || childPolicy > IIOMetadataFormat.CHILD_POLICY_SOME
        || childPolicy == IIOMetadataFormat.CHILD_POLICY_REPEAT)
      throw new IllegalArgumentException ("wrong child policy");

    nodes.put (rootName, new IIOMetadataNode (rootName));
    childPolicies.put (rootName, new Integer (childPolicy));
    this.rootName = rootName;
  }

  /**
   * Construct a blank IIOMetadataFormatImpl with the given root name,
   * a child policy of CHILD_POLICY_REPEAT and the given minimum and
   * maximum limits on the number of root element children.
   *
   * @param rootName the root element name
   * @param minChildren the minimum number of children that this node
   * can have
   * @param maxChildren the maximum number of children that this node
   * can have
   *
   * @exception IllegalArgumentException if rootName is null
   * @exception IllegalArgumentException if minChildren is less than
   * zero or greater than maxChildren
   */
  public IIOMetadataFormatImpl (String rootName,
                                int minChildren,
                                int maxChildren)
  {
    if (rootName == null)
      throw new IllegalArgumentException ("null argument");

    if (minChildren < 0 || maxChildren < minChildren)
      throw new IllegalArgumentException ("invalid min or max children argument");

    nodes.put (rootName, new IIOMetadataNode (rootName));
    childPolicies.put (rootName, new Integer (IIOMetadataFormat.CHILD_POLICY_REPEAT));
    childRanges.put (rootName, new int [] { minChildren, maxChildren });
    this.rootName = rootName;
  }

  protected void addAttribute (String elementName,
                               String attrName,
                               int dataType,
                               boolean required,
                               String defaultValue)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    node.setAttributeNode (new IIOMetadataNodeAttr (node,
                                                    attrName,
                                                    dataType,
                                                    required,
                                                    defaultValue));
  }

  protected void addAttribute (String elementName,
                               String attrName,
                               int dataType,
                               boolean required,
                               String defaultValue,
                               List<String> enumeratedValues)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    node.setAttributeNode (new IIOMetadataNodeAttrEnumerated (node,
                                                              attrName,
                                                              dataType,
                                                              required,
                                                              defaultValue,
                                                              enumeratedValues));
  }

  protected void addAttribute (String elementName,
                               String attrName,
                               int dataType,
                               boolean required,
                               String defaultValue,
                               String minValue,
                               String maxValue,
                               boolean minInclusive,
                               boolean maxInclusive)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    node.setAttributeNode (new IIOMetadataNodeAttrBounded (node,
                                                           attrName,
                                                           dataType,
                                                           required,
                                                           defaultValue,
                                                           minValue,
                                                           maxValue,
                                                           minInclusive,
                                                           maxInclusive));
  }

  protected void addAttribute (String elementName,
                               String attrName,
                               int dataType,
                               boolean required,
                               int listMinLength,
                               int listMaxLength)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    node.setAttributeNode (new IIOMetadataNodeAttrList (node,
                                                        attrName,
                                                        dataType,
                                                        required,
                                                        listMinLength,
                                                        listMaxLength));
  }

  protected void addBooleanAttribute (String elementName,
                                      String attrName,
                                      boolean hasDefaultValue,
                                      boolean defaultValue)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);

    List enumeratedValues = new ArrayList();
    enumeratedValues.add ("TRUE");
    enumeratedValues.add ("FALSE");

    node.setAttributeNode (new IIOMetadataNodeAttrEnumerated (node,
                                                              attrName,
                                                              IIOMetadataFormat.DATATYPE_BOOLEAN,
                                                              hasDefaultValue,
                                                              defaultValue ? "TRUE" : "FALSE",
                                                              enumeratedValues));
  }

  protected void addChildElement (String elementName, String parentName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (parentName);

    node.appendChild (new IIOMetadataNode (elementName));
    childPolicies.put (elementName, new Integer (IIOMetadataFormat.CHILD_POLICY_REPEAT));
  }

  protected void addElement (String elementName, String parentName, int childPolicy)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (parentName);

    node.appendChild (new IIOMetadataNode (elementName));
    childPolicies.put (elementName, new Integer (childPolicy));
  }

  protected void addElement (String elementName, String parentName,
                             int minChildren, int maxChildren)
  {
    addChildElement (elementName, parentName);
    childRanges.put (elementName, new int [] { minChildren, maxChildren });
  }

  private void addNodeObject (IIOMetadataNode node, NodeObject o)
  {
    node.setUserObject (o);
  }

  private NodeObject getNodeObject (IIOMetadataNode node)
  {
    return (NodeObject) node.getUserObject ();
  }

  private void removeNodeObject (IIOMetadataNode node)
  {
    node.setUserObject (null);
  }

  protected <T> void addObjectValue (String elementName, Class<T> classType,
                                     boolean required, T defaultValue)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    addNodeObject (node, new NodeObject (node,
                                         classType,
                                         required,
                                         defaultValue));
  }

  protected <T> void addObjectValue (String elementName, Class<T> classType,
                                     boolean required, T defaultValue,
                                     List<? extends T> enumeratedValues)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    addNodeObject (node, new NodeObjectEnumerated (node,
                                                   classType,
                                                   required,
                                                   defaultValue,
                                                   enumeratedValues));
  }

  protected <T extends Object & Comparable<? super T>>
  void addObjectValue (String elementName, Class<T> classType,
                       T defaultValue,
                       Comparable<? super T> minValue,
                       Comparable<? super T> maxValue,
                       boolean minInclusive,
                       boolean maxInclusive)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    addNodeObject (node, new NodeObjectBounded (node,
                                                classType,
                                                defaultValue,
                                                minValue,
                                                maxValue,
                                                minInclusive,
                                                maxInclusive));
  }

  protected void addObjectValue (String elementName, Class<?> classType,
                                 int arrayMinLength, int arrayMaxLength)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    addNodeObject (node, new NodeObjectArray (node,
                                              classType,
                                              arrayMinLength,
                                              arrayMaxLength));
  }

  public String getRootName ()
  {
    return rootName;
  }

  protected String getResourceBaseName ()
  {
    return resourceBaseName;
  }

  public static IIOMetadataFormat getStandardFormatInstance ()
  {
    // FIXME: populate this with the standard metadata format
    return new IIOMetadataFormatImpl (standardMetadataFormatName,
                                      IIOMetadataFormat.CHILD_POLICY_ALL)
      {
        public boolean canNodeAppear (String elementName,
                                      ImageTypeSpecifier specifier)
        {
          return true;
        }
      };
  }

  public abstract boolean canNodeAppear (String elementName,
                                         ImageTypeSpecifier specifier);

  protected void removeAttribute (String elementName,
                                  String attrName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    node.removeAttribute (attrName);
  }

  protected void removeElement (String elementName)
  {
    nodes.remove (elementName);
  }

  protected void removeObjectValue (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    removeNodeObject (node);
  }

  protected void setResourceBaseName (String resourceBaseName)
  {
    this.resourceBaseName = resourceBaseName;
  }

  public int getAttributeDataType (String elementName, String attrName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) node.getAttributeNode (attrName);
    return attr.getDataType ();
  }

  public String getAttributeDefaultValue (String elementName, String attrName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) node.getAttributeNode (attrName);
    return attr.getValue();
  }

  public String getAttributeDescription (String elementName, String attrName, Locale locale)
  {
    return getDescription (elementName + "/" + attrName, locale);
  }

  public String[] getAttributeEnumerations (String elementName, String attrName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    IIOMetadataNodeAttrEnumerated attr =
      (IIOMetadataNodeAttrEnumerated) node.getAttributeNode (attrName);

    Object[] attrEnums = attr.getEnumerations();

    String[] attrNames = new String[attrEnums.length];

    for (int i = 0; i < attrEnums.length; i++)
      {
        attrNames[i] = (String) attrEnums[i];
      }

    return attrNames;
  }

  public int getAttributeListMaxLength (String elementName, String attrName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    IIOMetadataNodeAttrList attr =
      (IIOMetadataNodeAttrList) node.getAttributeNode (attrName);
    return attr.getListMaxLength();
  }

  public int getAttributeListMinLength (String elementName, String attrName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    IIOMetadataNodeAttrList attr =
      (IIOMetadataNodeAttrList) node.getAttributeNode (attrName);
    return attr.getListMinLength();
  }

  public String getAttributeMaxValue (String elementName, String attrName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    IIOMetadataNodeAttrBounded attr =
      (IIOMetadataNodeAttrBounded) node.getAttributeNode (attrName);
    return attr.getMaxValue();
  }

  public String getAttributeMinValue (String elementName, String attrName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    IIOMetadataNodeAttrBounded attr =
      (IIOMetadataNodeAttrBounded) node.getAttributeNode (attrName);
    return attr.getMinValue();
  }

  public String[] getAttributeNames (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);

    NamedNodeMap attrNodes = node.getAttributes();

    String[] attrNames = new String[attrNodes.getLength()];

    for (int i = 0; i < attrNodes.getLength(); i++)
      {
        attrNames[i] = attrNodes.item (i).getLocalName();
      }

    return attrNames;
  }

  public int getAttributeValueType (String elementName, String attrName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) node.getAttributeNode (attrName);
    return attr.getDataType();
  }

  public String[] getChildNames (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);

    NodeList childNodes = node.getChildNodes();

    String[] childNames = new String[childNodes.getLength()];

    for (int i = 0; i < childNodes.getLength(); i++)
      {
        childNames[i] = childNodes.item (i).getLocalName();
      }

    return childNames;
  }

  public int getChildPolicy (String elementName)
  {
    return ((Integer) childPolicies.get (elementName)).intValue();
  }

  private String getDescription (String resourceName, Locale locale)
  {
    if (resourceBaseName == null)
      return null;

    Locale l = locale;

    if (l == null)
      l = Locale.getDefault();

    ResourceBundle bundle = ResourceBundle.getBundle (resourceBaseName, locale);

    String desc = null;

    if (bundle == null)
      {
        try
          {
            desc = bundle.getString (resourceName);
          }
        catch (MissingResourceException e)
          {
            desc = null;
          }
      }

    return desc;
  }

  public String getElementDescription (String elementName, Locale locale)
  {
    return getDescription (elementName, locale);
  }

  public int getElementMaxChildren (String elementName)
  {
    return ((int[]) childRanges.get (elementName))[1];
  }

  public int getElementMinChildren (String elementName)
  {
    return ((int[]) childRanges.get (elementName))[0];
  }

  public int getObjectArrayMaxLength (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    return ((Integer) ((NodeObjectArray) getNodeObject (node)).getArrayMaxLength ()).intValue();
  }

  public int getObjectArrayMinLength (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    return ((Integer) ((NodeObjectArray) getNodeObject (node)).getArrayMinLength ()).intValue();
  }

  public Class<?> getObjectClass (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    return getNodeObject (node).getClassType ();
  }

  public Object getObjectDefaultValue (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    return getNodeObject (node).getDefaultValue ();
  }

  public Object[] getObjectEnumerations (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    return ((NodeObjectEnumerated) getNodeObject (node)).getEnumerations ();
  }

  public Comparable<?> getObjectMaxValue (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    return ((NodeObjectBounded) getNodeObject (node)).getMaxValue ();
  }

  public Comparable<?> getObjectMinValue (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    return ((NodeObjectBounded) getNodeObject (node)).getMinValue ();
  }

  public int getObjectValueType (String elementName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    NodeObject n = getNodeObject (node);

    if (n == null)
      return IIOMetadataFormat.VALUE_NONE;
    else
      return n.getValueType ();
  }

  public boolean isAttributeRequired (String elementName, String attrName)
  {
    IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
    return ((IIOMetadataNodeAttr) node.getAttributeNode (attrName)).isRequired();
  }
}
