/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.util;


/**
 * A collection of attributes, as found associated with a tag in an XML
 * document.  Often you will not want to use this interface directly, instead
 * passing it to {@link android.content.res.Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
 * Resources.Theme.obtainStyledAttributes()}
 * which will take care of parsing the attributes for you.  In particular,
 * the Resources API will convert resource references (attribute values such as
 * "@string/my_label" in the original XML) to the desired type
 * for you; if you use AttributeSet directly then you will need to manually
 * check for resource references
 * (with {@link #getAttributeResourceValue(int, int)}) and do the resource
 * lookup yourself if needed.  Direct use of AttributeSet also prevents the
 * application of themes and styles when retrieving attribute values.
 * 
 * <p>This interface provides an efficient mechanism for retrieving
 * data from compiled XML files, which can be retrieved for a particular
 * XmlPullParser through {@link Xml#asAttributeSet
 * Xml.asAttributeSet()}.  Normally this will return an implementation
 * of the interface that works on top of a generic XmlPullParser, however it
 * is more useful in conjunction with compiled XML resources:
 * 
 * <pre>
 * XmlPullParser parser = resources.getXml(myResouce);
 * AttributeSet attributes = Xml.asAttributeSet(parser);</pre>
 * 
 * <p>The implementation returned here, unlike using
 * the implementation on top of a generic XmlPullParser,
 * is highly optimized by retrieving pre-computed information that was
 * generated by aapt when compiling your resources.  For example,
 * the {@link #getAttributeFloatValue(int, float)} method returns a floating
 * point number previous stored in the compiled resource instead of parsing
 * at runtime the string originally in the XML file.
 * 
 * <p>This interface also provides additional information contained in the
 * compiled XML resource that is not available in a normal XML file, such
 * as {@link #getAttributeNameResource(int)} which returns the resource
 * identifier associated with a particular XML attribute name.
 */
public interface AttributeSet {
    /**
     * Returns the number of attributes available in the set.
     * 
     * @return A positive integer, or 0 if the set is empty.
     */
    public int getAttributeCount();

    /**
     * Returns the name of the specified attribute.
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * 
     * @return A String containing the name of the attribute, or null if the
     *         attribute cannot be found.
     */
    public String getAttributeName(int index);

    /**
     * Returns the value of the specified attribute as a string representation.
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * 
     * @return A String containing the value of the attribute, or null if the
     *         attribute cannot be found.
     */
    public String getAttributeValue(int index);

    /**
     * Returns the value of the specified attribute as a string representation.
     * The lookup is performed using the attribute name.
     * 
     * @param namespace The namespace of the attribute to get the value from.
     * @param name The name of the attribute to get the value from.
     * 
     * @return A String containing the value of the attribute, or null if the
     *         attribute cannot be found.
     */
    public String getAttributeValue(String namespace, String name);

    /**
     * Returns a description of the current position of the attribute set.
     * For instance, if the attribute set is loaded from an XML document,
     * the position description could indicate the current line number.
     * 
     * @return A string representation of the current position in the set,
     *         may be null.
     */
    public String getPositionDescription();

    /**
     * Return the resource ID associated with the given attribute name.  This
     * will be the identifier for an attribute resource, which can be used by
     * styles.  Returns 0 if there is no resource associated with this
     * attribute.
     * 
     * <p>Note that this is different than {@link #getAttributeResourceValue}
     * in that it returns a resource identifier for the attribute name; the
     * other method returns this attribute's value as a resource identifier.
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * 
     * @return The resource identifier, 0 if none.
     */
    public int getAttributeNameResource(int index);

    /**
     * Return the index of the value of 'attribute' in the list 'options'.
     *
     * @param namespace Namespace of attribute to retrieve. 
     * @param attribute Name of attribute to retrieve.
     * @param options List of strings whose values we are checking against.
     * @param defaultValue Value returned if attribute doesn't exist or no
     *                     match is found.
     * 
     * @return Index in to 'options' or defaultValue.
     */
    public int getAttributeListValue(String namespace, String attribute,
                                     String[] options, int defaultValue);

    /**
     * Return the boolean value of 'attribute'.
     * 
     * @param namespace Namespace of attribute to retrieve.
     * @param attribute The attribute to retrieve.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public boolean getAttributeBooleanValue(String namespace, String attribute,
                                            boolean defaultValue);

    /**
     * Return the value of 'attribute' as a resource identifier.
     * 
     * <p>Note that this is different than {@link #getAttributeNameResource}
     * in that it returns a the value contained in this attribute as a
     * resource identifier (i.e., a value originally of the form
     * "@package:type/resource"); the other method returns a resource
     * identifier that identifies the name of the attribute.
     * 
     * @param namespace Namespace of attribute to retrieve.
     * @param attribute The attribute to retrieve.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public int getAttributeResourceValue(String namespace, String attribute,
                                         int defaultValue);

    /**
     * Return the integer value of 'attribute'.
     * 
     * @param namespace Namespace of attribute to retrieve.
     * @param attribute The attribute to retrieve.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public int getAttributeIntValue(String namespace, String attribute,
                                    int defaultValue);

    /**
     * Return the boolean value of 'attribute' that is formatted as an
     * unsigned value.  In particular, the formats 0xn...n and #n...n are
     * handled.
     * 
     * @param namespace Namespace of attribute to retrieve.
     * @param attribute The attribute to retrieve.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public int getAttributeUnsignedIntValue(String namespace, String attribute,
                                            int defaultValue);

    /**
     * Return the float value of 'attribute'.
     * 
     * @param namespace Namespace of attribute to retrieve.
     * @param attribute The attribute to retrieve.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public float getAttributeFloatValue(String namespace, String attribute,
                                        float defaultValue);

    /**
     * Return the index of the value of attribute at 'index' in the list 
     * 'options'. 
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * @param options List of strings whose values we are checking against.
     * @param defaultValue Value returned if attribute doesn't exist or no
     *                     match is found.
     * 
     * @return Index in to 'options' or defaultValue.
     */
    public int getAttributeListValue(int index, String[] options, int defaultValue);

    /**
     * Return the boolean value of attribute at 'index'.
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public boolean getAttributeBooleanValue(int index, boolean defaultValue);

    /**
     * Return the value of attribute at 'index' as a resource identifier.
     * 
     * <p>Note that this is different than {@link #getAttributeNameResource}
     * in that it returns a the value contained in this attribute as a
     * resource identifier (i.e., a value originally of the form
     * "@package:type/resource"); the other method returns a resource
     * identifier that identifies the name of the attribute.
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public int getAttributeResourceValue(int index, int defaultValue);

    /**
     * Return the integer value of attribute at 'index'.
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public int getAttributeIntValue(int index, int defaultValue);

    /**
     * Return the integer value of attribute at 'index' that is formatted as an
     * unsigned value.  In particular, the formats 0xn...n and #n...n are
     * handled.
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public int getAttributeUnsignedIntValue(int index, int defaultValue);

    /**
     * Return the float value of attribute at 'index'.
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public float getAttributeFloatValue(int index, float defaultValue);

    /**
     * Return the value of the "id" attribute or null if there is not one.
     * Equivalent to getAttributeValue(null, "id").
     * 
     * @return The id attribute's value or null.
     */
    public String getIdAttribute();

    /**
     * Return the value of the "class" attribute or null if there is not one.
     * Equivalent to getAttributeValue(null, "class").
     * 
     * @return The class attribute's value or null.
     */
    public String getClassAttribute();

    /**
     * Return the integer value of the "id" attribute or defaultValue if there
     * is none.
     * Equivalent to getAttributeResourceValue(null, "id", defaultValue);
     *
     * @param defaultValue What to return if the "id" attribute isn't found.
     * @return int Resulting value.
     */
    public int getIdAttributeResourceValue(int defaultValue);

    /**

     * Return the value of the "style" attribute or 0 if there is not one.
     * Equivalent to getAttributeResourceValue(null, "style").
     * 
     * @return The style attribute's resource identifier or 0.
     */
    public int getStyleAttribute();
}
