/*
 * Copyright 2023 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
 */

#pragma once

#include <ox/std/array.hpp>

#include <nostalgia/gfx/tilesheet.hpp>

namespace jasper::world {

namespace ngfx = nostalgia::gfx;

using CollisionMap = uint32_t;

enum class ObjectType: uint8_t {
	None         = 0,
	NormalBgTile = 1,
	NormalSprite = 2,
	Person       = 3,
};

using ObjectId = uint32_t;

struct WorldObject {
	static constexpr auto TypeName = "net.drinkingtea.jasper.world.WorldObject";
	static constexpr auto TypeVersion = 1;
	ObjectId id{};
	ox::String name;
	uint16_t intervalMs{};
	uint8_t palBank{};
	ngfx::SubSheetId subsheetId{};
	CollisionMap collisionMap{};
	uint8_t frames{};
	uint8_t objectType{};
	uint8_t ext1{};
	uint8_t ext2{};
	uint8_t ext3{};
};

OX_MODEL_BEGIN(WorldObject)
	OX_MODEL_FIELD(id)
	OX_MODEL_FIELD(name)
	OX_MODEL_FIELD_RENAME(intervalMs, interval_ms)
	OX_MODEL_FIELD_RENAME(palBank, pal_bank)
	OX_MODEL_FIELD_RENAME(subsheetId, subsheet_id)
	OX_MODEL_FIELD_RENAME(collisionMap, collision_map)
	OX_MODEL_FIELD(frames)
	OX_MODEL_FIELD_RENAME(objectType, object_type)
	OX_MODEL_FIELD(ext1)
	OX_MODEL_FIELD(ext2)
	OX_MODEL_FIELD(ext3)
OX_MODEL_END()

enum class TerrainType: uint8_t {
	NormalLand,
	NormalWater,
};

void bgObjSetTerrainType(WorldObject &obj, TerrainType t) noexcept;

[[nodiscard]]
TerrainType bgObjGetTerrainType(WorldObject &obj) noexcept;

struct WorldObjectSet {
	static constexpr auto TypeName = "net.drinkingtea.jasper.world.WorldObjectSet";
	static constexpr auto TypeVersion = 1;
	static constexpr auto Preloadable = true;
	// index used to assign unique IDs to objects in the set
	ObjectId objIdIdx = 0;
	ox::FileAddress tilesheet;
	ox::Vector<ox::FileAddress> palettes;
	ox::Vector<WorldObject> objects;
};

OX_MODEL_BEGIN(WorldObjectSet)
	OX_MODEL_FIELD_RENAME(objIdIdx, obj_id_idx)
	OX_MODEL_FIELD(tilesheet)
	OX_MODEL_FIELD(palettes)
	OX_MODEL_FIELD(objects)
OX_MODEL_END()

}
