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

/**
 *
 * @author ranides
 */
public final class ByteArrayUtils {

    private ByteArrayUtils() {
        // utility class
    }

    /**
     * Tworzy nową tablicę o podanym rozmiarze, inicjalizując wszystkie elementy
     * podaną wartością.
     * @param size
     * @param value
     * @return
     */
    public static byte[] make(int size, byte value) {
        byte[] content = new byte[size];
        if(value!=0) { for(int i=0; i<size; i++) { content[i] = value; } }
        return content;
    }

    /**
     * Usuwa z tablicy pierwszy element, przesuwając wszystkie pozostałe o 1
     * pozycję w lewo. Jako wynik zwraca wartość usuniętego elementu. Uwaga:
     * rozmiar tablicy nie jest zmieniany, wartość ostatniego elementu też - co
     * oznacza, że wartość ostatniego elementu jest duplikowana.
     * @param values
     * @return
     */
    public static byte shift(byte[] values) {
        if(values == null || values.length==0) { throw new EmptyCollectionException(); }
        byte value = values[0];
        for(int i=1,n=values.length; i<n; i++) { values[i-1] = values[i]; } //NOPMD
        return value;
    }

    /**
     * Usuwa z tablicy ostatni element, przesuwając wszystkie pozostałe o 1
     * pozycję w prawo. Jako wynik zwraca wartość usuniętego elementu. Uwaga:
     * rozmiar tablicy nie jest zmieniany, wartość pierwszego elementu też - co
     * oznacza, że wartość pierwszego elementu jest duplikowana.
     * @param values
     * @return
     */
    public static byte unshift(byte[] values) {
        if(values == null || values.length==0) { throw new EmptyCollectionException(); }
        byte value = values[values.length-1];
        for(int i=values.length-1; i>0; i--) { values[i] = values[i-1]; } //NOPMD
        return value;
    }

    /**
     * Tworzy nową tablicę i kopiuje do niej zawartość obu tablic.
     * @param first
     * @param second
     * @return
     */
    public static byte[] concat(byte[] first, byte[] second) {
        byte[] result = new byte[ first.length + second.length ];
        System.arraycopy(first, 0, result, 0, first.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }

    /**
     * Porównuje zawartość tablic, i zwraca {@code true}, jeśli są równe.
     * @param array1
     * @param array2
     * @return
     */
    public static boolean equals(byte[] array1, byte[] array2) {
        if (array1==array2) {
            return true;
        }
        if (array1==null || array2==null) {
            return false;
        }
        int n = array1.length;
        if (array2.length != n) {
            return false;
        }
        for (int i=0; i<n; i++) {
            if (array1[i] != array2[i]) { return false; }
        }
        return true;
    }

    /**
     * Porównuje pierwsze {@code size} elementów w tablicach, i zwraca {@code true},
     * jeśli są równe.
     * @param size
     * @param array1
     * @param array2
     * @return
     */
    public static boolean equals(int size, byte[] array1, byte[] array2) {
        if (array1==array2) {
            return true;
        }
        if (array1==null || array2==null) {
            return false;
        }
        if(array1.length != array2.length && (array1.length < size || array2.length < size) ) {
            return false;
        }
        for (int i=0, n=Math.min(array1.length, size); i<n; i++) {
            if (array1[i] != array2[i]) { return false; }
        }
        return true;
    }

}
