/*
 * The Broad Institute
 * SOFTWARE COPYRIGHT NOTICE AGREEMENT
 * This is copyright (2007-2008) by the Broad Institute/Massachusetts Institute 
 * of Technology.  It is licensed to You under the Gnu Public 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.opensource.org/licenses/gpl-2.0.php
 *
 * This software is supplied without any warranty or guaranteed support
 * whatsoever. Neither the Broad Institute nor MIT can be responsible for its
 * use, misuse, or functionality.
*/

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.broad.igv.data;

/**
 *
 * @author jrobinso
 */
public class IntArrayList {
    
    static final int maxGrowIncrement = Integer.MAX_VALUE / 10;
    
    private int sz = 0;
    private int [] values;
    
    public IntArrayList(int maxSize) {
        values = new int[maxSize];
    }
    
    public int size() {
        return sz;
    }
    
    public void add(int v) {
        if(sz >= values.length) {
            grow();
        }
        values[sz] = v;
        sz++;
    }
    
    public void addAll(int [] array) {
        if(values.length - sz < array.length) {
            grow(array.length);
        }
        System.arraycopy(array, 0, values, sz, array.length);
        sz += array.length;
    }
    
    public int [] toArray() {
        trim();
        return values;
    }
    
    public int get(int idx) {
        if(idx >= sz) {
            throw new IndexOutOfBoundsException("Index out of bounds.  Size = " + sz + " Index = " + idx);
        }
        else {
            return values[idx];
        }
    }
    
    private void grow() {
        grow((int)   (Math.max(1000, 0.2 * values.length)));
    }
    
    private void grow(int increment) {
        if(values.length >= Integer.MAX_VALUE) {
            throw new RuntimeException("Maximum array size exceeded");
        }
        int newSize = Math.min(Integer.MAX_VALUE, values.length + increment);
        resize(newSize);
        
    }

    private void resize(int newSize) {
        int[] tmp = new int[newSize];
        System.arraycopy(values, 0, tmp, 0, Math.min(tmp.length, values.length));
        values = tmp;
    }
    
    private void trim() {
        resize(sz);
    }

    public void reorder(int [] indeces) {
        if(indeces.length != sz) {
            throw new IllegalArgumentException("Index array length not equal to size");
        }
        int [] reorderedValues = new int[sz];
        for(int i=0; i<sz; i++) {
            reorderedValues[i] = values[indeces[i]];
        }
        values = reorderedValues;
    }

}
