package com.eddbc;

import android.util.Log;

import java.util.ArrayList;
import java.util.Arrays;

public class ByteArrayBuilder {
    private ArrayList<Byte> data = new ArrayList<Byte>();

    private byte[] array() {
        Byte[] b = data.toArray(new Byte[0]);
        return unbox(b);
    }



    // This does the final shrinking.
    public byte[] toArray() {
        byte[] ar =  Arrays.copyOf(array(), length());
        return ar;
    }

    public void append(byte[] newData) {
        byte[] array = addByteArrays(array(), newData);
        setData(array);
    }

    public void setData(byte[] d) {
        setData(box(d));
    }

    public void setData(Byte[] d){
        data = new ArrayList<Byte>(Arrays.asList(d));
    }
    
    public int length() {
        return array().length;
    }

    /**
     * Returns a sub-sequence from the start index to the end index
     * @param start start index
     * @param end end index
     * @return sub-sequence of bytes
     */
    public byte[] section(int start, int end) {
        return Arrays.copyOfRange(array(), start, end);
    }

    /**
     * Delete data between start and end indexes
     * @param start start index
     * @param end end index
     */
    public void delete(int start, int end) {
        byte[] section1;
        byte[] section2;

        if(start == 0){
            section1 = new byte[0];
        } else {
            section1 = Arrays.copyOfRange(array(), 0, start-1);
        }

        if(end >= length()-1) {
            section2 = new byte[0];
        } else {
            section2 = Arrays.copyOfRange(array(), end+1, length()-1);
        }

        byte[] result = addByteArrays(section1, section2);
        setData(result);
    }





    /**
     *
     * @param b1 First ArrayBuffer
     * @param b2 Second ArrayBuffer
     * @return Resulting combined ArrayBuffer
     */
    private byte[] addByteArrays(byte[] b1, byte[] b2){
        // create a destination array that is the size of the two arrays
        byte[] r = new byte[b1.length + b2.length ];

        // copy b1 into start of destination (from pos 0, copy b1.length Bytes)
        System.arraycopy(b1, 0, r, 0, b1.length);

        // copy b2 into end of destination (from pos b1.length, copy b2.length Bytes)
        System.arraycopy(b2, 0, r, b1.length, b2.length);

        return r;
    }

    private Byte[] box(byte[] bytes){
        Byte[] objs = new Byte[bytes.length];

        int i=0;
        for(byte b: bytes) {
            objs[i++] = b;
        }

        return objs;
    }

    private byte[] unbox(Byte[] objs) {
        byte[] bytes = new byte[objs.length];

        int i=0;
        for(Byte b: objs)
            bytes[i++] = b;

        return bytes;
    }
}
