/*
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.lists;

import java.util.List;
import net.ranides.assira.collection.IntCollection;
import net.ranides.assira.collection.arrays.IntArrays;
import net.ranides.assira.collection.iterators.IntListIterator;

/**
 * Specialization of List for integer types.
 * Avoids unecessary boxing and unboxing operations.
 *
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 */
public interface IntList extends IntCollection, List<Integer> {

    /**
     * Empty list
     */
    IntList EMPTY = IntArrays.asList();

    /**
     * Creates new IntList with provided values
     * @param values values
     * @return list
     */
    static IntList of(int...values) {
        return new IntArrayList(values);
    }

    /**
     * non-generic version of {@link #add(int, Object)}
     * @param index index
     * @param k k
     */
    void add(int index, int k);

    /**
     * non-generic version of {@link #addAll(java.util.Collection)}
     * @param list list
     * @return bool
     */
    boolean addAll(IntList list);

    /**
     * non-generic version of {@link #addAll(int, java.util.Collection)}
     * @param index index
     * @param values values
     * @return bool
     */
    boolean addAll(int index, IntCollection values);

    /**
     * non-generic version of {@link #addAll(int, java.util.Collection)}
     * @param index index
     * @param values values
     * @return bool
     */
    boolean addAll(int index, IntList values);

    /**
     * Adds elements to this type-specific list using optimized system calls.
     *
     * @param index the index at which to add elements.
     * @param array the array containing the elements.
     */
    void addElements(int index, int[] array);

    /**
     * Adds elements to this type-specific list using optimized system calls.
     *
     * @param index the index at which to add elements.
     * @param array the array containing the elements.
     * @param offset the offset of the first element to add.
     * @param length the number of elements to add.
     */
    void addElements(int index, int[] array, int offset, int length);

    /**
     * Copies element of this type-specific list into the given array using
     * optimized system calls.
     *
     * @param from the start index (inclusive).
     * @param target the destination array.
     * @param offset the offset into the destination array where to store the
    first element copied.
     * @param length the number of elements to be copied.
     */
    void getElements(int from, int[] target, int offset, int length);

    /**
     * non-generic version of {@link #get(int)}
     * @param index index
     * @return int
     */
    int getInt(int index);

    /**
     * Returns the hash code for this list, which is identical to
     * {@link java.util.List#hashCode()}.
     *
     * @return the hash code for this list.
     */
    @Override
    int hashCode();

    /**
     * non-generic version of {@link #indexOf(Object)}
     * @param k k
     * @return int
     */
    int indexOf(int k);

    @Override
    IntListIterator iterator();

    /**
     * non-generic version of {@link #lastIndexOf(Object)}
     * @param k k
     * @return int
     */
    int lastIndexOf(int k);

    @Override
    IntListIterator listIterator();

    @Override
    IntListIterator listIterator(int index);

    /**
     * non-generic version of {@link java.util.Stack#peek()}
     * @return int
     */
    int peekInt();

    /**
     * non-generic generalization of {@link java.util.Stack#peek()}
     * It takes element at "i" position counting backwards from the end.
     * peek(0) is equivalent to peek().
     *
     * @param i i
     * @return int
     */
    int peekInt(int i);

    /**
     * non-generic version of {@link java.util.Stack#pop()}
     * @return int
     */
    int popInt();

    /**
     * non-generic version of {@link java.util.Stack#push(Object)}
     * @param o o
     */
    void push(int o);

    /**
     * Removes elements of this type-specific list using optimized system calls.
     *
     * @param from the start index (inclusive).
     * @param to the end index (exclusive).
     */
    void removeElements(int from, int to);

    /**
     * non-generic version of {@link #remove(Object)}
     * @param index index
     * @return int
     */
    int removeInt(int index);

    /**
     * non-generic version of {@link #set(int, Object)}
     * @param index index
     * @param k k
     * @return int
     */
    int set(int index, int k);

    @Override
    IntList subList(int from, int to);

}
