/*
 * Copyright (C) 2014 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.support.v4.util;

/**
 * CircularIntArray is a circular integer array data structure that provides O(1) random read, O(1)
 * prepend and O(1) append. The CircularIntArray automatically grows its capacity when number of
 * added integers is over its capacity.
 */
public final class CircularIntArray
{
    private int[] mElements;
    private int mHead;
    private int mTail;
    private int mCapacityBitmask;

    private void doubleCapacity() {
        int n = mElements.length;
        int r = n - mHead;
        int newCapacity = n << 1;
        if (newCapacity < 0) {
            throw new RuntimeException("Max array capacity exceeded");
        }
        int[] a = new int[newCapacity];
        System.arraycopy(mElements, mHead, a, 0, r);
        System.arraycopy(mElements, 0, a, r, mHead);
        mElements = a;
        mHead = 0;
        mTail = n;
        mCapacityBitmask = newCapacity - 1;
    }

    /**
     * Creates a circular array with default capacity.
     */
    public CircularIntArray() {
        this(8);
    }

    /**
     * Creates a circular array with capacity for at least {@code minCapacity}
     * elements.
     *
     * @param minCapacity the minimum capacity, between 1 and 2^30 inclusive
     */
    public CircularIntArray(int minCapacity) {
        if (minCapacity < 1) {
            throw new IllegalArgumentException("capacity must be >= 1");
        }
        if (minCapacity > (2 << 29)) {
            throw new IllegalArgumentException("capacity must be <= 2^30");
        }

        // If minCapacity isn't a power of 2, round up to the next highest
        // power of 2.
        final int arrayCapacity;
        if (Integer.bitCount(minCapacity) != 1) {
            arrayCapacity = Integer.highestOneBit(minCapacity - 1) << 1;
        } else {
            arrayCapacity = minCapacity;
        }

        mCapacityBitmask = arrayCapacity - 1;
        mElements = new int[arrayCapacity];
    }

    /**
     * Add an integer in front of the CircularIntArray.
     * @param e  Integer to add.
     */
    public void addFirst(int e) {
        mHead = (mHead - 1) & mCapacityBitmask;
        mElements[mHead] = e;
        if (mHead == mTail) {
            doubleCapacity();
        }
    }

    /**
     * Add an integer at end of the CircularIntArray.
     * @param e  Integer to add.
     */
    public void addLast(int e) {
        mElements[mTail] = e;
        mTail = (mTail + 1) & mCapacityBitmask;
        if (mTail == mHead) {
            doubleCapacity();
        }
    }

    /**
     * Remove first integer from front of the CircularIntArray and return it.
     * @return  The integer removed.
     * @throws ArrayIndexOutOfBoundsException if CircularIntArray is empty.
     */
    public int popFirst() {
        if (mHead == mTail) throw new ArrayIndexOutOfBoundsException();
        int result = mElements[mHead];
        mHead = (mHead + 1) & mCapacityBitmask;
        return result;
    }

    /**
     * Remove last integer from end of the CircularIntArray and return it.
     * @return  The integer removed.
     * @throws ArrayIndexOutOfBoundsException if CircularIntArray is empty.
     */
    public int popLast() {
        if (mHead == mTail) throw new ArrayIndexOutOfBoundsException();
        int t = (mTail - 1) & mCapacityBitmask;
        int result = mElements[t];
        mTail = t;
        return result;
    }

    /**
     * Remove all integers from the CircularIntArray.
     */
    public void clear() {
        mTail = mHead;
    }

    /**
     * Remove multiple integers from front of the CircularIntArray, ignore when numOfElements
     * is less than or equals to 0.
     * @param numOfElements  Number of integers to remove.
     * @throws ArrayIndexOutOfBoundsException if numOfElements is larger than
     *         {@link #size()}
     */
    public void removeFromStart(int numOfElements) {
        if (numOfElements <= 0) {
            return;
        }
        if (numOfElements > size()) {
            throw new ArrayIndexOutOfBoundsException();
        }
        mHead = (mHead + numOfElements) & mCapacityBitmask;
    }

    /**
     * Remove multiple elements from end of the CircularIntArray, ignore when numOfElements
     * is less than or equals to 0.
     * @param numOfElements  Number of integers to remove.
     * @throws ArrayIndexOutOfBoundsException if numOfElements is larger than
     *         {@link #size()}
     */
    public void removeFromEnd(int numOfElements) {
        if (numOfElements <= 0) {
            return;
        }
        if (numOfElements > size()) {
            throw new ArrayIndexOutOfBoundsException();
        }
        mTail = (mTail - numOfElements) & mCapacityBitmask;
    }

    /**
     * Get first integer of the CircularIntArray.
     * @return The first integer.
     * @throws {@link ArrayIndexOutOfBoundsException} if CircularIntArray is empty.
     */
    public int getFirst() {
        if (mHead == mTail) throw new ArrayIndexOutOfBoundsException();
        return mElements[mHead];
    }

    /**
     * Get last integer of the CircularIntArray.
     * @return The last integer.
     * @throws {@link ArrayIndexOutOfBoundsException} if CircularIntArray is empty.
     */
    public int getLast() {
        if (mHead == mTail) throw new ArrayIndexOutOfBoundsException();
        return mElements[(mTail - 1) & mCapacityBitmask];
    }

    /**
     * Get nth (0 <= n <= size()-1) integer of the CircularIntArray.
     * @param n  The zero based element index in the CircularIntArray.
     * @return The nth integer.
     * @throws {@link ArrayIndexOutOfBoundsException} if n < 0 or n >= size().
     */
    public int get(int n) {
        if (n < 0 || n >= size()) throw new ArrayIndexOutOfBoundsException();
        return mElements[(mHead + n) & mCapacityBitmask];
    }

    /**
     * Get number of integers in the CircularIntArray.
     * @return Number of integers in the CircularIntArray.
     */
    public int size() {
        return (mTail - mHead) & mCapacityBitmask;
    }

    /**
     * Return true if size() is 0.
     * @return true if size() is 0.
     */
    public boolean isEmpty() {
        return mHead == mTail;
    }

}
