Assets = 
{
	Asset("IMAGE", "minimap/beequeen.tex"),
	Asset("ATLAS", "minimap/beequeen.xml"),
	Asset("IMAGE", "minimap/giantbeehive.tex"),
	Asset("ATLAS", "minimap/giantbeehive.xml"),	
	Asset("SOUND", "sound/beequeen.fsb"),
	Asset("SOUNDPACKAGE", "sound/beequeen.fev"),
}

PrefabFiles = 
{
	"giantbeehive",
	"beequeen",
	"beeguard",
	"minibeehive",
	"hivehat",
}

require = GLOBAL.require
local TUNING = GLOBAL.TUNING
local GetPlayer = GLOBAL.GetPlayer
local Combat = require "components/combat"
local follower = require "components/follower"
local harvestable = require "components/harvestable"
local ccanattack = Combat.CanAttack
local GetPlayer = GLOBAL.GetPlayer
local STRINGS = GLOBAL.STRINGS
local RECIPETABS = GLOBAL.RECIPETABS
local Recipe = GLOBAL.Recipe
local Ingredient = GLOBAL.Ingredient
local TECH = GLOBAL.TECH
local ACTIONS = GLOBAL.ACTIONS
local Vector3 = GLOBAL.Vector3
local distsq = GLOBAL.distsq
local GetWorld = GLOBAL.GetWorld
local Prefabs = GLOBAL.Prefabs
local Transform = GLOBAL.Transform
local Physics = GLOBAL.Physics
local AnimState = GLOBAL.AnimState
local FRAMES = GLOBAL.FRAMES
local DEGREES = GLOBAL.DEGREES
local SpawnPrefab = GLOBAL.SpawnPrefab
local TheCamera = GLOBAL.TheCamera
local seg_time = 30
local day_segs = 10
local dusk_segs = 4
local night_segs = 2
local day_time = seg_time * day_segs
local dusk_time = seg_time * dusk_segs
local night_time = seg_time * night_segs
local total_day_time = seg_time*16
local TheSim = GLOBAL.TheSim
local SpawnPrefab = GLOBAL.SpawnPrefab

AddMinimapAtlas("minimap/beequeen.xml")
AddMinimapAtlas("minimap/giantbeehive.xml")

GLOBAL.TUNING.BEEHIVE_SPLITDELAY = GetModConfigData("beehive_split_delay")
GLOBAL.TUNING.GIAGANTICBEEHIVE_SPAWNCHANCE = GetModConfigData("giantbeehive_spawn_chance")
GLOBAL.TUNING.BEEHIVE_SPAWN_BEEHIVE = GetModConfigData("beehive_split_beehive")

--Credits to Mouse for the mode More Realistic Beehive
local function OnSave(inst, data)
	data.dayssincesplice = inst.dayssincesplice
	data.splicesetup = inst.splicesetup
	data.splicetargettime = inst.splicetargettime
end

local function OnLoad(inst, data)
	if data then
		if data.dayssincesplice then
			inst.dayssincesplice = data.dayssincesplice
		else
			inst.dayssincesplice = 0
		end
		if data.splicetargettime then
			inst.splicetargettime = data.splicetargettime
		end
	end
end

local function splicer(inst)
	if not inst.dayssincesplice then
		inst.dayssincesplice = 0
	end
	if not inst.splicetargettime or inst.dayssincesplice <= 1 then
		inst.splicetargettime = GLOBAL.TUNING.BEEHIVE_SPLITDELAY-- + math.random(-3,3)
	end
	inst.dayssincesplice = inst.dayssincesplice + 1
	if inst.dayssincesplice >= inst.splicetargettime and (inst.components.childspawner.numchildrenoutside + inst.components.childspawner.childreninside) >= inst.components.childspawner.maxchildren then
		local beehivesplit = GLOBAL.TUNING.BEEHIVE_SPAWN_BEEHIVE
		if beehivesplit == 1 then
			local newhive
			local chance = math.random(1,GLOBAL.TUNING.GIAGANTICBEEHIVE_SPAWNCHANCE)
			if chance == 1 then
				newhive = GLOBAL.SpawnPrefab("giantbeehive")
			else
				newhive = GLOBAL.SpawnPrefab("beehive")
			end
			local time = math.random(5,25)
			local offset = GLOBAL.CreateDiscEmitter(15)
			local currentloc = GLOBAL.Vector3(inst.Transform:GetWorldPosition())
			local dx, dz = offset()
			currentloc.x = currentloc.x + dx + 3
			currentloc.z = currentloc.z + dz + 3	
			local position = GLOBAL.GetWorld().Map:GetTileAtPoint(currentloc.x, currentloc.y, currentloc.z)
			if (position ~= GLOBAL.GROUND.IMPASSABLE and position ~= GLOBAL.GROUND.OCEAN_SHALLOW and position ~= GLOBAL.GROUND.MANGROVE) then
				--phase 1: gather at new point
				inst:DoTaskInTime(time, function(inst)
					inst.components.childspawner:ReleaseAllChildren(nil,"killerbee")
					for k,bee in pairs(inst.components.childspawner.childrenoutside) do
						bee:DoPeriodicTask(.1, function(inst)
							if not bee.ignoreperitask then
								bee.components.locomotor:GoToPoint(currentloc)
							end
						end)
					end
				end)
				--phase 2: create hive and clean up
				inst:DoTaskInTime(time+5, function(inst) GLOBAL.SpawnPrefab("poopcloud").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z) end)
				inst:DoTaskInTime(time+6, function(inst) GLOBAL.SpawnPrefab("ground_chunks_breaking").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z) end)
				inst:DoTaskInTime(time+7, function(inst) GLOBAL.SpawnPrefab("poopcloud").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z) end)
				inst:DoTaskInTime(time+8, function(inst) GLOBAL.SpawnPrefab("ground_chunks_breaking").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z) end)
				inst:DoTaskInTime(time+9, function(inst) GLOBAL.SpawnPrefab("poopcloud").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z) end)
				inst:DoTaskInTime(time+10, function(inst)
					for k,bee in pairs(inst.components.childspawner.childrenoutside) do
						inst.components.childspawner:GoHome(bee)
					end
					newhive.Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z)
					newhive.components.childspawner.childreninside = 3
					inst.components.childspawner.childreninside = 3
					inst.dayssincesplice = 0
					GLOBAL.SpawnPrefab("collapse_small").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z)
				end)
			end
		else
			local chance = math.random(1,GLOBAL.TUNING.GIAGANTICBEEHIVE_SPAWNCHANCE)
			if chance == 1 then
				local newhive = GLOBAL.SpawnPrefab("giantbeehive")
				local time = math.random(5,25)
				local offset = GLOBAL.CreateDiscEmitter(15)
				local currentloc = GLOBAL.Vector3(inst.Transform:GetWorldPosition())
				local dx, dz = offset()
				currentloc.x = currentloc.x + dx + 3
				currentloc.z = currentloc.z + dz + 3	
				local position = GLOBAL.GetWorld().Map:GetTileAtPoint(currentloc.x, currentloc.y, currentloc.z)
				if (position ~= GLOBAL.GROUND.IMPASSABLE and position ~= GLOBAL.GROUND.OCEAN_SHALLOW and position ~= GLOBAL.GROUND.MANGROVE) then
					--phase 1: gather at new point
					inst:DoTaskInTime(time, function(inst)
						inst.components.childspawner:ReleaseAllChildren(nil,"killerbee")
						for k,bee in pairs(inst.components.childspawner.childrenoutside) do
							bee:DoPeriodicTask(.1, function(inst)
								if not bee.ignoreperitask then
									bee.components.locomotor:GoToPoint(currentloc)
								end
							end)
						end
					end)
					--phase 2: create hive and clean up
					inst:DoTaskInTime(time+5, function(inst) GLOBAL.SpawnPrefab("poopcloud").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z) end)
					inst:DoTaskInTime(time+6, function(inst) GLOBAL.SpawnPrefab("ground_chunks_breaking").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z) end)
					inst:DoTaskInTime(time+7, function(inst) GLOBAL.SpawnPrefab("poopcloud").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z) end)
					inst:DoTaskInTime(time+8, function(inst) GLOBAL.SpawnPrefab("ground_chunks_breaking").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z) end)
					inst:DoTaskInTime(time+9, function(inst) GLOBAL.SpawnPrefab("poopcloud").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z) end)
					inst:DoTaskInTime(time+10, function(inst)
						for k,bee in pairs(inst.components.childspawner.childrenoutside) do
							inst.components.childspawner:GoHome(bee)
						end
						newhive.Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z)
						newhive.components.childspawner.childreninside = 3
						inst.components.childspawner.childreninside = 3
						inst.dayssincesplice = 0
						GLOBAL.SpawnPrefab("collapse_small").Transform:SetPosition(currentloc.x,currentloc.y,currentloc.z)
					end)
				end
			end
		end
	end
end

local levels = 
{
    { amount=6, idle="honey3", hit="hit_honey3" },
    { amount=3, idle="honey2", hit="hit_honey2" },
    { amount=1, idle="honey1", hit="hit_honey1" },
    { amount=0, idle="bees_loop", hit="hit_idle" },
}
local function setlevel(inst, level)
    if not inst.anims then
        inst.anims = {idle = level.idle, hit = level.hit}
    else
        inst.anims.idle = level.idle
        inst.anims.hit = level.hit
    end
    inst.AnimState:PlayAnimation(inst.anims.idle)
end
local function beeboxOnLoad(inst, data)
	if data then
		if data.dayssincesplice then
			inst.dayssincesplice = data.dayssincesplice
		else
			inst.dayssincesplice = 0
		end
		if data.splicetargettime then
			inst.splicetargettime = data.splicetargettime
		end
	end
    for k,v in pairs(levels) do
        if inst.components.harvestable.produce >= v.amount then
            setlevel(inst, v)
            break
        end
    end
end
local function x(inst)
	inst.OnSave = OnSave
	inst.OnLoad = OnLoad
	inst:ListenForEvent("daytime", function() splicer(inst) end, GLOBAL.GetWorld())
end
AddPrefabPostInit("beehive", x)

GLOBAL.STRINGS.NAMES.GIANTBEEHIVE = "Gigantic Beehive"
GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.GIANTBEEHIVE = "I don't want to know how many guys are inside."
GLOBAL.STRINGS.NAMES.BEEQUEEN = "Bee Queen"
GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.BEEQUEEN = "Keep that stinger away from me!"
GLOBAL.STRINGS.NAMES.BEEGUARD = "Bee Guard"
GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.BEEGUARD = "It's guarding the queen."

GLOBAL.STRINGS.ACTIONS.MINIBEEHIVE = "Wake up"

function MiniBeeHiveSimPostInit()
ACTIONS.MINIBEEHIVE = GLOBAL.Action()
ACTIONS.MINIBEEHIVE.fn = function(act)
 local tar = act.target or act.invobject
  if tar and tar.components.minibeehive then
        tar.components.minibeehive:Working(tar)
        return true
    end
end
for k,v in pairs(ACTIONS) do
	 if k == "MINIBEEHIVE" then
    		v.str = STRINGS.ACTIONS[k] or "ACTION"
   		 v.id = k
	 end
end 
local function addActionHandler(SGname, action, state, condition)
	actionHandler = GLOBAL.ActionHandler(action, state, condition)
	for k,v in pairs(GLOBAL.SGManager.instances) do	
		if(k.sg.name == SGname) then
			k.sg.actionhandlers[action] = actionHandler
			break
		end
	end 
end
local function addState(SGname, state)
	 for k,v in pairs(GLOBAL.SGManager.instances) do	
		if(k.sg.name == SGname) then
			k.sg.states[state.name] =  state
			break
		end
	 end
end
addActionHandler("wilson", GLOBAL.ACTIONS.MINIBEEHIVE, "minibeehive")
local minibeehive = GLOBAL.State{
        name = "minibeehive",
        tags = {"doing"},
        
        onenter = function(inst, timeout)
            
            inst.sg:SetTimeout(timeout or 1)
            inst.components.locomotor:Stop()
            inst.AnimState:PlayAnimation("build_pre")
            inst.AnimState:PushAnimation("build_loop", true)
        end,
        
        ontimeout= function(inst)
            inst.AnimState:PlayAnimation("build_pst")
            inst.sg:GoToState("idle", false)
            inst:PerformBufferedAction()
        
        end,
        
        onexit= function(inst)
            inst.SoundEmitter:KillSound("make")
        end, 
    }

    addState("wilson", minibeehive)
	end
AddSimPostInit(MiniBeeHiveSimPostInit)