/*
 * Copyright (C) 2007 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 com.android.dx.cf.attrib;

import com.android.dx.rop.cst.CstString;
import com.android.dx.rop.cst.CstType;
import com.android.dx.util.FixedSizeList;

/**
 * List of "inner class" entries, which are the contents of
 * {@code InnerClasses} attributes.
 */
public final class InnerClassList extends FixedSizeList {
    /**
     * Constructs an instance.
     *
     * @param count the number of elements to be in the list of inner classes
     */
    public InnerClassList(int count) {
        super(count);
    }

    /**
     * Gets the indicated item.
     *
     * @param n {@code >= 0;} which item
     * @return {@code null-ok;} the indicated item
     */
    public Item get(int n) {
        return (Item) get0(n);
    }

    /**
     * Sets the item at the given index.
     *
     * @param n {@code >= 0, < size();} which class
     * @param innerClass {@code non-null;} class this item refers to
     * @param outerClass {@code null-ok;} outer class that this class is a
     * member of, if any
     * @param innerName {@code null-ok;} original simple name of this class,
     * if not anonymous
     * @param accessFlags original declared access flags
     */
    public void set(int n, CstType innerClass, CstType outerClass,
                    CstString innerName, int accessFlags) {
        set0(n, new Item(innerClass, outerClass, innerName, accessFlags));
    }

    /**
     * Item in an inner classes list.
     */
    public static class Item {
        /** {@code non-null;} class this item refers to */
        private final CstType innerClass;

        /** {@code null-ok;} outer class that this class is a member of, if any */
        private final CstType outerClass;

        /** {@code null-ok;} original simple name of this class, if not anonymous */
        private final CstString innerName;

        /** original declared access flags */
        private final int accessFlags;

        /**
         * Constructs an instance.
         *
         * @param innerClass {@code non-null;} class this item refers to
         * @param outerClass {@code null-ok;} outer class that this class is a
         * member of, if any
         * @param innerName {@code null-ok;} original simple name of this
         * class, if not anonymous
         * @param accessFlags original declared access flags
         */
        public Item(CstType innerClass, CstType outerClass,
                    CstString innerName, int accessFlags) {
            if (innerClass == null) {
                throw new NullPointerException("innerClass == null");
            }

            this.innerClass = innerClass;
            this.outerClass = outerClass;
            this.innerName = innerName;
            this.accessFlags = accessFlags;
        }

        /**
         * Gets the class this item refers to.
         *
         * @return {@code non-null;} the class
         */
        public CstType getInnerClass() {
            return innerClass;
        }

        /**
         * Gets the outer class that this item's class is a member of, if any.
         *
         * @return {@code null-ok;} the class
         */
        public CstType getOuterClass() {
            return outerClass;
        }

        /**
         * Gets the original name of this item's class, if not anonymous.
         *
         * @return {@code null-ok;} the name
         */
        public CstString getInnerName() {
            return innerName;
        }

        /**
         * Gets the original declared access flags.
         *
         * @return the access flags
         */
        public int getAccessFlags() {
            return accessFlags;
        }
    }
}
