/*
 * Copyright 2015 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Run this file with the `java_sample.sh` script.

import MyGame.Sample.Color
import MyGame.Sample.Equipment
import MyGame.Sample.Monster
import MyGame.Sample.Vec3
import MyGame.Sample.Weapon

import com.google.flatbuffers.FlatBufferBuilder

@kotlin.ExperimentalUnsignedTypes
class SampleBinary {

  companion object {
    // Example how to use FlatBuffers to create and read binary buffers.
    @JvmStatic
    fun main(args: Array<String>) {
        val builder = FlatBufferBuilder(0)

        // Create some weapons for our Monster ('Sword' and 'Axe').
        val weaponOneName = builder.createString("Sword")
        val weaponOneDamage: Short = 3
        val weaponTwoName = builder.createString("Axe")
        val weaponTwoDamage: Short = 5

        // Use the `createWeapon()` helper function to create the weapons, since we set every field.
        val weaps = IntArray(2)
        weaps[0] = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage)
        weaps[1] = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage)

        // Serialize the FlatBuffer data.
        val name = builder.createString("Orc")
        val treasure = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).asUByteArray()
        val inv = Monster.createInventoryVector(builder, treasure)
        val weapons = Monster.createWeaponsVector(builder, weaps)
        val pos = Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)

        Monster.startMonster(builder)
        Monster.addPos(builder, pos)
        Monster.addName(builder, name)
        Monster.addColor(builder, Color.Red)
        Monster.addHp(builder, 300.toShort())
        Monster.addInventory(builder, inv)
        Monster.addWeapons(builder, weapons)
        Monster.addEquippedType(builder, Equipment.Weapon)
        Monster.addEquipped(builder, weaps[1])
        val orc = Monster.endMonster(builder)

        builder.finish(orc) // You could also call `Monster.finishMonsterBuffer(builder, orc);`.

        // We now have a FlatBuffer that can be stored on disk or sent over a network.

        // ...Code to store to disk or send over a network goes here...

        // Instead, we are going to access it right away, as if we just received it.

        val buf = builder.dataBuffer()

        // Get access to the root:
        val monster = Monster.getRootAsMonster(buf)

        // Note: We did not set the `mana` field explicitly, so we get back the default value.
        assert(monster.mana == 150.toShort())
        assert(monster.hp == 300.toShort())
        assert(monster.name.equals("Orc"))
        assert(monster.color == Color.Red)
        assert(monster.pos!!.x == 1.0f)
        assert(monster.pos!!.y == 2.0f)
        assert(monster.pos!!.z == 3.0f)

        // Get and test the `inventory` FlatBuffer `vector`.
        for (i in 0 until monster.inventoryLength) {
            assert(monster.inventory(i) == i.toUByte())
        }

        // Get and test the `weapons` FlatBuffer `vector` of `table`s.
        val expectedWeaponNames = arrayOf("Sword", "Axe")
        val expectedWeaponDamages = intArrayOf(3, 5)
        for (i in 0 until monster.weaponsLength) {
            assert(monster.weapons(i)!!.name.equals(expectedWeaponNames[i]))
            assert(monster.weapons(i)!!.damage.toInt() == expectedWeaponDamages[i])
        }

        // Get and test the `equipped` FlatBuffer `union`.
        assert(monster.equippedType == Equipment.Weapon)
        val equipped = monster.equipped(Weapon()) as Weapon?
        assert(equipped!!.name.equals("Axe"))
        assert(equipped.damage == 5.toShort())

        println("The FlatBuffer was successfully created and verified!")
    }
  }
}
