local class = require 'libs/middleclass'

Sexyloop = class('Sexyloop')

require 'patterns/Sexyloop'

function Sexyloop:initialize (state, x, y, board)
	self.state = state
	self.x = x
	self.y = y
	self.board = board
end

Sexyloop.colors = {
	{0  , 0  , 0  },
	{0  , 0  , 255},
	{255, 0  , 0  },
	{255, 0  , 255},
	{0  , 255, 0  },
	{0  , 255, 255},
	{255, 255, 0  },
	{255, 255, 255},
	{150, 150, 150},
	{255, 200, 0  }
}

function Sexyloop:next_state ()
	return self:conditions ()
end

Sexyloop.static.transitions = {
	{{0,0,0,0,1},2},
	{{0,0,0,0,4},3},
	{{0,0,0,1,2},2},
	{{0,0,0,1,5},2},
	{{0,0,0,2,1},2},
	{{0,0,0,2,4},2},
	{{0,0,0,4,2},2},
	{{0,0,0,4,5},2},
	{{0,0,0,7,5},2},
	{{0,0,1,0,2},2},
	{{0,0,2,1,4},1},
	{{0,0,2,1,7},1},
	{{0,0,2,3,2},2},
	{{0,1,1,2,2},1},
	{{0,1,2,1,2},1},
	{{0,1,2,3,2},1},
	{{0,1,2,4,2},1},
	{{0,1,2,4,5},1},
	{{0,1,2,5,2},6},
	{{0,1,2,6,2},6},
	{{0,1,2,7,2},1},
	{{0,1,2,7,5},1},
	{{0,1,3,4,2},1},
	{{0,1,3,7,2},1},
	{{0,1,4,2,2},1},
	{{0,1,4,2,5},1},
	{{0,1,4,3,2},1},
	{{0,1,4,3,5},1},
	{{0,1,4,4,2},1},
	{{0,1,4,6,2},1},
	{{0,1,7,2,2},1},
	{{0,1,7,2,5},1},
	{{0,1,7,5,6},1},
	{{0,1,7,6,2},1},
	{{0,1,7,7,2},1},
	{{1,0,0,0,1},1},
	{{1,0,0,1,2},1},
	{{1,0,0,2,1},1},
	{{1,0,0,2,4},4},
	{{1,0,0,2,7},7},
	{{1,0,1,2,1},1},
	{{1,0,1,2,4},4},
	{{1,0,1,2,7},7},
	{{1,0,2,0,2},1},
	{{1,0,2,1,1},1},
	{{1,0,2,1,2},1},
	{{1,0,2,1,3},1},
	{{1,0,2,2,1},1},
	{{1,0,2,2,4},4},
	{{1,0,2,2,7},7},
	{{1,0,2,3,2},4},
	{{1,0,2,4,1},4},
	{{1,0,2,4,2},4},
	{{1,0,2,4,3},4},
	{{1,0,2,5,1},1},
	{{1,0,2,5,2},7},
	{{1,0,2,5,4},3},
	{{1,0,2,5,7},7},
	{{1,0,2,7,1},7},
	{{1,0,2,7,2},7},
	{{1,0,2,7,3},5},
	{{1,0,5,1,2},1},
	{{1,0,5,4,2},4},
	{{1,0,5,7,2},7},
	{{1,0,6,2,1},1},
	{{1,0,6,2,4},4},
	{{1,0,6,2,7},7},
	{{1,1,1,1,2},1},
	{{1,1,1,2,2},1},
	{{1,1,1,2,4},4},
	{{1,1,1,2,5},1},
	{{1,1,1,2,7},7},
	{{1,1,1,6,2},1},
	{{1,1,2,1,2},1},
	{{1,1,2,1,3},1},
	{{1,1,2,1,5},1},
	{{1,1,2,2,2},1},
	{{1,1,2,2,4},4},
	{{1,1,2,2,7},7},
	{{1,1,2,3,2},1},
	{{1,1,2,4,2},4},
	{{1,1,2,4,3},4},
	{{1,1,2,5,2},7},
	{{1,1,2,5,4},3},
	{{1,1,2,5,7},7},
	{{1,1,2,6,2},6},
	{{1,1,2,7,2},7},
	{{1,1,2,7,3},5},
	{{1,1,3,2,2},1},
	{{1,1,3,3,2},1},
	{{1,1,5,4,2},4},
	{{1,1,5,7,2},7},
	{{1,1,6,2,4},4},
	{{1,1,6,2,7},7},
	{{1,2,2,2,4},4},
	{{1,2,2,2,7},7},
	{{1,2,2,4,3},4},
	{{1,2,2,7,3},7},
	{{1,2,3,2,4},4},
	{{1,2,3,2,7},7},
	{{1,2,4,2,6},6},
	{{1,2,4,3,3},3},
	{{1,2,6,2,7},6},
	{{2,0,0,0,1},2},
	{{2,0,0,0,2},2},
	{{2,0,0,0,4},2},
	{{2,0,0,0,5},2},
	{{2,0,0,0,7},1},
	{{2,0,0,1,2},2},
	{{2,0,0,1,5},2},
	{{2,0,0,2,1},2},
	{{2,0,0,2,2},2},
	{{2,0,0,2,3},2},
	{{2,0,0,2,4},2},
	{{2,0,0,2,6},0},
	{{2,0,0,2,7},2},
	{{2,0,0,3,2},4},
	{{2,0,0,4,2},3},
	{{2,0,0,4,5},2},
	{{2,0,0,5,4},5},
	{{2,0,0,5,7},5},
	{{2,0,0,6,2},0},
	{{2,0,0,7,2},2},
	{{2,0,0,7,5},2},
	{{2,0,1,0,2},2},
	{{2,0,1,1,2},2},
	{{2,0,1,2,2},2},
	{{2,0,1,4,2},2},
	{{2,0,1,7,2},2},
	{{2,0,2,0,2},2},
	{{2,0,2,0,3},2},
	{{2,0,2,0,5},2},
	{{2,0,2,0,6},5},
	{{2,0,2,0,7},3},
	{{2,0,2,1,2},2},
	{{2,0,2,1,5},2},
	{{2,0,2,2,1},2},
	{{2,0,2,2,2},2},
	{{2,0,2,2,3},2},
	{{2,0,2,3,2},3},
	{{2,0,2,4,2},2},
	{{2,0,2,4,5},2},
	{{2,0,2,5,2},5},
	{{2,0,2,6,2},0},
	{{2,0,2,6,5},0},
	{{2,0,2,7,2},2},
	{{2,0,2,7,5},2},
	{{2,0,3,1,2},2},
	{{2,0,3,2,2},2},
	{{2,0,3,4,2},2},
	{{2,0,3,4,5},2},
	{{2,0,3,7,2},2},
	{{2,0,4,1,2},2},
	{{2,0,4,2,2},2},
	{{2,0,4,4,2},2},
	{{2,0,5,1,2},2},
	{{2,0,5,4,2},5},
	{{2,0,5,7,2},5},
	{{2,0,6,1,2},5},
	{{2,0,6,2,1},2},
	{{2,0,6,4,2},5},
	{{2,0,6,7,2},5},
	{{2,0,7,1,2},2},
	{{2,0,7,2,2},2},
	{{2,0,7,7,2},2},
	{{2,1,1,2,2},2},
	{{2,1,2,2,2},2},
	{{2,1,2,2,3},2},
	{{2,1,2,2,4},2},
	{{2,1,2,2,7},2},
	{{2,1,2,3,2},3},
	{{2,1,3,2,2},2},
	{{2,1,4,2,2},2},
	{{2,1,6,2,2},2},
	{{2,1,7,2,2},2},
	{{2,2,2,2,4},2},
	{{2,2,2,2,7},2},
	{{2,2,2,3,4},2},
	{{2,2,2,3,7},2},
	{{2,2,2,4,3},2},
	{{2,2,2,4,4},2},
	{{2,2,2,7,3},2},
	{{2,2,2,7,7},2},
	{{2,2,3,2,4},3},
	{{2,2,3,2,7},3},
	{{3,0,0,0,1},3},
	{{3,0,0,0,2},2},
	{{3,0,0,0,3},2},
	{{3,0,0,0,4},3},
	{{3,0,0,0,7},4},
	{{3,0,0,1,2},3},
	{{3,0,0,3,2},2},
	{{3,0,0,4,2},1},
	{{3,0,1,0,2},1},
	{{3,0,1,2,5},0},
	{{3,0,2,1,2},3},
	{{3,0,2,4,2},3},
	{{3,0,2,5,2},1},
	{{3,0,2,7,2},3},
	{{3,0,3,3,2},1},
	{{3,1,2,1,2},3},
	{{3,1,2,4,2},3},
	{{3,1,2,5,2},1},
	{{3,1,2,7,2},3},
	{{3,2,4,2,4},3},
	{{3,2,4,2,5},1},
	{{3,2,4,2,7},3},
	{{3,2,5,2,7},1},
	{{3,2,7,2,7},3},
	{{4,0,0,0,0},1},
	{{4,0,0,0,2},1},
	{{4,0,1,0,2},0},
	{{4,0,1,1,2},0},
	{{4,0,1,2,2},0},
	{{4,0,1,2,5},0},
	{{4,0,1,6,2},0},
	{{4,0,2,1,2},0},
	{{4,0,2,1,5},0},
	{{4,0,2,2,2},1},
	{{4,0,2,3,2},1},
	{{4,0,2,6,2},6},
	{{4,0,3,1,2},0},
	{{4,0,3,2,2},1},
	{{5,0,0,0,2},5},
	{{5,0,0,1,2},5},
	{{5,0,0,2,1},5},
	{{5,0,0,2,3},2},
	{{5,0,0,2,4},5},
	{{5,0,0,2,7},5},
	{{5,0,0,4,2},5},
	{{5,0,0,7,2},5},
	{{5,0,2,0,2},2},
	{{5,0,2,0,5},2},
	{{5,0,2,1,2},5},
	{{5,0,2,1,5},2},
	{{5,0,2,4,2},5},
	{{5,0,2,7,2},5},
	{{5,0,3,1,2},0},
	{{6,0,2,0,2},2},
	{{6,0,2,1,2},2},
	{{6,0,2,2,2},0},
	{{6,0,2,4,2},2},
	{{6,0,2,7,2},2},
	{{6,1,2,2,2},0},
	{{6,2,2,2,4},0},
	{{6,2,2,2,7},0},
	{{7,0,1,0,2},0},
	{{7,0,1,1,2},0},
	{{7,0,1,2,2},0},
	{{7,0,1,2,5},0},
	{{7,0,1,6,2},0},
	{{7,0,2,1,2},0},
	{{7,0,2,1,5},0},
	{{7,0,2,2,2},1},
	{{7,0,2,3,2},0},
	{{7,0,2,6,2},6},
	{{7,0,3,1,2},0},
	{{0,1,2,4,3},1},
	{{0,1,2,7,3},1},
	{{0,1,2,9,2},9},
	{{0,1,5,6,2},6},
	{{0,1,6,2,2},6},
	{{0,1,6,3,2},6},
	{{0,1,9,2,4},1},
	{{0,1,9,2,7},1},
	{{0,1,9,4,2},1},
	{{0,1,9,7,2},1},
	{{1,0,1,9,2},9},
	{{1,0,2,1,9},1},
	{{1,0,2,4,9},4},
	{{1,0,2,7,9},7},
	{{1,0,2,9,2},1},
	{{1,0,3,4,2},9},
	{{1,0,3,7,2},9},
	{{1,0,4,9,2},4},
	{{1,0,5,6,2},6},
	{{1,0,6,2,2},6},
	{{1,0,7,9,2},7},
	{{1,0,9,2,1},0},
	{{1,1,1,9,2},1},
	{{1,1,2,1,9},6},
	{{1,1,2,4,9},4},
	{{1,1,2,7,9},7},
	{{1,1,2,9,2},1},
	{{1,1,3,4,2},9},
	{{1,1,3,7,2},9},
	{{1,1,4,9,2},4},
	{{1,1,5,6,2},6},
	{{1,1,6,2,2},6},
	{{1,1,6,9,2},9},
	{{1,1,7,9,2},7},
	{{1,2,2,4,6},6},
	{{1,2,2,7,6},6},
	{{1,2,4,2,9},1},
	{{1,2,4,5,6},6},
	{{1,2,7,2,9},1},
	{{1,2,7,5,6},6},
	{{2,0,0,0,6},0},
	{{2,0,0,3,6},0},
	{{2,0,0,6,5},0},
	{{2,0,1,3,2},2},
	{{2,0,2,0,9},2},
	{{2,0,2,1,9},2},
	{{2,0,2,2,4},2},
	{{2,0,2,2,7},2},
	{{2,0,2,2,9},9},
	{{2,0,2,9,2},2},
	{{2,0,3,1,9},2},
	{{2,0,4,3,2},2},
	{{2,0,7,3,2},2},
	{{2,0,9,1,2},2},
	{{2,0,9,4,2},2},
	{{2,0,9,7,2},2},
	{{2,1,2,2,6},2},
	{{2,1,2,2,9},9},
	{{2,1,2,6,2},2},
	{{2,2,2,2,9},2},
	{{2,2,2,9,4},9},
	{{2,2,2,9,7},9},
	{{2,2,6,2,9},2},
	{{3,0,0,0,6},0},
	{{3,0,2,9,2},1},
	{{3,1,2,9,2},1},
	{{3,2,4,2,9},4},
	{{3,2,7,2,9},7},
	{{4,0,2,1,3},0},
	{{4,0,2,9,2},1},
	{{4,0,5,6,2},6},
	{{4,0,6,2,2},6},
	{{4,0,9,1,2},0},
	{{4,0,9,2,1},0},
	{{4,1,6,2,2},6},
	{{5,0,0,0,6},0},
	{{5,0,0,6,2},0},
	{{5,0,0,6,5},0},
	{{6,0,0,2,2},0},
	{{6,0,2,0,5},0},
	{{6,0,2,1,5},0},
	{{6,0,2,2,1},0},
	{{6,0,2,2,4},0},
	{{6,0,2,2,7},0},
	{{6,0,2,3,2},0},
	{{6,0,2,4,5},0},
	{{6,0,2,7,5},0},
	{{6,0,3,2,1},0},
	{{6,0,9,9,2},2},
	{{6,1,2,1,9},2},
	{{6,1,2,2,5},0},
	{{6,1,2,3,2},0},
	{{6,1,9,9,2},2},
	{{6,2,3,2,4},0},
	{{6,2,3,2,7},0},
	{{6,2,4,9,9},2},
	{{6,2,7,9,9},2},
	{{7,0,2,1,3},0},
	{{7,0,2,9,2},1},
	{{7,0,5,6,2},6},
	{{7,0,6,2,2},6},
	{{7,0,9,1,2},0},
	{{7,0,9,2,1},0},
	{{7,1,6,2,2},6},
	{{9,0,2,1,2},9},
	{{9,0,2,1,3},1},
	{{9,0,2,2,9},9},
	{{9,0,9,1,2},9},
	{{9,1,2,1,2},9},
	{{9,1,2,1,9},9},
	{{9,1,2,2,9},9},
	{{9,1,2,4,2},9},
	{{9,1,2,4,9},9},
	{{9,1,2,7,2},9},
	{{9,1,2,7,9},9},
	{{9,1,2,9,2},1},
	{{9,1,2,9,9},1},
	{{9,1,6,9,2},1},
	{{9,2,2,9,4},9},
	{{9,2,2,9,6},2},
	{{9,2,2,9,7},9}
}



function Sexyloop:conditions ()

	local a,b,c,d,e = self:neighbourhood_state()


	if self.state == 0  and self:neighbourhood_zero() == true then
		return 0
	end


	for k, v in pairs(Sexyloop.transitions) do
		if v[1][1] == a then
			if v[1][2] == b then
				if v[1][3] == c then
					if v[1][4] == d then
						if v[1][5] == e then
							return v[2]
						end
					end
				end
			end

			if v[1][2] == e then
				if v[1][3] == b then
					if v[1][4] == c then
						if v[1][5] == d then
							return v[2]
						end
					end
				end
			end
			if v[1][2] == d then
				if v[1][3] == e then
					if v[1][4] == b then
						if v[1][5] == c then
							return v[2]
						end
					end
				end
			end
			if v[1][2] == c then
				if v[1][3] == d then
					if v[1][4] == e then
						if v[1][5] == b then
							return v[2]
						end
					end
				end
			end
		end
	end


	var any1={0,1,2,3,4,5,6,7,8,9}
	var any2={0,1,2,3,4,5,6,7,8,9}
	var any3={0,1,2,3,4,5,6,7,8,9}
	var any4={0,1,2,3,4,5,6,7,8,9}
	var a1to9={1,2,3,4,5,6,7,8,9}
	var a01={0,1}
	var a235={2,3,5}
	var a467={4,6,7}
	var x1={2,3,4,5,6,7}
	var x2={2,3,4,5,6,7}
	var x3={2,3,4,5,6,7}

	-- surrent state 8 -> 0
	if self.state == 8 then
		return 0
	end

	--curent state 0 or 1 -> 8
	if self.state == 0 or self.state == 1 then

	end

	a01,8,x1,x2,any1,8
	a01,8,x1,x2,x3,8
	a01,8,x1,any1,any2,8
	a01,8,x1,any1,x2,8
	a01,8,any1,any2,x1,8
	a01,8,any1,any2,any3,a01
	a01,8,any1,x1,x2,8
	a01,8,any1,x1,any2,8


	--2 3 5 -> 0
	if self.state == 2 or self.state == 3 or self.state == 5 then
		return 0
	end

	--4 6 7 -> 1
	if self.state == 4 or self.state == 6 or self.state == 7 then
		return 1
	end

	-- 0 -> 0
	if self.state == 0 then
		return 0
	end

	--1..9 -> 8
	return 8

end

function Sexyloop:neighbourhood_other ()
	local a,b,c,d

	function coordinate_state (x, y)
		if self.board.present[x] == nil then
			return 0
		end
		if self.board.present[x][y] == nil then
			return 0
		end
		return self.board.present[x][y].state
	end

	local ret = 0
	local a = coordinate_state(self.x,self.y+1)
	local b = coordinate_state(self.x+1,self.y)
	local c = coordinate_state(self.x,self.y-1)
	local d = coordinate_state(self.x-1,self.y)

	for k, v in pairs({a,b,c,d}) do
		if v == 2 or  v == 3  or  v == 4  or  v == 5 or  v == 6  or v == 7  then
			ret = ret + 1
		end
	end

	return ret
end

function Sexyloop:neighbourhood_zero ()
	local a,b,c,d

	function coordinate_state (x, y)
		if self.board.present[x] == nil then
			return 0
		end
		if self.board.present[x][y] == nil then
			return 0
		end
		return self.board.present[x][y].state
	end

	local ret = 0
	local a = coordinate_state(self.x,self.y+1)
	local b = coordinate_state(self.x+1,self.y)
	local c = coordinate_state(self.x,self.y-1)
	local d = coordinate_state(self.x-1,self.y)

	if a == 0 and  b == 0  and  c == 0  and  d == 0 then
		return true
	else
		return false
	end
end

function Sexyloop:neighbourhood_eight ()
	local a,b,c,d

	function coordinate_state (x, y)
		if self.board.present[x] == nil then
			return 0
		end
		if self.board.present[x][y] == nil then
			return 0
		end
		return self.board.present[x][y].state
	end

	local ret = 0
	local a = coordinate_state(self.x,self.y+1)
	local b = coordinate_state(self.x+1,self.y)
	local c = coordinate_state(self.x,self.y-1)
	local d = coordinate_state(self.x-1,self.y)

	for k, v in pairs({a,b,c,d}) do
		if v == 8 then
			ret = ret + 1
		end
	end

	return ret
end


function Sexyloop:neighbourhood_state ()
	local a,b,c,d

	function coordinate_state (x, y)
		if self.board.present[x] == nil then
			return 0
		end
		if self.board.present[x][y] == nil then
			return 0
		end
		return self.board.present[x][y].state
	end

	local a = coordinate_state(self.x,self.y-1)
	local b = coordinate_state(self.x+1,self.y)
	local c = coordinate_state(self.x,self.y+1)
	local d = coordinate_state(self.x-1,self.y)


	return self.state, a,b,c,d
end
