// 
// Decompiled by Procyon v0.6.0
// 

package com.google.protobuf;

import java.util.Collection;
import java.util.Arrays;
import java.util.RandomAccess;

final class FloatArrayList extends AbstractProtobufList<Float> implements Internal.FloatList, RandomAccess, PrimitiveNonBoxingCollection
{
    private static final float[] EMPTY_ARRAY;
    private static final FloatArrayList EMPTY_LIST;
    private float[] array;
    private int size;
    
    public static FloatArrayList emptyList() {
        return FloatArrayList.EMPTY_LIST;
    }
    
    FloatArrayList() {
        this(FloatArrayList.EMPTY_ARRAY, 0, true);
    }
    
    private FloatArrayList(final float[] other, final int size, final boolean isMutable) {
        super(isMutable);
        this.array = other;
        this.size = size;
    }
    
    FloatArrayList(final FloatArrayList other, final boolean isMutable) {
        this((other.size == 0) ? FloatArrayList.EMPTY_ARRAY : Arrays.copyOf(other.array, other.size), other.size, isMutable);
    }
    
    @Override
    protected void removeRange(final int fromIndex, final int toIndex) {
        this.ensureIsMutable();
        if (toIndex < fromIndex) {
            throw new IndexOutOfBoundsException("toIndex < fromIndex");
        }
        System.arraycopy(this.array, toIndex, this.array, fromIndex, this.size - toIndex);
        this.size -= toIndex - fromIndex;
        ++this.modCount;
    }
    
    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof FloatArrayList)) {
            return super.equals(o);
        }
        final FloatArrayList other = (FloatArrayList)o;
        if (this.size != other.size) {
            return false;
        }
        final float[] arr = other.array;
        for (int i = 0; i < this.size; ++i) {
            if (Float.floatToIntBits(this.array[i]) != Float.floatToIntBits(arr[i])) {
                return false;
            }
        }
        return true;
    }
    
    @Override
    public int hashCode() {
        int result = 1;
        for (int i = 0; i < this.size; ++i) {
            result = 31 * result + Float.floatToIntBits(this.array[i]);
        }
        return result;
    }
    
    @Override
    public Internal.FloatList mutableCopyWithCapacity(final int capacity) {
        if (capacity < this.size) {
            throw new IllegalArgumentException();
        }
        final float[] newArray = (capacity == 0) ? FloatArrayList.EMPTY_ARRAY : Arrays.copyOf(this.array, capacity);
        return new FloatArrayList(newArray, this.size, true);
    }
    
    @Override
    public Float get(final int index) {
        return this.getFloat(index);
    }
    
    @Override
    public float getFloat(final int index) {
        this.ensureIndexInRange(index);
        return this.array[index];
    }
    
    @Override
    public int indexOf(final Object element) {
        if (!(element instanceof Float)) {
            return -1;
        }
        final float unboxedElement = (float)element;
        for (int numElems = this.size(), i = 0; i < numElems; ++i) {
            if (this.array[i] == unboxedElement) {
                return i;
            }
        }
        return -1;
    }
    
    @Override
    public boolean contains(final Object element) {
        return this.indexOf(element) != -1;
    }
    
    @Override
    public int size() {
        return this.size;
    }
    
    @Override
    public Float set(final int index, final Float element) {
        return this.setFloat(index, element);
    }
    
    @Override
    public float setFloat(final int index, final float element) {
        this.ensureIsMutable();
        this.ensureIndexInRange(index);
        final float previousValue = this.array[index];
        this.array[index] = element;
        return previousValue;
    }
    
    @Override
    public boolean add(final Float element) {
        this.addFloat(element);
        return true;
    }
    
    @Override
    public void add(final int index, final Float element) {
        this.addFloat(index, element);
    }
    
    @Override
    public void addFloat(final float element) {
        this.ensureIsMutable();
        if (this.size == this.array.length) {
            final int length = growSize(this.array.length);
            final float[] newArray = new float[length];
            System.arraycopy(this.array, 0, newArray, 0, this.size);
            this.array = newArray;
        }
        this.array[this.size++] = element;
    }
    
    private void addFloat(final int index, final float element) {
        this.ensureIsMutable();
        if (index < 0 || index > this.size) {
            throw new IndexOutOfBoundsException(this.makeOutOfBoundsExceptionMessage(index));
        }
        if (this.size < this.array.length) {
            System.arraycopy(this.array, index, this.array, index + 1, this.size - index);
        }
        else {
            final int length = growSize(this.array.length);
            final float[] newArray = new float[length];
            System.arraycopy(this.array, 0, newArray, 0, index);
            System.arraycopy(this.array, index, newArray, index + 1, this.size - index);
            this.array = newArray;
        }
        this.array[index] = element;
        ++this.size;
        ++this.modCount;
    }
    
    @Override
    public boolean addAll(final Collection<? extends Float> collection) {
        this.ensureIsMutable();
        Internal.checkNotNull(collection);
        if (!(collection instanceof FloatArrayList)) {
            return super.addAll(collection);
        }
        final FloatArrayList list = (FloatArrayList)collection;
        if (list.size == 0) {
            return false;
        }
        final int overflow = Integer.MAX_VALUE - this.size;
        if (overflow < list.size) {
            throw new OutOfMemoryError();
        }
        final int newSize = this.size + list.size;
        if (newSize > this.array.length) {
            this.array = Arrays.copyOf(this.array, newSize);
        }
        System.arraycopy(list.array, 0, this.array, this.size, list.size);
        this.size = newSize;
        ++this.modCount;
        return true;
    }
    
    @Override
    public Float remove(final int index) {
        this.ensureIsMutable();
        this.ensureIndexInRange(index);
        final float value = this.array[index];
        if (index < this.size - 1) {
            System.arraycopy(this.array, index + 1, this.array, index, this.size - index - 1);
        }
        --this.size;
        ++this.modCount;
        return value;
    }
    
    void ensureCapacity(final int minCapacity) {
        if (minCapacity <= this.array.length) {
            return;
        }
        if (this.array.length == 0) {
            this.array = new float[Math.max(minCapacity, 10)];
            return;
        }
        int n;
        for (n = this.array.length; n < minCapacity; n = growSize(n)) {}
        this.array = Arrays.copyOf(this.array, n);
    }
    
    private static int growSize(final int previousSize) {
        return Math.max(previousSize * 3 / 2 + 1, 10);
    }
    
    private void ensureIndexInRange(final int index) {
        if (index < 0 || index >= this.size) {
            throw new IndexOutOfBoundsException(this.makeOutOfBoundsExceptionMessage(index));
        }
    }
    
    private String makeOutOfBoundsExceptionMessage(final int index) {
        return "Index:" + index + ", Size:" + this.size;
    }
    
    static {
        EMPTY_ARRAY = new float[0];
        EMPTY_LIST = new FloatArrayList(FloatArrayList.EMPTY_ARRAY, 0, false);
    }
}
