--[[
Изначально есть 4 окошка в котором прокручиваются числа.
В первых 3х окошках около 10 чисел
В последнем окошке четыре числа, каждое число выделено своим цветом.
Над окошками находятся 4 лампочки. Изначально они выключены.
Если игрок не найдет трафарет для прохождения игры, он не смоежт начать игру, т.к. механизм неактивен.

Когда игрок находит трафарет и прикладывает к механизму, он видит, что необходимо сложить первое число со вторым, вычесть третье и получить четвертое. 
Как только какая-то из последовательностей составлена правильно, подсвечивается лампочка того цвета, сумма для числа какого цвета найдена.

Игра пройдена, когда все лампочки включены
]]

count_several_equations = {}
local self = count_several_equations
self.params = 
{
	init_numbers = {1, 1, 1, 1}, -- номер элмента в полоске при загрузке игры
	num_values =  -- значения чисел на полосочках
	{
		{28, 23, 14, 2, 8},
		{5, 13, 24, 20, 1},
		{6, 11, 3, 17, 10},
		{44, 15, 46, 6}
	},
	--[[password = {, -- для первого результата вычислений
				{4, 3, 2, 2}, -- для второго результата вычислений
				{1, 3, 1, 3}, -- для третьего результата вычислений
				{5, 5, 3, 4} -- для четвертого результата вычислений
			},]]
	horizontal = false,
	states = {5, 5, 5, 4}, -- количество состояний для каждой ленточки
	move_time = 500,
	luck_id = "lamp", -- id в dsfrontend для результатов вычислений
	
	fin_clip = "scene04_04_minigame", -- клип на победу
	--звуки
	sound_on_click = "select_part",
	sound_lever = "rotation_ring" -- звук поворота рычага
}

-- функция для перемещения по горизонтали/вертикали в зависимости от настроек
local add_delta = function(_pos, _delta)
	if self.params.horizontal then
		_pos.X = _pos.X - _delta
	else
		_pos.Y = _pos.Y - _delta
	end
end

function self.Init(_owner)
	sminigames.SetStandartScriptName(_owner, count_several_equations)
	self.moves = {}
	
	self.timer = __create_timer("", "qe_level")
	
	self.images = nil
	
	_owner.AddFlags(sf.gui.CBaseWidget.FlagClipDraw)
	
	self.handle = __cast(_owner.GetWidget("handle", true), sf.gui.CImageWidget) 
	-- находим все изображения
	self.images = {}
	self.luck = {}
	local i = #self.params.init_numbers
	local w = _owner.GetWidgets()	
	while not w.IsEnd() do
		local widget = __cast(w.Get(), sf.gui.CImageWidget) 
		if widget then
			local id = tonumber(widget.GetId().c_str())
			if id then -- ид должен быть числом				
				local init_number = 1
				if i > 0 then init_number = self.params.init_numbers[i] end
				local pos = sf.misc.FloatVector(widget.GetOffset())
				local size, rect = nil, sf.misc.FloatRect(pos.X, pos.Y, 0.0, 0.0)
				-- размер ячейки по горизонтали/вертикали в зависимости от настроек
				if self.params.horizontal then
					size = widget.GetSize().X
					size = size / (self.params.states[i] + 2)
					rect.Width = size
					rect.Height = widget.GetSize().Y
				else
					size = widget.GetSize().Y
					size = size / (self.params.states[i] + 2)
					rect.Width = widget.GetSize().X
					rect.Height = size
				end				

				local init_pos = sf.misc.FloatVector(pos)
				local number = init_number
				if number == 0 then number = self.params.states[i] end
				add_delta(init_pos, size * number)
				widget.SetOffset(init_pos.X, init_pos.Y)

				self.images[id] = { widget = widget, number = number, size = size, rect = rect}
				
				i = i-1
			--[[elseif string.find(widget.GetId().c_str(), self.params.luck_id) then
				table.insert(self.luck, widget)
				widget.AddFlags(sf.gui.CWidget.FlagHidden)]]
			else
				self.back_image = widget
			end
		end
		w.Next()
	end
	for i = 1, # self.params.num_values[#self.params.num_values] do
		local id = self.params.luck_id
		if i < 10 then
			id = id .. 0
		end
		id = id .. i
		local widg = __cast(_owner.GetWidget(id, true), sf.gui.CImageWidget)
		if widg then
			table.insert(self.luck, widg)
			if (sminigames.save and sminigames.save[i] == 0) or not sminigames.save then
				widg.AddFlags(sf.gui.CWidget.FlagHidden)
			end
		end
	end
	
	self.state = self.params.init_numbers
	if not sminigames.save then
		sminigames.save = {}
		for i = 1, # self.params.num_values[#self.params.num_values] do
			table.insert(sminigames.save, 0)
		end
	end
end

function self.OnMouseMove(_owner, _pos, _state, _broadcast)
	if self.win then
		return true
	end
	
	for id, image in pairs(self.images) do
		if not self.moves[id] and image.rect.IsContains(_pos.X, _pos.Y) and id ~= #self.images then
			sf.gui.g_Cursor.Instance().SetCursor(sf.gui.CCursor.CursorHand)
			return true
		end
	end
	return false
end

function self.OnMouseDown(_owner, _pos, _button, _state, _broadcast)
	for id, image in pairs(self.images) do
		if not self.moves[id] and image.rect.IsContains(_pos.X, _pos.Y)and id ~= #self.images then		
			local direction = (_button==_owner.LeftButton and 1 or -1)
			self.MoveRibbon(id, direction)
			return true
		end
	end
	return false
end

-- сдвинуть _id в направлении _dir
function self.MoveRibbon(_id, _dir)
	self.moves[_id] = { start_time = self.timer.Get().GetTime(), direction = _dir}
	self.state[_id] = self.state[_id] + self.moves[_id].direction
	if self.state[_id] < 1 then
		self.state[_id] = #self.params.num_values[_id]
	elseif self.state[_id] > #self.params.num_values[_id] then
		self.state[_id] = 1
	end
	if self.params.sound_on_click then
		sound(self.params.sound_on_click)
	end
end

function self.OnUpdate(_owner) 
	if  sf.core.g_Application.GetTimeManager().GetTimer(_T("qe_level")).GetK() < 0.01 then
		return
	end

	if not self.timer then return end
	if self.need_move_last then
		self.need_move_last = false
		self.MoveRibbon(#self.images, 1)
	end
	if self.start_win then
		if self.params.sound_lever then
			sound(self.params.sound_lever)
		end
		local clip_time = qe.GetClipTime(self.handle_clip.GetClip())
		if self.timer.Get().GetTime() - self.start_win >= clip_time then
			_owner.SetGameResult(1)
			_owner.OnEndGame()
			self.moves = {}
			self.timer = nil
		end
	else
		local time = self.timer.Get().GetTime()
		
		-- перемещаем двигающиеся изображения
		for id,move in pairs(self.moves) do
			local image = self.images[id]
			local new_pos = sf.misc.FloatVector(image.rect.X, image.rect.Y)
			
			if time < move.start_time + self.params.move_time then
				-- в процессе перемещения
				local delta = image.number*image.size + move.direction*(time - move.start_time)/self.params.move_time*image.size
				add_delta(new_pos, delta)
				image.widget.SetOffset(new_pos.X, new_pos.Y)
			else
				-- пермещение закончилось
				-- удаляем перемещение
				self.moves[id] = nil
				-- перемещаем изображение на 1 вперед
				image.number = image.number + move.direction
				if image.number > self.params.states[id] then
					image.number = 1
				elseif image.number < 1 then 
					image.number = self.params.states[id]
				end
				local delta = image.number * image.size 
				add_delta(new_pos, delta)
				image.widget.SetOffset(new_pos.X, new_pos.Y)
				-- проверяем победу
				self.CheckVictory(_owner)
			end
		end
	end
end

function self.CheckVictory(_owner)
	local all_visible = true
	local a = self.params.num_values[1][self.state[1]]
	local b = self.params.num_values[2][self.state[2]]
	local c = self.params.num_values[3][self.state[3]]
	local d = self.params.num_values[4][self.state[4]]
	if a + b - c == d then -- установили для i-го пароля верную последовательность
		self.luck[self.state[4]].RemFlags(sf.gui.CWidget.FlagHidden)
		sminigames.save[self.state[4]] = 1
		self.need_move_last = true
		--self.MoveRibbon(#self.images, 1)
	end
	for i = 1, #self.params.num_values[#self.params.num_values] do
		if __and(sf.gui.CWidget.FlagHidden, self.luck[i].GetFlags()) ~= 0 then
			all_visible = false
			break
		end
	end 
	if all_visible then
		self.handle.AddFlags(sf.gui.CWidget.FlagHidden)
		self.handle_clip = sf.gui.CClipWidget("", 0, 0)
		self.handle_clip.GetClip().Load(self.params.fin_clip, true)
		_owner.AddWidget(self.handle_clip)
		self.start_win = self.timer.Get().GetTime()
		
		self.win = true
	--	_owner.SetGameResult(1)
	--	_owner.OnEndGame()
	--	self.moves = {}
	--	self.timer = nil
	end
end