/*
 * 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.dex.file;

import com.android.dx.rop.cst.CstType;
import com.android.dx.rop.type.StdTypeList;
import com.android.dx.rop.type.Type;
import com.android.dx.rop.type.TypeList;
import com.android.dx.util.AnnotatedOutput;
import com.android.dx.util.Hex;

/**
 * Representation of a list of class references.
 */
public final class TypeListItem extends OffsettedItem {
    /** alignment requirement */
    private static final int ALIGNMENT = 4;

    /** element size in bytes */
    private static final int ELEMENT_SIZE = 2;

    /** header size in bytes */
    private static final int HEADER_SIZE = 4;

    /** {@code non-null;} the actual list */
    private final TypeList list;

    /**
     * Constructs an instance.
     *
     * @param list {@code non-null;} the actual list
     */
    public TypeListItem(TypeList list) {
        super(ALIGNMENT, (list.size() * ELEMENT_SIZE) + HEADER_SIZE);

        this.list = list;
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return StdTypeList.hashContents(list);
    }

    /** {@inheritDoc} */
    @Override
    public ItemType itemType() {
        return ItemType.TYPE_TYPE_LIST;
    }

    /** {@inheritDoc} */
    public void addContents(DexFile file) {
        TypeIdsSection typeIds = file.getTypeIds();
        int sz = list.size();

        for (int i = 0; i < sz; i++) {
            typeIds.intern(list.getType(i));
        }
    }

    /** {@inheritDoc} */
    @Override
    public String toHuman() {
        throw new RuntimeException("unsupported");
    }

    /**
     * Gets the underlying list.
     *
     * @return {@code non-null;} the list
     */
    public TypeList getList() {
        return list;
    }

    /** {@inheritDoc} */
    @Override
    protected void writeTo0(DexFile file, AnnotatedOutput out) {
        TypeIdsSection typeIds = file.getTypeIds();
        int sz = list.size();

        if (out.annotates()) {
            out.annotate(0, offsetString() + " type_list");
            out.annotate(HEADER_SIZE, "  size: " + Hex.u4(sz));
            for (int i = 0; i < sz; i++) {
                Type one = list.getType(i);
                int idx = typeIds.indexOf(one);
                out.annotate(ELEMENT_SIZE,
                             "  " + Hex.u2(idx) + " // " + one.toHuman());
            }
        }

        out.writeInt(sz);

        for (int i = 0; i < sz; i++) {
            out.writeShort(typeIds.indexOf(list.getType(i)));
        }
    }

    /** {@inheritDoc} */
    @Override
    protected int compareTo0(OffsettedItem other) {
        TypeList thisList = this.list;
        TypeList otherList = ((TypeListItem) other).list;

        return StdTypeList.compareContents(thisList, otherList);
    }
}
