/**
 * =========================================
 * LibXML : a free Java layouting library
 * =========================================
 *
 * Project Info:  http://reporting.pentaho.org/libxml/
 *
 * (C) Copyright 2006-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
 *
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this
 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
 * in the United States and other countries.]
 *
 *
 * ------------
 * $Id: FixNamespaceUriAttributes.java 3518 2007-10-16 10:26:53Z tmorgner $
 * ------------
 * (C) Copyright 2006-2007, by Pentaho Corporation.
 */
package org.jfree.xmlns.parser;

import org.xml.sax.Attributes;

/**
 * Creation-Date: 10.04.2006, 11:13:10
 *
 * @author Thomas Morgner
 */
public class FixNamespaceUriAttributes implements Attributes
{
  private Attributes attributes;
  private String defaultNSUri;

  public FixNamespaceUriAttributes(final String defaultNSUri,
                                   final Attributes attributes)
  {
    this.attributes = attributes;
    this.defaultNSUri = defaultNSUri;
  }

  /**
   * Return the number of attributes in the list.
   * <p/>
   * <p>Once you know the number of attributes, you can iterate through the
   * list.</p>
   *
   * @return The number of attributes in the list.
   * @see #getURI(int)
   * @see #getLocalName(int)
   * @see #getQName(int)
   * @see #getType(int)
   * @see #getValue(int)
   */
  public int getLength()
  {
    return attributes.getLength();
  }

  /**
   * Look up an attribute's Namespace URI by index.
   *
   * @param index The attribute index (zero-based).
   * @return The Namespace URI, or the empty string if none is available, or
   *         null if the index is out of range.
   * @see #getLength
   */
  public String getURI(final int index)
  {
    final String uri = attributes.getURI(index);
    if (uri == null || "".equals(uri))
    {
      return defaultNSUri;
    }
    return uri;
  }

  /**
   * Look up an attribute's local name by index.
   *
   * @param index The attribute index (zero-based).
   * @return The local name, or the empty string if Namespace processing is not
   *         being performed, or null if the index is out of range.
   * @see #getLength
   */
  public String getLocalName(final int index)
  {
    final String name = attributes.getLocalName(index);
    if (name == null || "".equals(name))
    {
      return attributes.getQName(index);
    }
    return name;
  }

  /**
   * Look up an attribute's XML qualified (prefixed) name by index.
   *
   * @param index The attribute index (zero-based).
   * @return The XML qualified name, or the empty string if none is available,
   *         or null if the index is out of range.
   * @see #getLength
   */
  public String getQName(final int index)
  {
    return attributes.getQName(index);
  }

  /**
   * Look up an attribute's type by index.
   * <p/>
   * <p>The attribute type is one of the strings "CDATA", "ID", "IDREF",
   * "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES", or "NOTATION"
   * (always in upper case).</p>
   * <p/>
   * <p>If the parser has not read a declaration for the attribute, or if the
   * parser does not report attribute types, then it must return the value
   * "CDATA" as stated in the XML 1.0 Recommendation (clause 3.3.3,
   * "Attribute-Value Normalization").</p>
   * <p/>
   * <p>For an enumerated attribute that is not a notation, the parser will
   * report the type as "NMTOKEN".</p>
   *
   * @param index The attribute index (zero-based).
   * @return The attribute's type as a string, or null if the index is out of
   *         range.
   * @see #getLength
   */
  public String getType(final int index)
  {
    return attributes.getType(index);
  }

  /**
   * Look up an attribute's value by index.
   * <p/>
   * <p>If the attribute value is a list of tokens (IDREFS, ENTITIES, or
   * NMTOKENS), the tokens will be concatenated into a single string with each
   * token separated by a single space.</p>
   *
   * @param index The attribute index (zero-based).
   * @return The attribute's value as a string, or null if the index is out of
   *         range.
   * @see #getLength
   */
  public String getValue(final int index)
  {
    return attributes.getValue(index);
  }

  /**
   * Look up the index of an attribute by Namespace name.
   *
   * @param uri       The Namespace URI, or the empty string if the name has no
   *                  Namespace URI.
   * @param localName The attribute's local name.
   * @return The index of the attribute, or -1 if it does not appear in the
   *         list.
   */
  public int getIndex(final String uri, final String localName)
  {
    final int idx = attributes.getIndex(uri, localName);
    if (idx >= 0)
    {
      return idx;
    }
    if (defaultNSUri.equals(uri))
    {
      return attributes.getIndex("", localName);
    }
    return -1;
  }

  /**
   * Look up the index of an attribute by XML qualified (prefixed) name.
   *
   * @param qName The qualified (prefixed) name.
   * @return The index of the attribute, or -1 if it does not appear in the
   *         list.
   */
  public int getIndex(final String qName)
  {
    return attributes.getIndex(qName);
  }

  /**
   * Look up an attribute's type by Namespace name.
   * <p/>
   * <p>See {@link #getType(int) getType(int)} for a description of the possible
   * types.</p>
   *
   * @param uri       The Namespace URI, or the empty String if the name has no
   *                  Namespace URI.
   * @param localName The local name of the attribute.
   * @return The attribute type as a string, or null if the attribute is not in
   *         the list or if Namespace processing is not being performed.
   */
  public String getType(final String uri, final String localName)
  {
    final String type = attributes.getType(uri, localName);
    if (type != null)
    {
      return type;
    }
    if (defaultNSUri.equals(uri))
    {
      return attributes.getType("", localName);
    }
    return null;

  }

  /**
   * Look up an attribute's type by XML qualified (prefixed) name.
   * <p/>
   * <p>See {@link #getType(int) getType(int)} for a description of the possible
   * types.</p>
   *
   * @param qName The XML qualified name.
   * @return The attribute type as a string, or null if the attribute is not in
   *         the list or if qualified names are not available.
   */
  public String getType(final String qName)
  {
    return attributes.getType(qName);
  }

  /**
   * Look up an attribute's value by Namespace name.
   * <p/>
   * <p>See {@link #getValue(int) getValue(int)} for a description of the
   * possible values.</p>
   *
   * @param uri       The Namespace URI, or the empty String if the name has no
   *                  Namespace URI.
   * @param localName The local name of the attribute.
   * @return The attribute value as a string, or null if the attribute is not in
   *         the list.
   */
  public String getValue(final String uri, final String localName)
  {
    final String value = attributes.getValue(uri, localName);
    if (value != null)
    {
      return value;
    }
    if (defaultNSUri.equals(uri))
    {
      return attributes.getValue("", localName);
    }
    return null;

  }

  /**
   * Look up an attribute's value by XML qualified (prefixed) name.
   * <p/>
   * <p>See {@link #getValue(int) getValue(int)} for a description of the
   * possible values.</p>
   *
   * @param qName The XML qualified name.
   * @return The attribute value as a string, or null if the attribute is not in
   *         the list or if qualified names are not available.
   */
  public String getValue(final String qName)
  {
    return attributes.getValue(qName);
  }
}
