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

import com.android.dx.cf.code.ByteBlock;

/**
 * A list of labeled items, allowing easy lookup by label.
 */
public class LabeledList extends FixedSizeList {

    /**
     * Sparse array indexed by label to FixedSizeList index.
     * -1 = invalid label.
     */
    private final IntList labelToIndex;

    /** @inheritDoc */
    public LabeledList(int size) {
        super(size);

        labelToIndex = new IntList(size);
    }

    /**
     * Constructs a new instance that is a copy of the old instance.
     *
     * @param old instance to copy
     */
    protected LabeledList(LabeledList old) {
        super(old.size());
        labelToIndex = old.labelToIndex.mutableCopy();

        int sz = old.size();

        for (int i = 0; i < sz; i++) {
            Object one = old.get0(i);
            if (one != null) {
                set0(i, one);
            }
        }
    }

    /**
     * Gets the maximum label (exclusive) of any block added to this instance.
     *
     * @return {@code >= 0;} the maximum label
     */
    public int getMaxLabel() {
        int sz = labelToIndex.size();

        // Gobble any deleted labels that may be at the end...
        int i;
        for (i = sz - 1; (i >= 0) && (labelToIndex.get(i) < 0); i--)
            ;

        int newSize = i+1;

        labelToIndex.shrink(newSize);

        return newSize;
    }

    /**
     * Removes a label from the label-to-index mapping
     * @param oldLabel label to remove
     */
    protected void removeLabel(int oldLabel) {
        labelToIndex.set(oldLabel, -1);
    }

    /**
     * Adds a label and index to the label-to-index mapping
     * @param label new label
     * @param index index of block.
     */
    protected void addLabelIndex(int label, int index) {
        int origSz = labelToIndex.size();

        for (int i = 0; i <= (label - origSz); i++) {
            labelToIndex.add(-1);
        }

        labelToIndex.set(label, index);
    }

    /**
     * Gets the index of the first item in the list with the given
     * label, if any.
     *
     * @param label {@code >= 0;} the label to look for
     * @return {@code >= -1;} the index of the so-labelled item, or {@code -1}
     * if none is found
     */
    public int indexOfLabel(int label) {
        if (label >= labelToIndex.size()) {
            return -1;
        } else {
            return labelToIndex.get(label);
        }
    }

    /** @inheritDoc */
    @Override
    public void shrinkToFit() {
        super.shrinkToFit();

        rebuildLabelToIndex();
    }

    /**
     * Rebuilds the label-to-index mapping after a shrinkToFit().
     * Note: assumes that the labels that are in the list are the same
     * although the indicies may have changed.
     */
    protected void rebuildLabelToIndex() {
        int szItems = size();

        for (int i = 0; i < szItems; i++) {
            LabeledItem li = (LabeledItem)get0(i);

            if (li != null) {
                labelToIndex.set(li.getLabel(), i);
            }
        }
    }

    /**
     * Sets the element at the given index.
     *
     * @param n {@code >= 0, < size();} which element
     * @param item {@code null-ok;} the value to store
     */
    protected void set(int n, LabeledItem item) {
        LabeledItem old = (LabeledItem) getOrNull0(n);

        set0(n, item);

        if (old != null) {
            removeLabel(old.getLabel());
        }

        if (item != null) {
            addLabelIndex(item.getLabel(), n);
        }        
    }
}
