
---- Alis, the funny colored square ----
-------------------------------------------------------------------------------

Alis = { 
	x = S_BORDER, y = S_BORDER, 
	dir = {A_SPEED, 0}, stop = false,
	cur_point = Circle.points[1],
	drawangle = 0.0,
	stoppower = 1.0, stopdec = 1/90,
	turbopower = 1.0, turbodec = 1/60,
	nbombs = 0, nbtimeout = 0
}

function Alis:reset()
	self.stopdec = Difficulty.stopdec
	self.turbodec = Difficulty.turbodec
	self.stoppower = 1.0
	self.turbopower = 1.0
	self.cur_point = Circle.points[1]
	self.dir = {A_SPEED, 0}
	self.stop = false
	self.x, self.y = S_BORDER, S_BORDER
end

function Alis:addNBomb()
	self.nbombs = self.nbombs + 1
end

function Alis:setDir(dx, dy, first)
	if first then
		Fibers:pre(self.cur_point)
		self.cur_point = nil
		Fibers:add(self.x, self.y)
	end
	Fibers:add(self.x, self.y)
	self.dir = {dx, dy}
end

function Alis:control(ctrl)
	-- ^,^
	local pre = Circle:getPrevious(self.cur_point)
	if ctrl:up() then
		if self.cur_point == nil and self.dir[1] == A_SPEED 
				and table.getn(Fibers.points) <= 3 then
			self:setDir(0, -A_SPEED)
		elseif not(self.cur_point == nil) and self.dir[1] == -A_SPEED 
				and not(pre[1] == self.x and pre[2] <= self.y) then
			self:setDir(0, -A_SPEED, true)
		end
	elseif ctrl:down() then
		if self.cur_point == nil and self.dir[1] == -A_SPEED 
				and table.getn(Fibers.points) <= 3 then
			self:setDir(0, A_SPEED)
		elseif not(self.cur_point == nil) and self.dir[1] == A_SPEED 
				and not(pre[1] == self.x and pre[2] >= self.y) then
			self:setDir(0, A_SPEED, true)
		end
	elseif ctrl:left() then
		if self.cur_point == nil and self.dir[2] == -A_SPEED 
				and table.getn(Fibers.points) <= 3 then
			self:setDir(-A_SPEED, 0)
		elseif not(self.cur_point == nil) and self.dir[2] == A_SPEED 
				and not(pre[2] == self.y and pre[1] <= self.x) then
			self:setDir(-A_SPEED, 0, true)
		end
	elseif ctrl:right() then
		if self.cur_point == nil and self.dir[2] == A_SPEED 
				and table.getn(Fibers.points) <= 3 then
			self:setDir(A_SPEED, 0)
		elseif not(self.cur_point == nil) and self.dir[2] == -A_SPEED 
				and not(pre[2] == self.y and pre[1] >= self.x) then
			self:setDir(A_SPEED, 0, true)
		end
	end
	
	if ctrl:l() and not ctrl:r() and self.stoppower > self.stopdec then
		MusicPlayer:stopSpeed()
		self.stop = true
		self.stoppower = self.stoppower - self.stopdec
	else 
		MusicPlayer:stopStopSpeed()
		self.stop = false
		if self.stoppower < 1.0 then 
			self.stoppower = self.stoppower + 0.00005/self.stopdec
		end
	end
	if ctrl:r() and not ctrl:l() and self.turbopower > self.turbodec then
		MusicPlayer:turboSpeed()
		self:draw(); self:move(); self:draw(); self:move()
		self.turbopower = self.turbopower - self.turbodec
	else
		MusicPlayer:stopTurboSpeed()
		if self.turbopower < 1.0 then 
			self.turbopower = self.turbopower + 0.00005/self.turbodec
		end
	end
	
	if ctrl:circle() then
		self:nBomb()
	elseif self.nbtimeout > 0 then
		self.nbtimeout = self.nbtimeout - 1
	end
end

function Alis:move()
	if self.stop then return end
	-- workaround for rare situation
	if self.cur_point and self.dir[1] == 0 and self.dir[2] == 0 then
		local p, np = Circle:getTriplet(self.cur_point)
		self.dir = {math.sgn(np[1]-p[1])*A_SPEED, math.sgn(np[2]-p[2])*A_SPEED} -- follow
	end

	self.x = self.x + self.dir[1]
	self.y = self.y + self.dir[2]
	
	if self.cur_point == nil then -- update the last Fiber point if free-roaming
		Fibers:changeLast(self.x, self.y)
		Game:addScore(1)
	end
	-- check for hit
	Circle:eachLine(function(p1, p2, hor)
		if p1 ~= self.cur_point then -- do nothing for current line
			-- check for hit on horizontal line
			if hor and self.dir[2] ~= 0 and self.y == p1[2] and
					isBound(self.x, p1[1], p2[1]) then -- we hit it
				if not self.cur_point then -- are we free roaming?
					self.cur_point = Fibers:resolve(p2)
					if not self.cur_point then self.cur_point = p1 end
				else 
					self.cur_point = p1
					self:dirChangeSound()
				end
				local p, np = Circle:getTriplet(self.cur_point)
				self.dir = {math.sgn(np[1]-p[1])*A_SPEED, 0} -- follow
				return false -- early exit
			-- check for hit on vertical line
			elseif not hor and self.dir[1] ~=0 and self.x == p1[1] and
					isBound(self.y, p1[2], p2[2]) then -- we hit it
				if not self.cur_point then -- are we free roaming?
					self.cur_point = Fibers:resolve(p2)
					if not self.cur_point then self.cur_point = p1 end
				else 
					self.cur_point = p1
					self:dirChangeSound()
				end
				local p, np = Circle:getTriplet(self.cur_point)
				self.dir = {0, math.sgn(np[2]-p[2])*A_SPEED} -- follow
				return false -- early exit
			end
		end
	end)
end

function Alis:nBomb()
	if self.nbombs > 0 and self.nbtimeout <= 0 then
		self.nbtimeout = 30
		self.nbombs = self.nbombs - 1
		NBomb:new(self.x, self.y)
	end
end

function Alis:draw()
	--screen:print(20, 40, "Alis x: " .. self.x .. " y: " .. self.y, white)
	screen.blitRotated(self.x - 8, self.y - 8, imgs.alis, self.drawangle)
	self.drawangle = self.drawangle + 10;
end

function Alis:dirChangeSound()
	sfx.dirchange:playAt(self.x/SCREEN_WIDTH*255)
end
