
Resource = inherited("Resource", ActionEntity)

Network.registerClass(Resource)

Resource.variables = {
	sync = {"x", "y", "health"},
	new = {"map","owner","x", "y", "dx", "dy", "type"},
}
Resource.structure = {
	sync = {"f", "f", "f"},
	new = {"e","e", "f", "f", "f", "f", "i"},
}

function Resource:def()
	return RESOURCE_TYPES[self.type]
end

function Resource:getMass()
	return self:stat("mass")
end


function Resource:getRadius()
	return self:stat("radius")
end


function Resource:new(map, owner, x,y, dx, dy, type)
	local astr = instance(self, map, owner, x, y, 0, dx, dy, 0, RESOURCE_TYPES[type].health)
	astr.type = type
	astr.map = map
	astr.x = x
	astr.y = y
	astr.dx = dx or 0
	astr.dy = dy or 0
	astr.time = 0
	astr.ownerDelay = 0
	astr.invul = 1
	map:addEnt(astr)
	map:addResource(astr)
	return astr
end

function Resource:remove()
	if not self._remove then
		self._remove = true
		self.map:removeEnt(self)
		self.map:removeResource(self)
	end
end

function Resource:step(time)
	self:super().step(self, time)
	
	if self.invul > 0 then
		self.invul = self.invul - time
	end

	if self.health <= self:stat("healthDrainThreshold") then
		self.health = self.health - time * self:stat("healthDrainSpeed")
		if self.owner ~= self.map then
			if self.health <= self:stat("healthDropThreshold") then
				self:setOwner(self.map)
			end
		end
	end

	self:applyFrictionDelta(time)
	self:applyFriction(time)

	if self.owner == self.map then
		self:applyGravity(time*0.5)

		if self.ownerDelay > 0 then
			self.ownerDelay = self.ownerDelay - time
		else
			local bestCarrier = nil
			local bestDist = nil

			for index, ent in pairs(self.map.ents) do
				if ent:isCarrier() then
					local dist = self:getDistanceTo(ent)
					if dist < self:stat("collectionDistance") then
						if not bestDist or dist < bestDist then
							bestDist = dist
							bestCarrier = ent
						end
					end
				end
			end

			if bestCarrier then
				self:setOwner(bestCarrier)
			end
		end

		self.time = self.time + time
		if self.time > 20 then
			self.health = self.health - 10*time
		end
	else
		if not self.suckInto then
			if self:getOwner().buildings then
				for index, building in pairs(self:getOwner().buildings) do
					if building:wantsResource(self) then
						local dist = self:getDistanceTo(building)
						if dist < self:stat("suckDistance") then
							self.suckInto = building
						end
					end
				end
			end
		else
			local angTo = self:getAngleTo(self.suckInto)
			self.dx = math.approach(self.dx, 0, math.difference(self.dx, 0)*time*self:stat("suckFriction"))
			self.dy = math.approach(self.dy, 0, math.difference(self.dy, 0)*time*self:stat("suckFriction"))
			self.dx = math.approach(self.dx, math.cos(angTo)*self:stat("suckSpeed"), time*self:stat("suckPower"))
			self.dy = math.approach(self.dy, math.sin(angTo)*self:stat("suckSpeed"), time*self:stat("suckPower"))

			local dist = self:getDistanceTo(self.suckInto)
			if dist <= self:stat("suckReachDistance") then
				if self.suckInto:addResource(self) then
					self:remove()
				else
					self.suckInto = nil
					self.dx = -self.dx*1.5
					self.dy = -self.dy*1.5
				end
			end
		end
	end

	self:applyHail(time)

	
	
end

function Resource:setOwner(ent)
	if self.owner ~= self.map then
		self.owner:removeResource(self)
	end
	self.owner = ent
	if self.owner ~= self.map then
		self.owner:addResource(self)
	end
end

function Resource:hurt(h)
	if self.invul <= 0 then
		self.health = self.health -h
		if self.health <= 0 then
			return true
		end
	end
end


function Resource:fakeStep(time)
	self.time = self.time + time
end

function Resource:isResource()
	return true
end

function Resource:canCollideWith(ent)
	return not ent:isResource() and not self.suckInto and self:getOwner() ~= ent:getOwner()
end

function Resource:getStepFrequency()
	return APP.tickTime*10
end

function Resource:renderAt(x,y,scale,angle,a,r,g,b)
	local r,g,b = 255,255,255
	if self.health <= self:stat("healthDrainThreshold") then
		local prg = (self:stat("healthDrainThreshold") - self.health) / self:stat("healthDrainThreshold")
		local blink = 255 - math.abs(math.cos(self.time*20*prg))*200
		r,g,b = blink,blink,blink
	end
	video.renderSpriteState(self:def().sprites.main, x, y, scale, angle, a, r, g, b)
	for i=1,5 do
		local angle = math.cos(self.time * (1+i*0.5))*math.sin(self.time*2 + i)*math.pi
		local dist = math.sin(self.time * (0.2+i*0.2))*math.cos(self.time*0.4 + i*0.5)*self:getRadius()*0.8
		local rx, ry = x + math.cos(angle) * dist *scale, y + math.sin(angle) * dist *scale
		video.renderSpriteState(self:def().sprites.main, x, y, scale, angle, a, r, g, b)
	end
end

function Resource:onHit(ent, angle, impulse, counterImpulse)
	if not ent:isCarrier() and not ent:isResource() then
		self:setOwner(self.map)
		self.ownerDelay = 2
		--ent:hurt(impulse*self:stat("impulseDamageFactor"))
	end
end

function Resource:onDestroy()
	self:explode()
	if self.owner ~= self.map then
		self.owner:removeResource(self)
	end
end

function Resource:onCollided(normal, impulse, torque)
	self:bounce(normal, 0.9)
	local impulseDamage = impulse/self:getMass()* self:stat("collisionDamageFactor")
	if impulseDamage > self:stat("collisionThreshold") then
		local damage = impulseDamage - self:stat("collisionThreshold")
		if self:hurt(damage) then
		end
	end
end