autoImport('LuaRolesOnCurrentMap')

LuaDynamicGrass = class('LuaDynamicGrass')

local gReusableLuaVector2A = LuaVector2.zero
local gReusableLuaVector2B = LuaVector2.zero
local gReusableLuaVector3A = LuaVector3.zero

local CreateArray = ReusableTable.CreateArray
local DestroyArray = ReusableTable.DestroyArray

local StateNone = 0
local StateNew = 1
local StateMoving = 2

function LuaDynamicGrass:EffectiveBodysCount()
	return #self.cachedEffectiveBodys
end

local effectSpawnFrameLimit = 40
function LuaDynamicGrass:ctor()
	self.posx, self.posy, self.posz = 0, 0, 0
	self.dirtyRemoves = {}
	self.cacheRoles = {}
	self.roleCount = 0
	self.frameCount = 0
end

function LuaDynamicGrass:AttachGameObject(go)
	self.gameObject = go
	self.transform = self.gameObject.transform
	self:SetPos()
end

--由於植物不會動所以座標只獲取一次
function LuaDynamicGrass:SetPos()
	self.posx, self.posy, self.posz = LuaGameObject.GetPosition(self.transform)
end

function LuaDynamicGrass:Initialize()
	self.grassSlope = self.gameObject:GetComponent('GrassSlopeV2')
	self.AddForce = self.grassSlope.AddForce
	self.ChangeForce = self.grassSlope.ChangeForce
	self.MinusForce = self.grassSlope.MinusForce
end

local sqrt = math.sqrt
local floor = math.floor
local LuaRolesOnCurrentMapIns = LuaRolesOnCurrentMap.Ins()
function LuaDynamicGrass:Update()
	if(self.roleCount>0) then
		for k,v in pairs(self.dirtyRemoves) do
			self:RemoveEffectiveBody(k)
		end
		for k,v in pairs(self.cacheRoles) do
			local posOfRole = NSceneUserProxy.Instance:Find(k):GetPosition()
			local grassToRoleX, grassToRoleZ = posOfRole[1] - self.posx, posOfRole[3] - self.posz
			local distance = sqrt(grassToRoleX ^ 2 + grassToRoleZ ^ 2)
			if distance <= self.effectiveDistance then
				gReusableLuaVector2A:Set(-grassToRoleX, grassToRoleZ)
				local forceDirection = gReusableLuaVector2A
				local force = floor(- 100 * distance / self.effectiveDistance + 100)
				if (forceDirection[1] ~= 0 or forceDirection[2] ~= 0) and force > 0 then
					if v[2] == StateNew then
						-- need optimize
						local id = self.AddForce(self.grassSlope, forceDirection, force, 0.5)
						v[1] = id
						v[2] = StateNone
					elseif v[2] == StateMoving then
						v[2] = StateNone
						-- need optimize
						self.ChangeForce(self.grassSlope, v[1], forceDirection, force, 0.5)
					end
				end
			end
		end
	end
	if(self.playingEffect) then
		self.frameCount = self.frameCount + 1
		if(self.frameCount>effectSpawnFrameLimit) then
			self.frameCount = 0
			self.playingEffect = false
		end
	end
end

function LuaDynamicGrass:RemoveEffectiveBody(role_id)
	local effectiveBody = self:GetEffectiveBody(role_id)
	if effectiveBody ~= nil then
		self.dirtyRemoves[role_id] = nil
		self:DoRemoveEffectiveBody(role_id,effectiveBody)
	end
end

function LuaDynamicGrass:MoveOrAdd(role_id)
	self.dirtyRemoves[role_id] = nil
	local effectiveBody = self:GetEffectiveBody(role_id)
	if(effectiveBody==nil) then
		effectiveBody = self:AddEffectBody(role_id)
		effectiveBody[1] = 0
		effectiveBody[2] = StateNew
	else
		effectiveBody[2] = StateMoving
	end
end

function LuaDynamicGrass:DirtyRemove(role_id)
	self.dirtyRemoves[role_id] = 1
end

local ArrayFindIndex = TableUtility.ArrayFindIndex
local remove = table.remove
function LuaDynamicGrass:DoRemoveEffectiveBody(role_id,effective_body)
	self.MinusForce(self.grassSlope, effective_body[1])
	self:RemoveEffectBody(role_id)
end

function LuaDynamicGrass:Launch(plant_type, effective_distance)
	self.plantType = plant_type
	self.effectiveDistance = effective_distance
end

function LuaDynamicGrass:Release()
	self.grassSlope = nil
	for k,v in pairs(self.cacheRoles) do
		DestroyArray(v)
	end
	self.cacheRoles = nil
end

function LuaDynamicGrass:GetEffectiveBody(role_id)
	return self.cacheRoles[role_id]
end

function LuaDynamicGrass:AddEffectBody(role_id)
	local cache = self.cacheRoles[role_id]
	if(cache==nil) then
		cache = CreateArray()
		self.cacheRoles[role_id] = cache
		self.roleCount = self.roleCount + 1
		if(self.roleCount == 1) then
			self:_PlayEffect()
		end
	end
	return cache
end

function LuaDynamicGrass:RemoveEffectBody(role_id)
	local cache = self.cacheRoles[role_id]
	if(cache) then
		self.roleCount = self.roleCount - 1
		DestroyArray(cache)
		self.cacheRoles[role_id] = nil
	end
end

function LuaDynamicGrass:_PlayEffect()
	if(self.playingEffect) then
		return
	end
	if self.plantType == LuaFarmland.PlantType.Wheat then
		self.playingEffect = true
		local effectPath = EffectMap.Maps.InteractionPlant_Wheat
		local assetEffect = Asset_Effect.PlayOneShotOn(effectPath, self.transform)
		-- assetEffect:RegisterWeakObserver(self)
	end
end

function LuaDynamicGrass:ObserverDestroyed(effect)
	self.playingEffect = false
end