/*
 * Copyright (C) 2008 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.content.res;

import com.android.ide.common.rendering.api.ArrayResourceValue;
import com.android.ide.common.rendering.api.AttrResourceValue;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceNamespace;
import com.android.ide.common.rendering.api.ResourceNamespace.Resolver;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.StyleResourceValue;
import com.android.ide.common.rendering.api.TextResourceValue;
import com.android.internal.util.XmlUtils;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.UnresolvedResourceValue;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.resources.ResourceType;
import com.android.resources.ResourceUrl;

import android.annotation.Nullable;
import android.content.res.Resources.Theme;
import android.graphics.Typeface;
import android.graphics.Typeface_Accessor;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.LayoutInflater_Delegate;
import android.view.ViewGroup.LayoutParams;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;

import static android.text.Html.FROM_HTML_MODE_COMPACT;
import static android.util.TypedValue.TYPE_ATTRIBUTE;
import static android.util.TypedValue.TYPE_DIMENSION;
import static android.util.TypedValue.TYPE_FLOAT;
import static android.util.TypedValue.TYPE_INT_BOOLEAN;
import static android.util.TypedValue.TYPE_INT_COLOR_ARGB4;
import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
import static android.util.TypedValue.TYPE_INT_COLOR_RGB4;
import static android.util.TypedValue.TYPE_INT_COLOR_RGB8;
import static android.util.TypedValue.TYPE_INT_DEC;
import static android.util.TypedValue.TYPE_INT_HEX;
import static android.util.TypedValue.TYPE_NULL;
import static android.util.TypedValue.TYPE_REFERENCE;
import static android.util.TypedValue.TYPE_STRING;
import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
import static com.android.SdkConstants.PREFIX_THEME_REF;
import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_EMPTY;
import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_NULL;
import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_UNDEFINED;

/**
 * Custom implementation of TypedArray to handle non compiled resources.
 */
public final class BridgeTypedArray extends TypedArray {

    private final Resources mBridgeResources;
    private final BridgeContext mContext;

    private final int[] mResourceId;
    private final ResourceValue[] mResourceData;
    private final String[] mNames;
    private final ResourceNamespace[] mNamespaces;

    // Contains ids that are @empty. We still store null in mResourceData for that index, since we
    // want to save on the check against empty, each time a resource value is requested.
    @Nullable
    private int[] mEmptyIds;

    public BridgeTypedArray(Resources resources, BridgeContext context, int len) {
        super(resources);
        mBridgeResources = resources;
        mContext = context;
        mResourceId = new int[len];
        mResourceData = new ResourceValue[len];
        mNames = new String[len];
        mNamespaces = new ResourceNamespace[len];
    }

    /**
     * A bridge-specific method that sets a value in the type array
     * @param index the index of the value in the TypedArray
     * @param name the name of the attribute
     * @param namespace namespace of the attribute
     * @param resourceId the reference id of this resource
     * @param value the value of the attribute
     */
    public void bridgeSetValue(int index, String name, ResourceNamespace namespace, int resourceId,
            ResourceValue value) {
        mResourceId[index] = resourceId;
        mResourceData[index] = value;
        mNames[index] = name;
        mNamespaces[index] = namespace;
    }

    /**
     * Seals the array after all calls to
     * {@link #bridgeSetValue(int, String, ResourceNamespace, int, ResourceValue)} have been done.
     * <p/>This allows to compute the list of non default values, permitting
     * {@link #getIndexCount()} to return the proper value.
     */
    public void sealArray() {
        // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt
        // first count the array size
        int count = 0;
        ArrayList<Integer> emptyIds = null;
        for (int i = 0; i < mResourceData.length; i++) {
            ResourceValue data = mResourceData[i];
            if (data != null) {
                String dataValue = data.getValue();
                if (REFERENCE_NULL.equals(dataValue) || REFERENCE_UNDEFINED.equals(dataValue)) {
                    mResourceData[i] = null;
                } else if (REFERENCE_EMPTY.equals(dataValue)) {
                    mResourceData[i] = null;
                    if (emptyIds == null) {
                        emptyIds = new ArrayList<>(4);
                    }
                    emptyIds.add(i);
                } else {
                    count++;
                }
            }
        }

        if (emptyIds != null) {
            mEmptyIds = new int[emptyIds.size()];
            for (int i = 0; i < emptyIds.size(); i++) {
                mEmptyIds[i] = emptyIds.get(i);
            }
        }

        // allocate the table with an extra to store the size
        mIndices = new int[count+1];
        mIndices[0] = count;

        // fill the array with the indices.
        int index = 1;
        for (int i = 0 ; i < mResourceData.length ; i++) {
            if (mResourceData[i] != null) {
                mIndices[index++] = i;
            }
        }
    }

    /**
     * Set the theme to be used for inflating drawables.
     */
    public void setTheme(Theme theme) {
        mTheme = theme;
    }

    /**
     * Return the number of values in this array.
     */
    @Override
    public int length() {
        return mResourceData.length;
    }

    /**
     * Return the Resources object this array was loaded from.
     */
    @Override
    public Resources getResources() {
        return mBridgeResources;
    }

    /**
     * Retrieve the styled string value for the attribute at <var>index</var>.
     *
     * @param index Index of attribute to retrieve.
     *
     * @return CharSequence holding string data.  May be styled.  Returns
     *         null if the attribute is not defined.
     */
    @Override
    public CharSequence getText(int index) {
        if (!hasValue(index)) {
            return null;
        }
        // As unfortunate as it is, it's possible to use enums with all attribute formats,
        // not just integers/enums. So, we need to search the enums always. In case
        // enums are used, the returned value is an integer.
        Integer v = resolveEnumAttribute(index);
        if (v != null) {
            return String.valueOf((int) v);
        }
        ResourceValue resourceValue = mResourceData[index];
        if (resourceValue instanceof TextResourceValue) {
            String rawString = resourceValue.getRawXmlValue();
            return Html.fromHtml(rawString, FROM_HTML_MODE_COMPACT);
        }
        return resourceValue.getValue();
    }

    /**
     * Retrieve the string value for the attribute at <var>index</var>.
     *
     * @param index Index of attribute to retrieve.
     *
     * @return String holding string data.  Any styling information is
     * removed.  Returns null if the attribute is not defined.
     */
    @Override
    public String getString(int index) {
        if (!hasValue(index)) {
            return null;
        }
        // As unfortunate as it is, it's possible to use enums with all attribute formats,
        // not just integers/enums. So, we need to search the enums always. In case
        // enums are used, the returned value is an integer.
        Integer v = resolveEnumAttribute(index);
        return v == null ? mResourceData[index].getValue() : String.valueOf((int) v);
    }

    /**
     * Retrieve the boolean value for the attribute at <var>index</var>.
     *
     * @param index Index of attribute to retrieve.
     * @param defValue Value to return if the attribute is not defined.
     *
     * @return Attribute boolean value, or defValue if not defined.
     */
    @Override
    public boolean getBoolean(int index, boolean defValue) {
        String s = getString(index);
        return s == null ? defValue : XmlUtils.convertValueToBoolean(s, defValue);

    }

    /**
     * Retrieve the integer value for the attribute at <var>index</var>.
     *
     * @param index Index of attribute to retrieve.
     * @param defValue Value to return if the attribute is not defined.
     *
     * @return Attribute int value, or defValue if not defined.
     */
    @Override
    public int getInt(int index, int defValue) {
        String s = getString(index);
        try {
            return convertValueToInt(s, defValue);
        } catch (NumberFormatException e) {
            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
                    String.format("\"%1$s\" in attribute \"%2$s\" is not a valid integer",
                            s, mNames[index]),
                    null, null);
        }
        return defValue;
    }

    /**
     * Retrieve the float value for the attribute at <var>index</var>.
     *
     * @param index Index of attribute to retrieve.
     *
     * @return Attribute float value, or defValue if not defined..
     */
    @Override
    public float getFloat(int index, float defValue) {
        String s = getString(index);
        try {
            if (s != null) {
                    return Float.parseFloat(s);
            }
        } catch (NumberFormatException e) {
            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
                    String.format("\"%1$s\" in attribute \"%2$s\" cannot be converted to float.",
                            s, mNames[index]),
                    null, null);
        }
        return defValue;
    }

    /**
     * Retrieve the color value for the attribute at <var>index</var>.  If
     * the attribute references a color resource holding a complex
     * {@link android.content.res.ColorStateList}, then the default color from
     * the set is returned.
     *
     * @param index Index of attribute to retrieve.
     * @param defValue Value to return if the attribute is not defined or
     *                 not a resource.
     *
     * @return Attribute color value, or defValue if not defined.
     */
    @Override
    public int getColor(int index, int defValue) {
        if (index < 0 || index >= mResourceData.length) {
            return defValue;
        }

        if (mResourceData[index] == null) {
            return defValue;
        }

        ColorStateList colorStateList = ResourceHelper.getColorStateList(
                mResourceData[index], mContext, mTheme);
        if (colorStateList != null) {
            return colorStateList.getDefaultColor();
        }

        return defValue;
    }

    @Override
    public ColorStateList getColorStateList(int index) {
        if (!hasValue(index)) {
            return null;
        }

        return ResourceHelper.getColorStateList(mResourceData[index], mContext, mTheme);
    }

    @Override
    public ComplexColor getComplexColor(int index) {
        if (!hasValue(index)) {
            return null;
        }

        return ResourceHelper.getComplexColor(mResourceData[index], mContext, mTheme);
    }

    /**
     * Retrieve the integer value for the attribute at <var>index</var>.
     *
     * @param index Index of attribute to retrieve.
     * @param defValue Value to return if the attribute is not defined or
     *                 not a resource.
     *
     * @return Attribute integer value, or defValue if not defined.
     */
    @Override
    public int getInteger(int index, int defValue) {
        return getInt(index, defValue);
    }

    /**
     * Retrieve a dimensional unit attribute at <var>index</var>.  Unit
     * conversions are based on the current {@link DisplayMetrics}
     * associated with the resources this {@link TypedArray} object
     * came from.
     *
     * @param index Index of attribute to retrieve.
     * @param defValue Value to return if the attribute is not defined or
     *                 not a resource.
     *
     * @return Attribute dimension value multiplied by the appropriate
     * metric, or defValue if not defined.
     *
     * @see #getDimensionPixelOffset
     * @see #getDimensionPixelSize
     */
    @Override
    public float getDimension(int index, float defValue) {
        String s = getString(index);
        if (s == null) {
            return defValue;
        }
        // Check if the value is a magic constant that doesn't require a unit.
        try {
            int i = Integer.parseInt(s);
            if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
                return i;
            }
        } catch (NumberFormatException ignored) {
            // pass
        }

        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
            return mValue.getDimension(mBridgeResources.getDisplayMetrics());
        }

        return defValue;
    }

    /**
     * Retrieve a dimensional unit attribute at <var>index</var> for use
     * as an offset in raw pixels.  This is the same as
     * {@link #getDimension}, except the returned value is converted to
     * integer pixels for you.  An offset conversion involves simply
     * truncating the base value to an integer.
     *
     * @param index Index of attribute to retrieve.
     * @param defValue Value to return if the attribute is not defined or
     *                 not a resource.
     *
     * @return Attribute dimension value multiplied by the appropriate
     * metric and truncated to integer pixels, or defValue if not defined.
     *
     * @see #getDimension
     * @see #getDimensionPixelSize
     */
    @Override
    public int getDimensionPixelOffset(int index, int defValue) {
        return (int) getDimension(index, defValue);
    }

    /**
     * Retrieve a dimensional unit attribute at <var>index</var> for use
     * as a size in raw pixels.  This is the same as
     * {@link #getDimension}, except the returned value is converted to
     * integer pixels for use as a size.  A size conversion involves
     * rounding the base value, and ensuring that a non-zero base value
     * is at least one pixel in size.
     *
     * @param index Index of attribute to retrieve.
     * @param defValue Value to return if the attribute is not defined or
     *                 not a resource.
     *
     * @return Attribute dimension value multiplied by the appropriate
     * metric and truncated to integer pixels, or defValue if not defined.
     *
     * @see #getDimension
     * @see #getDimensionPixelOffset
     */
    @Override
    public int getDimensionPixelSize(int index, int defValue) {
        try {
            return getDimension(index, null);
        } catch (RuntimeException e) {
            String s = getString(index);

            if (s != null) {
                // looks like we were unable to resolve the dimension value
                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
                        String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.",
                                s, mNames[index]),
                        null, null);
            }

            return defValue;
        }
    }

    /**
     * Special version of {@link #getDimensionPixelSize} for retrieving
     * {@link android.view.ViewGroup}'s layout_width and layout_height
     * attributes.  This is only here for performance reasons; applications
     * should use {@link #getDimensionPixelSize}.
     *
     * @param index Index of the attribute to retrieve.
     * @param name Textual name of attribute for error reporting.
     *
     * @return Attribute dimension value multiplied by the appropriate
     * metric and truncated to integer pixels.
     */
    @Override
    public int getLayoutDimension(int index, String name) {
        try {
            // this will throw an exception if not found.
            return getDimension(index, name);
        } catch (RuntimeException e) {

            if (LayoutInflater_Delegate.sIsInInclude) {
                throw new RuntimeException("Layout Dimension '" + name + "' not found.");
            }

            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
                    "You must supply a " + name + " attribute.",
                    null, null);

            return 0;
        }
    }

    @Override
    public int getLayoutDimension(int index, int defValue) {
        return getDimensionPixelSize(index, defValue);
    }

    /** @param name attribute name, used for error reporting. */
    private int getDimension(int index, @Nullable String name) {
        String s = getString(index);
        if (s == null) {
            if (name != null) {
                throw new RuntimeException("Attribute '" + name + "' not found");
            }
            throw new RuntimeException();
        }
        // Check if the value is a magic constant that doesn't require a unit.
        try {
            int i = Integer.parseInt(s);
            if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
                return i;
            }
        } catch (NumberFormatException ignored) {
            // pass
        }
        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
            float f = mValue.getDimension(mBridgeResources.getDisplayMetrics());

            final int res = (int)(f+0.5f);
            if (res != 0) return res;
            if (f == 0) return 0;
            if (f > 0) return 1;
        }

        throw new RuntimeException();
    }

    /**
     * Retrieve a fractional unit attribute at <var>index</var>.
     *
     * @param index Index of attribute to retrieve.
     * @param base The base value of this fraction.  In other words, a
     *             standard fraction is multiplied by this value.
     * @param pbase The parent base value of this fraction.  In other
     *             words, a parent fraction (nn%p) is multiplied by this
     *             value.
     * @param defValue Value to return if the attribute is not defined or
     *                 not a resource.
     *
     * @return Attribute fractional value multiplied by the appropriate
     * base value, or defValue if not defined.
     */
    @Override
    public float getFraction(int index, int base, int pbase, float defValue) {
        String value = getString(index);
        if (value == null) {
            return defValue;
        }

        if (ResourceHelper.parseFloatAttribute(mNames[index], value, mValue, false)) {
            return mValue.getFraction(base, pbase);
        }

        // looks like we were unable to resolve the fraction value
        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
                String.format(
                        "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.",
                        value, mNames[index]),
                null, null);

        return defValue;
    }

    /**
     * Retrieve the resource identifier for the attribute at
     * <var>index</var>.  Note that attribute resource as resolved when
     * the overall {@link TypedArray} object is retrieved.  As a
     * result, this function will return the resource identifier of the
     * final resource value that was found, <em>not</em> necessarily the
     * original resource that was specified by the attribute.
     *
     * @param index Index of attribute to retrieve.
     * @param defValue Value to return if the attribute is not defined or
     *                 not a resource.
     *
     * @return Attribute resource identifier, or defValue if not defined.
     */
    @Override
    public int getResourceId(int index, int defValue) {
        if (index < 0 || index >= mResourceData.length) {
            return defValue;
        }

        // get the Resource for this index
        ResourceValue resValue = mResourceData[index];

        // no data, return the default value.
        if (resValue == null) {
            return defValue;
        }

        // check if this is a style resource
        if (resValue instanceof StyleResourceValue) {
            // get the id that will represent this style.
            return mContext.getDynamicIdByStyle((StyleResourceValue)resValue);
        }

        // If the attribute was a reference to a resource, and not a declaration of an id (@+id),
        // then the xml attribute value was "resolved" which leads us to a ResourceValue with a
        // valid type, name, namespace and a potentially null value.
        if (!(resValue instanceof UnresolvedResourceValue)) {
            return mContext.getResourceId(resValue.asReference(), defValue);
        }

        // else, try to get the value, and resolve it somehow.
        String value = resValue.getValue();
        if (value == null) {
            return defValue;
        }
        value = value.trim();


        // `resValue` failed to be resolved. We extract the interesting bits and get rid of this
        // broken object. The namespace and resolver come from where the XML attribute was defined.
        ResourceNamespace contextNamespace = resValue.getNamespace();
        Resolver namespaceResolver = resValue.getNamespaceResolver();

        if (value.startsWith("#")) {
            // this looks like a color, do not try to parse it
            return defValue;
        }

        if (Typeface_Accessor.isSystemFont(value)) {
            // A system font family value, do not try to parse
            return defValue;
        }

        // Handle the @id/<name>, @+id/<name> and @android:id/<name>
        // We need to return the exact value that was compiled (from the various R classes),
        // as these values can be reused internally with calls to findViewById().
        // There's a trick with platform layouts that not use "android:" but their IDs are in
        // fact in the android.R and com.android.internal.R classes.
        // The field mPlatformFile will indicate that all IDs are to be looked up in the android R
        // classes exclusively.

        // if this is a reference to an id, find it.
        ResourceUrl resourceUrl = ResourceUrl.parse(value);
        if (resourceUrl != null) {
            if (resourceUrl.type == ResourceType.ID) {
                ResourceReference referencedId =
                        resourceUrl.resolve(contextNamespace, namespaceResolver);

                // Look for the idName in project or android R class depending on isPlatform.
                if (resourceUrl.isCreate()) {
                    int idValue;
                    if (referencedId.getNamespace() == ResourceNamespace.ANDROID) {
                        idValue = Bridge.getResourceId(ResourceType.ID, resourceUrl.name);
                    } else {
                        idValue = mContext.getLayoutlibCallback().getOrGenerateResourceId(referencedId);
                    }
                    return idValue;
                }
                // This calls the same method as in if(create), but doesn't create a dynamic id, if
                // one is not found.
                return mContext.getResourceId(referencedId, defValue);
            }
            else if (resourceUrl.type == ResourceType.AAPT) {
                ResourceReference referencedId =
                        resourceUrl.resolve(contextNamespace, namespaceResolver);
                return mContext.getLayoutlibCallback().getOrGenerateResourceId(referencedId);
            }
        }
        // not a direct id valid reference. First check if it's an enum (this is a corner case
        // for attributes that have a reference|enum type), then fallback to resolve
        // as an ID without prefix.
        Integer enumValue = resolveEnumAttribute(index);
        if (enumValue != null) {
            return enumValue;
        }

        return defValue;
    }

    @Override
    public int getThemeAttributeId(int index, int defValue) {
        // TODO: Get the right Theme Attribute ID to enable caching of the drawables.
        return defValue;
    }

    /**
     * Retrieve the Drawable for the attribute at <var>index</var>.  This
     * gets the resource ID of the selected attribute, and uses
     * {@link Resources#getDrawable Resources.getDrawable} of the owning
     * Resources object to retrieve its Drawable.
     *
     * @param index Index of attribute to retrieve.
     *
     * @return Drawable for the attribute, or null if not defined.
     */
    @Override
    @Nullable
    public Drawable getDrawable(int index) {
        if (!hasValue(index)) {
            return null;
        }

        ResourceValue value = mResourceData[index];
        return ResourceHelper.getDrawable(value, mContext, mTheme);
    }

    /**
     * Version of {@link #getDrawable(int)} that accepts an override density.
     * @hide
     */
    @Override
    @Nullable
    public Drawable getDrawableForDensity(int index, int density) {
        return getDrawable(index);
    }

    /**
     * Retrieve the Typeface for the attribute at <var>index</var>.
     * @param index Index of attribute to retrieve.
     *
     * @return Typeface for the attribute, or null if not defined.
     */
    @Override
    public Typeface getFont(int index) {
        if (!hasValue(index)) {
            return null;
        }

        ResourceValue value = mResourceData[index];
        return ResourceHelper.getFont(value, mContext, mTheme);
    }

    /**
     * Retrieve the CharSequence[] for the attribute at <var>index</var>.
     * This gets the resource ID of the selected attribute, and uses
     * {@link Resources#getTextArray Resources.getTextArray} of the owning
     * Resources object to retrieve its String[].
     *
     * @param index Index of attribute to retrieve.
     *
     * @return CharSequence[] for the attribute, or null if not defined.
     */
    @Override
    public CharSequence[] getTextArray(int index) {
        if (!hasValue(index)) {
            return null;
        }
        ResourceValue resVal = mResourceData[index];
        if (resVal instanceof ArrayResourceValue) {
            ArrayResourceValue array = (ArrayResourceValue) resVal;
            int count = array.getElementCount();
            return count >= 0 ?
                    Resources_Delegate.resolveValues(mBridgeResources, array) :
                    null;
        }
        int id = getResourceId(index, 0);
        String resIdMessage = id > 0 ? " (resource id 0x" + Integer.toHexString(id) + ')' : "";
        assert false :
                String.format("%1$s in %2$s%3$s is not a valid array resource.", resVal.getValue(),
                        mNames[index], resIdMessage);

        return new CharSequence[0];
    }

    @Override
    public int[] extractThemeAttrs() {
        // The drawables are always inflated with a Theme and we don't care about caching. So,
        // just return.
        return null;
    }

    @Override
    public int getChangingConfigurations() {
        // We don't care about caching. Any change in configuration is a fresh render. So,
        // just return.
        return 0;
    }

    /**
     * Retrieve the raw TypedValue for the attribute at <var>index</var>.
     *
     * @param index Index of attribute to retrieve.
     * @param outValue TypedValue object in which to place the attribute's
     *                 data.
     *
     * @return Returns true if the value was retrieved, else false.
     */
    @Override
    public boolean getValue(int index, TypedValue outValue) {
        // TODO: more switch cases for other types.
        outValue.type = getType(index);
        switch (outValue.type) {
            case TYPE_NULL:
                return false;
            case TYPE_STRING:
                outValue.string = getString(index);
                return true;
            case TYPE_REFERENCE:
                outValue.resourceId = mResourceId[index];
                return true;
            case TYPE_INT_COLOR_ARGB4:
            case TYPE_INT_COLOR_ARGB8:
            case TYPE_INT_COLOR_RGB4:
            case TYPE_INT_COLOR_RGB8:
                ColorStateList colorStateList = getColorStateList(index);
                if (colorStateList == null) {
                    return false;
                }
                outValue.data = colorStateList.getDefaultColor();
                return true;
            default:
                // For back-compatibility, parse as float.
                String s = getString(index);
                return s != null &&
                        ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false);
        }
    }

    @Override
    @SuppressWarnings("ResultOfMethodCallIgnored")
    public int getType(int index) {
        String value = getString(index);
        if (value == null) {
            return TYPE_NULL;
        }
        if (value.startsWith(PREFIX_RESOURCE_REF)) {
            return TYPE_REFERENCE;
        }
        if (value.startsWith(PREFIX_THEME_REF)) {
            return TYPE_ATTRIBUTE;
        }
        try {
            // Don't care about the value. Only called to check if an exception is thrown.
            convertValueToInt(value, 0);
            if (value.startsWith("0x") || value.startsWith("0X")) {
                return TYPE_INT_HEX;
            }
            // is it a color?
            if (value.startsWith("#")) {
                int length = value.length() - 1;
                if (length == 3) {  // rgb
                    return TYPE_INT_COLOR_RGB4;
                }
                if (length == 4) {  // argb
                    return TYPE_INT_COLOR_ARGB4;
                }
                if (length == 6) {  // rrggbb
                    return TYPE_INT_COLOR_RGB8;
                }
                if (length == 8) {  // aarrggbb
                    return TYPE_INT_COLOR_ARGB8;
                }
            }
            if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
                return TYPE_INT_BOOLEAN;
            }
            return TYPE_INT_DEC;
        } catch (NumberFormatException ignored) {
            try {
                Float.parseFloat(value);
                return TYPE_FLOAT;
            } catch (NumberFormatException ignore) {
            }
            // Might be a dimension.
            if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) {
                return TYPE_DIMENSION;
            }
        }
        // TODO: handle fractions.
        return TYPE_STRING;
    }

    /**
     * Determines whether there is an attribute at <var>index</var>.
     *
     * @param index Index of attribute to retrieve.
     *
     * @return True if the attribute has a value, false otherwise.
     */
    @Override
    public boolean hasValue(int index) {
        return index >= 0 && index < mResourceData.length && mResourceData[index] != null;
    }

    @Override
    public boolean hasValueOrEmpty(int index) {
        return hasValue(index) || index >= 0 && index < mResourceData.length &&
                mEmptyIds != null && Arrays.binarySearch(mEmptyIds, index) >= 0;
    }

    /**
     * Retrieve the raw TypedValue for the attribute at <var>index</var>
     * and return a temporary object holding its data.  This object is only
     * valid until the next call on to {@link TypedArray}.
     *
     * @param index Index of attribute to retrieve.
     *
     * @return Returns a TypedValue object if the attribute is defined,
     *         containing its data; otherwise returns null.  (You will not
     *         receive a TypedValue whose type is TYPE_NULL.)
     */
    @Override
    public TypedValue peekValue(int index) {
        if (index < 0 || index >= mResourceData.length) {
            return null;
        }

        if (getValue(index, mValue)) {
            return mValue;
        }

        return null;
    }

    /**
     * Returns a message about the parser state suitable for printing error messages.
     */
    @Override
    public String getPositionDescription() {
        return "<internal -- stub if needed>";
    }

    /**
     * Give back a previously retrieved TypedArray, for later re-use.
     */
    @Override
    public void recycle() {
        // pass
    }

    @Override
    public String toString() {
        return Arrays.toString(mResourceData);
    }

    /**
     * Searches for the string in the attributes (flag or enums) and returns the integer.
     * If found, it will return an integer matching the value.
     *
     * @param index Index of attribute to retrieve.
     *
     * @return Attribute int value, or null if not defined.
     */
    private Integer resolveEnumAttribute(int index) {
        // Get the map of attribute-constant -> IntegerValue
        Map<String, Integer> map = null;
        if (mNamespaces[index] == ResourceNamespace.ANDROID) {
            map = Bridge.getEnumValues(mNames[index]);
        } else {
            // get the styleable matching the resolved name
            RenderResources res = mContext.getRenderResources();
            ResourceValue attr = res.getResolvedResource(
                    ResourceReference.attr(mNamespaces[index], mNames[index]));
            if (attr instanceof AttrResourceValue) {
                map = ((AttrResourceValue) attr).getAttributeValues();
            }
        }

        if (map != null && !map.isEmpty()) {
            // Accumulator to store the value of the 1+ constants.
            int result = 0;
            boolean found = false;

            String value = mResourceData[index].getValue();
            if (!value.isEmpty()) {
                // Check if the value string is already representing an integer and return it if so.
                // Resources coming from res.apk in an AAR may have flags and enums in integer form.
                char c = value.charAt(0);
                if (Character.isDigit(c) || c == '-' || c == '+') {
                    try {
                        return convertValueToInt(value, 0);
                    } catch (NumberFormatException e) {
                        // Ignore and continue.
                    }
                }
                // Split the value in case it is a mix of several flags.
                String[] keywords = value.split("\\|");
                for (String keyword : keywords) {
                    Integer i = map.get(keyword.trim());
                    if (i != null) {
                        result |= i;
                        found = true;
                    }
                    // TODO: We should act smartly and log a warning for incorrect keywords. However,
                    // this method is currently called even if the resourceValue is not an enum.
                }
                if (found) {
                    return result;
                }
            }
        }

        return null;
    }

    /**
     * Copied from {@link XmlUtils#convertValueToInt(CharSequence, int)}, but adapted to account
     * for aapt, and the fact that host Java VM's Integer.parseInt("XXXXXXXX", 16) cannot handle
     * "XXXXXXXX" > 80000000.
     */
    private static int convertValueToInt(@Nullable String charSeq, int defValue) {
        if (null == charSeq || charSeq.isEmpty())
            return defValue;

        int sign = 1;
        int index = 0;
        int len = charSeq.length();
        int base = 10;

        if ('-' == charSeq.charAt(0)) {
            sign = -1;
            index++;
        }

        if ('0' == charSeq.charAt(index)) {
            //  Quick check for a zero by itself
            if (index == (len - 1))
                return 0;

            char c = charSeq.charAt(index + 1);

            if ('x' == c || 'X' == c) {
                index += 2;
                base = 16;
            } else {
                index++;
                // Leave the base as 10. aapt removes the preceding zero, and thus when framework
                // sees the value, it only gets the decimal value.
            }
        } else if ('#' == charSeq.charAt(index)) {
            return ResourceHelper.getColor(charSeq) * sign;
        } else if ("true".equals(charSeq) || "TRUE".equals(charSeq)) {
            return -1;
        } else if ("false".equals(charSeq) || "FALSE".equals(charSeq)) {
            return 0;
        }

        // Use Long, since we want to handle hex ints > 80000000.
        return ((int)Long.parseLong(charSeq.substring(index), base)) * sign;
    }

    static TypedArray obtain(Resources res, int len) {
        return new BridgeTypedArray(res, null, len);
    }
}
