// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.protocol.io;

import javax.annotation.Nonnull;
import io.netty.buffer.ByteBuf;

public final class VarInt
{
    private VarInt() {
    }
    
    public static void write(@Nonnull final ByteBuf buf, int value) {
        if (value < 0) {
            throw new IllegalArgumentException("VarInt cannot encode negative values: " + value);
        }
        while ((value & 0xFFFFFF80) != 0x0) {
            buf.writeByte((value & 0x7F) | 0x80);
            value >>>= 7;
        }
        buf.writeByte(value);
    }
    
    public static int read(@Nonnull final ByteBuf buf) {
        int value = 0;
        int shift = 0;
        while (true) {
            final byte b = buf.readByte();
            value |= (b & 0x7F) << shift;
            if ((b & 0x80) == 0x0) {
                return value;
            }
            shift += 7;
            if (shift > 28) {
                throw new ProtocolException("VarInt exceeds maximum length (5 bytes)");
            }
        }
    }
    
    public static int peek(@Nonnull final ByteBuf buf, final int index) {
        int value = 0;
        int shift = 0;
        int pos = index;
        while (pos < buf.writerIndex()) {
            final byte b = buf.getByte(pos++);
            value |= (b & 0x7F) << shift;
            if ((b & 0x80) == 0x0) {
                return value;
            }
            shift += 7;
            if (shift > 28) {
                return -1;
            }
        }
        return -1;
    }
    
    public static int length(@Nonnull final ByteBuf buf, final int index) {
        int pos = index;
        while (pos < buf.writerIndex()) {
            if ((buf.getByte(pos++) & 0x80) == 0x0) {
                return pos - index;
            }
            if (pos - index > 5) {
                return -1;
            }
        }
        return -1;
    }
    
    public static int size(final int value) {
        if ((value & 0xFFFFFF80) == 0x0) {
            return 1;
        }
        if ((value & 0xFFFFC000) == 0x0) {
            return 2;
        }
        if ((value & 0xFFE00000) == 0x0) {
            return 3;
        }
        if ((value & 0xF0000000) == 0x0) {
            return 4;
        }
        return 5;
    }
}
