/*
 * This file is part of artnet4j.
 * 
 * Copyright 2009 Karsten Schmidt (PostSpectacular Ltd.)
 * 
 * artnet4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * artnet4j is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with artnet4j. If not, see <http://www.gnu.org/licenses/>.
 */

package de.ctdo.bunti.artnet;

public class ByteUtils {
    private static final int BYTE_OVERFLOW = 256;
    private static final int BYTE_MAX = 0xff;
    private static final int BIT_PER_BYTE = 8;
    private static final int ONE_BYTE_OFFSET = 1;

    private final byte[] data;

    public ByteUtils(byte[] data) {
        this.data = data;
    }
    
    public static final int byteToUint(byte b) {
        return (b < 0 ? BYTE_OVERFLOW + b : b);
    }

    public static final byte uintToByte(int i) {
        return (byte)(i & BYTE_MAX);
    }

    public final byte[] getBytes() {
        return data;
    }

    public final int getInt16(int offset) {
        return (byteToUint(data[offset]) << BIT_PER_BYTE) | byteToUint(data[offset + 1]);
    }

    public final int getInt16LE(int offset) {
        return (byteToUint(data[offset + ONE_BYTE_OFFSET]) << BIT_PER_BYTE) | byteToUint(data[offset]);
    }

    public final int getInt8(int offset) {
        return byteToUint(data[offset]);
    }

    public final int getLength() {
        return data.length;
    }

    public final void setByteChunk(byte[] buffer, int offset, int len) {
        System.arraycopy(buffer, 0, data, offset, len);
    }

    public final void setInt16(int val, int offset) {
        data[offset] = (byte) (val >> BIT_PER_BYTE & BYTE_MAX);
        data[offset + ONE_BYTE_OFFSET] = (byte) (val & BYTE_MAX);
    }

    public final void setInt16LE(int val, int offset) {
        data[offset] = (byte) (val & BYTE_MAX);
        data[offset + ONE_BYTE_OFFSET] = (byte) (val >> BIT_PER_BYTE & BYTE_MAX);
    }

    public final void setInt8(int val, int offset) {
        data[offset] = (byte) (val & BYTE_MAX);
    }

}
