--------------------------------------------------------------------------------
-- Animation code
-- animation.lua
-- -----------------------------------------------------------------------------

SimNetwork_DATA = true
if not SimNetwork_DATA		then dofile("data.lua") end

ANIMATION = {
	packet_cable1 = {
		e = "data/cables/packet.obj",
		bounds = {0.2, 0.2, 0.2},
	},
	
	packet_cable10 = {
		e = "data/cables/packet.obj",
		bounds = {0.2, 0.2, 0.2},
	},
	
	packet_cable100 = {
		e = "data/cables/packet.obj",
		bounds = {0.2, 0.2, 0.2},
	},
}

function loadAnimationModels()
	for x, model in ANIMATION do
		if model.e ~= nil and type(model.e) == "string" then
			model.e = E.create_object(model.e)
			hide(model.e)
		end
	end
end 

--------------------------------------------------------------------------------
-- class: CustomerAnim
-- Manages animation for a single customer
--------------------------------------------------------------------------------
CustomerAnim = {}
CustomerAnim_Mt = {__index = CustomerAnim}

CUSTOMER_JUMP_COUNT = 2
CUSTOMER_JUMP = 8
CUSTOMER_STEP = 0.7

function CustomerAnim:new(gObject)
	newCustomerAnim = {
		g = gObject,
		step = 0,
		
		x, y, z = E.get_entity_position(gObject.e)
	}
	
	newCustomerAnim.x, newCustomerAnim.y, newCustomerAnim.z = E.get_entity_position(gObject.e)
	
	--print("new CustomerAnim object for:", gObject.o:getName())
	setmetatable(newCustomerAnim, CustomerAnim_Mt)
	return newCustomerAnim

end

function CustomerAnim:animate()
	
	if self.step > CUSTOMER_JUMP_COUNT*2 - 1 then
		-- should jump two times only
		return
	else
		
		-- make the customer jump
		local curX, curY, curZ = E.get_entity_position(self.g.e)
		local offset = curY - self.y

		if math.mod(self.step, 2) == 0 then
			-- go up			
			if offset > CUSTOMER_JUMP then
				self.step = self.step + 1
			else
				E.move_entity(self.g.e, 0, CUSTOMER_STEP, 0)
			end
		else
			-- go down
			if offset <= 0 then
				self.step = self.step + 1
				-- position entity at original coordinates
				E.set_entity_position(self.g.e, self.x, self.y, self.z)
			else
				E.move_entity(self.g.e, 0, -CUSTOMER_STEP, 0)
			end
		end
	end
end
-------------------------------------------------------------------
-- class: CableAnim
-- Manages animation for a single cable
-------------------------------------------------------------------
CableAnim = {}
CableAnim_Mt = {__index = CableAnim}

function CableAnim:new(gObject)
	newCableAnim = {
		g = gObject,
		step = 0,
		utilization = nil,
		packets = {},
	}
	
	setmetatable(newCableAnim, CableAnim_Mt)
	return newCableAnim
end

function CableAnim:deleteAnimation()
	for x, packet in self.packets do
		E.delete_entity(packets)
	end
	self.packets = {}
	
end

function CableAnim:resetAnimation()

	self:deleteAnimation()
	self.step = 0
end

-------------------------------------------------------------------
-- Function:	CableAnim:createPackets()
-- Inputs:	distance: distance between individual packets
function CableAnim:createPackets(distance)

	-- for now, draw packets on first segment
	local top = {}
	local bottom = {}
	
	local angle = self.g.o:getAngles()[1]
	local x, y, z = E.get_entity_position(self.g.e)
	
	top[1] = (self.g.o:getLength() / 2) * math.cos(math.rad(angle))
	top[2] = 0
	top[3] = (self.g.o:getLength() / 2) * math.sin(math.rad(angle))
	
	bottom[1] = x - top[1]
	bottom[2] = top[2]
	bottom[3] = z + top[3]
	
	top[1] = x + top[1]
	top[3] = z - top[3]
	
	local curDistance = top[3]
	
	while  curDistance < bottom do
	
		local model = "packet_" .. self.g.o:getSubtype()
		local aPacket = E.create_clone(ANIMATION[model].e)
		
		-- calculate position of packet
		local p = {}
		p[1] = top[1] + (curDistance / 2) * math.cos(math.rad(angle))
		p[2] = 0
		p[3] = top[3] - (curDistance / 2) * math.sin(math.rad(angle))
		
		-- rotate packet about y in the same angle
		E.set_entity_rotation(aPacket, 0, angle, 0)
		
		-- set position
		E.set_entity_position(aPacket, unpack(p))
		
		-- assign it to scene
		gameScene:display(aPacket)
		
		E.parent_entity(aPacket, gameScene:getHeadLight())
		
	end
end

function CableAnim:animate()
	
	if self.utilization ~= g.o:getUtilization() then
		self:resetAnimation()
		self.utilization = g.o:getUtilization()
	end
end
