// automatically generated by the FlatBuffers compiler, do not modify

package MyGame.Example

import java.nio.*
import kotlin.math.sign
import com.google.flatbuffers.*

@Suppress("unused")
class Stat : Table() {

    fun __init(_i: Int, _bb: ByteBuffer)  {
        __reset(_i, _bb)
    }
    fun __assign(_i: Int, _bb: ByteBuffer) : Stat {
        __init(_i, _bb)
        return this
    }
    val id : String?
        get() {
            val o = __offset(4)
            return if (o != 0) __string(o + bb_pos) else null
        }
    val idAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(4, 1)
    fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1)
    val val_ : Long
        get() {
            val o = __offset(6)
            return if(o != 0) bb.getLong(o + bb_pos) else 0L
        }
    fun mutateVal_(val_: Long) : Boolean {
        val o = __offset(6)
        return if (o != 0) {
            bb.putLong(o + bb_pos, val_)
            true
        } else {
            false
        }
    }
    val count : UShort
        get() {
            val o = __offset(8)
            return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
        }
    fun mutateCount(count: UShort) : Boolean {
        val o = __offset(8)
        return if (o != 0) {
            bb.putShort(o + bb_pos, count.toShort())
            true
        } else {
            false
        }
    }
    override fun keysCompare(o1: Int, o2: Int, _bb: ByteBuffer) : Int {
        val val_1 = _bb.getShort(__offset(8, o1, _bb))
        val val_2 = _bb.getShort(__offset(8, o2, _bb))
        return (val_1 - val_2).sign
    }
    companion object {
        fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
        fun getRootAsStat(_bb: ByteBuffer): Stat = getRootAsStat(_bb, Stat())
        fun getRootAsStat(_bb: ByteBuffer, obj: Stat): Stat {
            _bb.order(ByteOrder.LITTLE_ENDIAN)
            return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
        }
        fun createStat(builder: FlatBufferBuilder, idOffset: Int, val_: Long, count: UShort) : Int {
            builder.startTable(3)
            addVal_(builder, val_)
            addId(builder, idOffset)
            addCount(builder, count)
            return endStat(builder)
        }
        fun startStat(builder: FlatBufferBuilder) = builder.startTable(3)
        fun addId(builder: FlatBufferBuilder, id: Int) = builder.addOffset(0, id, 0)
        fun addVal_(builder: FlatBufferBuilder, val_: Long) = builder.addLong(1, val_, 0L)
        fun addCount(builder: FlatBufferBuilder, count: UShort)  {
            builder.addShort(count.toShort())
            builder.slot(2)
        }
        fun endStat(builder: FlatBufferBuilder) : Int {
            val o = builder.endTable()
            return o
        }
        fun __lookup_by_key(obj: Stat?, vectorLocation: Int, key: UShort, bb: ByteBuffer) : Stat? {
            var span = bb.getInt(vectorLocation - 4)
            var start = 0
            while (span != 0) {
                var middle = span / 2
                val tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb)
                val value = bb.getShort(__offset(8, bb.capacity() - tableOffset, bb)).toUShort()
                val comp = value.compareTo(key)
                when {
                    comp > 0 -> span = middle
                    comp < 0 -> {
                        middle++
                        start += middle
                        span -= middle
                    }
                    else -> {
                        return (obj ?: Stat()).__assign(tableOffset, bb)
                    }
                }
            }
            return null
        }
    }
}
