#include <ultra64.h>
#include "sm64.h"
#include "behavior_data.h"
#include "model_ids.h"
#include "seq_ids.h"
#include "dialog_ids.h"
#include "segment_symbols.h"
#include "level_commands.h"
#include "game/level_update.h"
#include "levels/scripts.h"
#include "actors/common1.h"
#include "make_const_nonconst.h"

#include "areas/1/custom.model.inc.h"

#include "levels/bits/header.h"
#include "levels/bbh/header.h"

extern u8 _bits_segment_ESegmentRomStart[];
extern u8 _bits_segment_ESegmentRomEnd[];

const LevelScript level_bits_entry[] = {
INIT_LEVEL(),
LOAD_MIO0(0x07, _bbh_segment_7SegmentRomStart, _bbh_segment_7SegmentRomEnd),
LOAD_RAW(0x1A, _bbhSegmentRomStart, _bbhSegmentRomEnd),
LOAD_RAW(0x0E, _bits_segment_ESegmentRomStart, _bits_segment_ESegmentRomEnd),
LOAD_MIO0(0xA, _bitfs_skybox_mio0SegmentRomStart, _bitfs_skybox_mio0SegmentRomEnd),
LOAD_MIO0(8, _common0_mio0SegmentRomStart, _common0_mio0SegmentRomEnd),
LOAD_RAW(15, _common0_geoSegmentRomStart, _common0_geoSegmentRomEnd),
LOAD_MIO0(5, _group1_mio0SegmentRomStart, _group1_mio0SegmentRomEnd),
LOAD_RAW(12, _group1_geoSegmentRomStart, _group1_geoSegmentRomEnd),
LOAD_MIO0(6, _group17_mio0SegmentRomStart, _group17_mio0SegmentRomEnd),
LOAD_RAW(13, _group17_geoSegmentRomStart, _group17_geoSegmentRomEnd),
ALLOC_LEVEL_POOL(),
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
// Level Specific Models
LOAD_MODEL_FROM_GEO(MODEL_BBH_HAUNTED_DOOR,           haunted_door_geo),
LOAD_MODEL_FROM_GEO(MODEL_BBH_STAIRCASE_STEP,         geo_bbh_0005B0),
LOAD_MODEL_FROM_GEO(MODEL_BBH_TILTING_FLOOR_PLATFORM, geo_bbh_0005C8),
LOAD_MODEL_FROM_GEO(MODEL_BBH_TUMBLING_PLATFORM,      geo_bbh_0005E0),
LOAD_MODEL_FROM_GEO(MODEL_BBH_TUMBLING_PLATFORM_PART, geo_bbh_0005F8),
LOAD_MODEL_FROM_GEO(MODEL_BBH_MOVING_BOOKSHELF,       geo_bbh_000610),
LOAD_MODEL_FROM_GEO(MODEL_BBH_MESH_ELEVATOR,          geo_bbh_000628),
LOAD_MODEL_FROM_GEO(MODEL_BBH_MERRY_GO_ROUND,         geo_bbh_000640),
LOAD_MODEL_FROM_GEO(MODEL_BBH_WOODEN_TOMB,            geo_bbh_000658),
// Unspecified Models
LOAD_MODEL_FROM_GEO(22,  warp_pipe_geo),
LOAD_MODEL_FROM_GEO(23,  bubbly_tree_geo),
LOAD_MODEL_FROM_GEO(24,  spiky_tree_geo),
LOAD_MODEL_FROM_GEO(25,  snow_tree_geo),
LOAD_MODEL_FROM_GEO(27,  palm_tree_geo),
LOAD_MODEL_FROM_GEO(31,  metal_door_geo),
LOAD_MODEL_FROM_GEO(32,  hazy_maze_door_geo),
LOAD_MODEL_FROM_GEO(34,  castle_door_0_star_geo),
LOAD_MODEL_FROM_GEO(35,  castle_door_1_star_geo),
LOAD_MODEL_FROM_GEO(36,  castle_door_3_stars_geo),
LOAD_MODEL_FROM_GEO(37,  key_door_geo),
LOAD_MODEL_FROM_GEO(38,  castle_door_geo),
// LOAD_MODEL_FROM_DL(132, 0x08025f08, 4),
// LOAD_MODEL_FROM_DL(158, 0x0302c8a0, 4),
// LOAD_MODEL_FROM_DL(159, 0x0302bcd0, 4),
// LOAD_MODEL_FROM_DL(161, 0x0301cb00, 4),
// LOAD_MODEL_FROM_DL(164, 0x04032a18, 4),
// LOAD_MODEL_FROM_DL(201, 0x080048e0, 4),
// LOAD_MODEL_FROM_DL(218, 0x08024bb8, 4),
JUMP_LINK(script_func_global_1),
JUMP_LINK(script_func_global_2),
JUMP_LINK(script_func_global_18),
JUMP_LINK(local_area_bits_1_),
FREE_LEVEL_POOL(),
MARIO_POS(/* area */ 1, /* yaw */ 0, /* pos */ 0, 0, 0),
CALL(/*arg*/ 0, /*func*/ lvl_init_or_update),
CALL_LOOP(/*arg*/ 1, /*func*/ lvl_init_or_update),
CLEAR_LEVEL(),
SLEEP_BEFORE_EXIT(/*frames*/ 1),
EXIT(),
};

const LevelScript local_area_bits_1_[] = {
AREA(1, Geo_bits_1_0x1b2d520),
TERRAIN(col_bits_1_0xe03b250),
SET_BACKGROUND_MUSIC(0, 56),
TERRAIN_TYPE(0),
JUMP_LINK(local_objects_bits_1_),
JUMP_LINK(local_warps_bits_1_),
END_AREA(),
RETURN()
};

const LevelScript local_objects_bits_1_[] = {
OBJECT_WITH_ACTS(0, -4000, 1024, 0, 0, 90, 0, 0xa0000,  bhvSpinAirborneWarp, 31),
OBJECT_WITH_ACTS(137, 3500, 3000, 3125, 0, 0, 0, 0x10000,  bhvExclamationBox, 31),
OBJECT_WITH_ACTS(122, -4000, 8000, -3750, 0, 0, 0, 0x1000000,  bhvStar, 31),
OBJECT_WITH_ACTS(122, 2500, 6425, -4500, 0, 0, 0, 0x4000000,  bhvStar, 31),
OBJECT_WITH_ACTS(122, 4000, 5300, 5250, 0, 0, 0, 0x3000000,  bhvStar, 31),
OBJECT_WITH_ACTS(122, -4437, 7700, 3313, 0, 0, 0, 0x2000000,  bhvStar, 31),
OBJECT_WITH_ACTS(0, -400, 1350, 0, 0, 0, 0, 0x0,  bhvBowserCourseRedCoinStar, 31),
OBJECT_WITH_ACTS(215, -4000, 2050, -3725, 0, 0, 0, 0x0,  bhvRedCoin, 31),
OBJECT_WITH_ACTS(215, -4000, -950, 3125, 0, 0, 0, 0x0,  bhvRedCoin, 31),
OBJECT_WITH_ACTS(215, 4500, 5050, 2750, 0, 0, 0, 0x0,  bhvRedCoin, 31),
OBJECT_WITH_ACTS(215, 4875, -1700, 2112, 0, 0, 0, 0x0,  bhvRedCoin, 31),
OBJECT_WITH_ACTS(215, 4875, 6250, -4450, 0, 0, 0, 0x0,  bhvRedCoin, 31),
OBJECT_WITH_ACTS(215, 3125, -1700, 0, 0, 0, 0, 0x0,  bhvRedCoin, 31),
OBJECT_WITH_ACTS(215, 0, -360, 0, 0, 0, 0, 0x0,  bhvRedCoin, 31),
OBJECT_WITH_ACTS(215, -4900, -1700, 0, 0, 0, 0, 0x0,  bhvRedCoin, 31),
OBJECT_WITH_ACTS(122, 4000, -1575, -2625, 0, 0, 0, 0x5000000,  bhvStar, 31),
OBJECT_WITH_ACTS(122, 4000, -750, -4750, 0, 0, 0, 0x6000000,  bhvStar, 31),
OBJECT_WITH_ACTS(207, 4000, 0, -3250, 0, 0, 0, 0x0,  bhvFloorSwitchHiddenObjects, 31),
OBJECT_WITH_ACTS(129, 5100, -2700, 2900, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4900, -2700, 2900, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4900, -2700, 2700, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 5100, -2700, 2700, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4100, -2500, 2700, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 3900, -2500, 2700, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4100, -2500, 2900, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 3900, -2500, 2900, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 5100, -1200, -4900, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 5100, -1200, -5100, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4900, -1200, -5100, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(89, 3920, 0, 1577, 0, 0, 0, 0x0,  bhvHeaveHo, 31),
OBJECT_WITH_ACTS(89, 3811, 0, -1129, 0, 0, 0, 0x0,  bhvHeaveHo, 31),
OBJECT_WITH_ACTS(180, -2750, 3100, 4000, 0, 0, 0, 0x0,  bhvFireSpitter, 31),
OBJECT_WITH_ACTS(180, -3125, 4650, -3500, 0, 0, 0, 0x0,  bhvFireSpitter, 31),
OBJECT_WITH_ACTS(180, 4000, 3850, -4450, 0, 0, 0, 0x0,  bhvFireSpitter, 31),
OBJECT_WITH_ACTS(0, -2875, 1975, 3875, 0, 0, 0, 0x0,  bhvCoinFormation, 31),
OBJECT_WITH_ACTS(0, -3550, 5000, 3125, 0, 0, 0, 0x110000,  bhvCoinFormation, 31),
OBJECT_WITH_ACTS(0, -4425, 6000, 3125, 0, 0, 0, 0x110000,  bhvCoinFormation, 31),
OBJECT_WITH_ACTS(0, -3565, 3675, -6185, 0, 0, 0, 0x110000,  bhvCoinFormation, 31),
OBJECT_WITH_ACTS(0, -4000, 6500, -2850, 0, 0, 0, 0x110000,  bhvCoinFormation, 31),
OBJECT_WITH_ACTS(0, 4900, -1250, 0, 0, 0, 0, 0x110000,  bhvCoinFormation, 31),
OBJECT_WITH_ACTS(0, 4875, 5000, -4450, 0, 0, 0, 0x110000,  bhvCoinFormation, 31),
OBJECT_WITH_ACTS(0, 3150, 5000, -3550, 0, 0, 0, 0x110000,  bhvCoinFormation, 31),
OBJECT_WITH_ACTS(206, 2100, 6500, -4500, 0, 0, 0, 0x0,  bhvSnufit, 31),
OBJECT_WITH_ACTS(206, 2900, 6500, -4500, 0, 0, 0, 0x0,  bhvSnufit, 31),
OBJECT_WITH_ACTS(206, 3600, -650, -5200, 0, 0, 0, 0x0,  bhvSnufit, 31),
OBJECT_WITH_ACTS(206, 0, 1500, -500, 0, 0, 0, 0x0,  bhvSnufit, 31),
OBJECT_WITH_ACTS(206, 0, 1500, 500, 0, 0, 0, 0x0,  bhvSnufit, 31),
OBJECT_WITH_ACTS(223, 91, 415, -1498, 0, 0, 0, 0x0,  bhvChuckya, 31),
OBJECT_WITH_ACTS(223, 104, 415, 1267, 0, 0, 0, 0x0,  bhvChuckya, 31),
OBJECT_WITH_ACTS(89, -3949, 0, 1416, 0, 0, 0, 0x0,  bhvHeaveHo, 31),
OBJECT_WITH_ACTS(89, -4026, 0, -1382, 0, 0, 0, 0x0,  bhvHeaveHo, 31),
OBJECT_WITH_ACTS(0, 0, 1050, 0, 0, 0, 0, 0xb0000,  bhvFadingWarp, 31),
OBJECT_WITH_ACTS(0, 500, 1050, 0, 0, 270, 0, 0xc0000,  bhvDeathWarp, 31),
OBJECT_WITH_ACTS(124, -3145, 0, -285, 0, 314, 0, 0xa00000,  bhvMessagePanel, 31),
OBJECT_WITH_ACTS(212, 4000, 11100, 4000, 0, 0, 0, 0x0,  bhv1Up, 31),
OBJECT_WITH_ACTS(129, 4000, -199, -1750, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4000, -199, -1550, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4000, -199, -1350, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4000, -199, -1150, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4000, -199, -950, 0, 0, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4000, -199, -750, 0, 45, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4141, -199, -891, 0, 45, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 4282, -199, -1032, 0, 45, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 3859, -199, -891, 0, 45, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(129, 3718, -199, -1032, 0, 45, 0, 0x0,  bhvHiddenObject, 31),
OBJECT_WITH_ACTS(0, -15, 4, 114, 0, 0, 20, 11,  RM_Scroll_Texture, 31),
OBJECT_WITH_ACTS(0, -15, 4, 26, 0, 0, 20, 12,  RM_Scroll_Texture, 31),
RETURN()
};

const LevelScript local_warps_bits_1_[] = {
WARP_NODE(10, 9, 1, 0, 0),
WARP_NODE(11, 34, 1, 10, 0),
WARP_NODE(12, 21, 1, 11, 0),
WARP_NODE(240, 16, 1, 51, 0),
WARP_NODE(241, 16, 1, 41, 0),
RETURN()
};
