#!/usr/bin/python
# 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.

# To run this file, use `python_sample.sh`.

# Append paths to the `flatbuffers` and `MyGame` modules. This is necessary
# to facilitate executing this script in the `samples` folder, and to root
# folder (where it gets placed when using `cmake`).
import os
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), '../python'))

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

# Example of how to use FlatBuffers to create and read binary buffers.


def main():
  builder = flatbuffers.Builder(0)

  # Create some weapons for our Monster ('Sword' and 'Axe').
  weapon_one = builder.CreateString('Sword')
  weapon_two = builder.CreateString('Axe')

  MyGame.Sample.Weapon.WeaponStart(builder)
  MyGame.Sample.Weapon.WeaponAddName(builder, weapon_one)
  MyGame.Sample.Weapon.WeaponAddDamage(builder, 3)
  sword = MyGame.Sample.Weapon.WeaponEnd(builder)

  MyGame.Sample.Weapon.WeaponStart(builder)
  MyGame.Sample.Weapon.WeaponAddName(builder, weapon_two)
  MyGame.Sample.Weapon.WeaponAddDamage(builder, 5)
  axe = MyGame.Sample.Weapon.WeaponEnd(builder)

  # Serialize the FlatBuffer data.
  name = builder.CreateString('Orc')

  MyGame.Sample.Monster.MonsterStartInventoryVector(builder, 10)
  # Note: Since we prepend the bytes, this loop iterates in reverse order.
  for i in reversed(range(0, 10)):
    builder.PrependByte(i)
  inv = builder.EndVector()

  MyGame.Sample.Monster.MonsterStartWeaponsVector(builder, 2)
  # Note: Since we prepend the data, prepend the weapons in reverse order.
  builder.PrependUOffsetTRelative(axe)
  builder.PrependUOffsetTRelative(sword)
  weapons = builder.EndVector()

  pos = MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)

  MyGame.Sample.Monster.MonsterStart(builder)
  MyGame.Sample.Monster.MonsterAddPos(builder, pos)
  MyGame.Sample.Monster.MonsterAddHp(builder, 300)
  MyGame.Sample.Monster.MonsterAddName(builder, name)
  MyGame.Sample.Monster.MonsterAddInventory(builder, inv)
  MyGame.Sample.Monster.MonsterAddColor(
      builder, MyGame.Sample.Color.Color().Red
  )
  MyGame.Sample.Monster.MonsterAddWeapons(builder, weapons)
  MyGame.Sample.Monster.MonsterAddEquippedType(
      builder, MyGame.Sample.Equipment.Equipment().Weapon
  )
  MyGame.Sample.Monster.MonsterAddEquipped(builder, axe)
  orc = MyGame.Sample.Monster.MonsterEnd(builder)

  builder.Finish(orc)

  # We now have a FlatBuffer that we could store on disk or send over a network.

  # ...Saving to file or sending over a network code goes here...

  # Instead, we are going to access this buffer right away (as if we just
  # received it).

  buf = builder.Output()

  # Note: We use `0` for the offset here, since we got the data using the
  # `builder.Output()` method. This simulates the data you would store/receive
  # in your FlatBuffer. If you wanted to read from the `builder.Bytes` directly,
  # you would need to pass in the offset of `builder.Head()`, as the builder
  # actually constructs the buffer backwards.
  monster = MyGame.Sample.Monster.Monster.GetRootAsMonster(buf, 0)

  # Note: We did not set the `Mana` field explicitly, so we get a default value.
  assert monster.Mana() == 150
  assert monster.Hp() == 300
  assert monster.Name() == b'Orc'
  assert monster.Color() == MyGame.Sample.Color.Color().Red
  assert monster.Pos().X() == 1.0
  assert monster.Pos().Y() == 2.0
  assert monster.Pos().Z() == 3.0

  # Get and test the `inventory` FlatBuffer `vector`.
  for i in range(monster.InventoryLength()):
    assert monster.Inventory(i) == i

  # Get and test the `weapons` FlatBuffer `vector` of `table`s.
  expected_weapon_names = [b'Sword', b'Axe']
  expected_weapon_damages = [3, 5]
  for i in range(monster.WeaponsLength()):
    assert monster.Weapons(i).Name() == expected_weapon_names[i]
    assert monster.Weapons(i).Damage() == expected_weapon_damages[i]

  # Get and test the `equipped` FlatBuffer `union`.
  assert monster.EquippedType() == MyGame.Sample.Equipment.Equipment().Weapon

  # An example of how you can appropriately convert the table depending on the
  # FlatBuffer `union` type. You could add `elif` and `else` clauses to handle
  # the other FlatBuffer `union` types for this field.
  if monster.EquippedType() == MyGame.Sample.Equipment.Equipment().Weapon:
    # `monster.Equipped()` returns a `flatbuffers.Table`, which can be used
    # to initialize a `MyGame.Sample.Weapon.Weapon()`, in this case.
    union_weapon = MyGame.Sample.Weapon.Weapon()
    union_weapon.Init(monster.Equipped().Bytes, monster.Equipped().Pos)

    assert union_weapon.Name() == b'Axe'
    assert union_weapon.Damage() == 5

  print('The FlatBuffer was successfully created and verified!')


if __name__ == '__main__':
  main()
