repeat_sequences = {}

repeat_sequences.params = 
{
	sequences = 
	{
		{14, 7, 11},
		{1, 17, 10},
		{14, 13, 8, 19},
		{2, 18, 9, 15, 4, 16},
		{12, 3, 5, 6, 20, 21}
	},
	
	pause_before_show = 1500, -- мс. пауза перед показом последовательности
	wink_period = 800, -- мс. скорость моргания - сколько времени требуется на "загорание" и "потухание" одного камня
	
	sounds_on_click = 
	{
		"",
		"",
		"",
		""
	},
	
	sound_click = "indicator",
	sound_error = "mini_game_repeat_sequences_error_01",
	
	-- настройки текста заклинания, который появляется по ходу кликания по словам
	text_rect = sf.misc.FloatRect(10.0, 440.0, 380.0, 50), -- рамка текста
	text_space_width = 5, -- расстояние между словами
	text_line_width = 25 -- высота строки
}

function repeat_sequences.OnUpdate(_owner)
	local i = 1
	while i <= #repeat_sequences.effects do
		local effect = repeat_sequences.effects[i]
		assert(effect)
		if not effect.is_dead then
			effect:Update(repeat_sequences.timer.Get().GetTime())
		end
		if effect.is_dead then
			table.remove(repeat_sequences.effects, i)			
		else
			i = i+1
		end
	end
end

function repeat_sequences.OnInput(_owner, _number, _widget)
	assert(#repeat_sequences.input < #repeat_sequences.sequence)
	
	sound(repeat_sequences.params.sound_click)
	table.insert(repeat_sequences.input, _number)
	repeat_sequences.text[#repeat_sequences.input].RemFlags(sf.gui.CBaseWidget.FlagHidden)
	
	for i,_ in ipairs(repeat_sequences.input) do
		if repeat_sequences.input[i]~=repeat_sequences.sequence[i] then
			-- неправильно повторили последовательность
			sound(repeat_sequences.params.sound_error)
			repeat_sequences.ClearText(_owner)
			repeat_sequences.ShowNextSequence(_owner)			
			return
		end
	end
	
	local button = __cast(_widget, sf.gui.CButtonWidget)
	assert(button)
	
	if #repeat_sequences.input == #repeat_sequences.sequence then
		-- ввели все правильно
		if repeat_sequences.current_sequence >= #repeat_sequences.params.sequences then
			-- это была последняя последовательность			
			_owner.SetGameResult(1)
			_owner.OnEndGame() 			
		else
			-- показываем следующую последовательность
			repeat_sequences.current_sequence = repeat_sequences.current_sequence + 1
			repeat_sequences.sequence = repeat_sequences.params.sequences[repeat_sequences.current_sequence]
			repeat_sequences.ShowNextSequence(_owner)
		end
	end
end

function repeat_sequences.OnChildAction(_owner, _action, _child)
	if	_action.c_str() == "pressed" then
		local number = tonumber(_child.GetId().c_str())
		if number then
			-- нажали кнопку с ид "1","2","3"...
			if repeat_sequences.params.sounds_on_click and repeat_sequences.params.sounds_on_click[number] then
				sf.core.g_Application.GetAudioManager().Play(repeat_sequences.params.sounds_on_click[number], -2, -2, -2, -2, -2)
			end
			repeat_sequences.OnInput(_owner, number, _child)
		end
	end
end

function repeat_sequences.Init(_owner)
	sminigames.SetStandartScriptName(_owner, repeat_sequences)
	
	repeat_sequences.timer = sf.core.CTimerWrapper(sf.core.g_Application.GetTimeManager().AttachTimer(_T(""), nil))
	repeat_sequences.effects = {}
	
	assert(#repeat_sequences.params.sequences>0)
	repeat_sequences.current_sequence = 1
	repeat_sequences.sequence = repeat_sequences.params.sequences[1]
	
	repeat_sequences.max_value = 0
	for i=1, #repeat_sequences.params.sequences do
		for j=1, #repeat_sequences.params.sequences[i] do
			if repeat_sequences.params.sequences[i][j] > repeat_sequences.max_value then
				repeat_sequences.max_value = repeat_sequences.params.sequences[i][j]
			end
		end
	end
	
	repeat_sequences.images = {}
	for i=1, repeat_sequences.max_value do
		local button = __cast(_owner.GetWidget(tostring(i)), sf.gui.CButtonWidget)
		if button then
			local iterator = button.GetWidgets()
			local image_widget, image = nil, nil
			if iterator.IsEnd() == false then
				image_widget = __cast(iterator.Get(), sf.gui.CImageWidget)
			end
			if image_widget then
				image = sf.graphics.CImage(image_widget.GetImage().GetTexture())
				local source_rect = sf.misc.FloatRect(image.GetRect())
				source_rect.X = source_rect.Width * 0.75
				source_rect.Width = source_rect.Width * 0.25
				local rect = sf.misc.FloatRect(image.GetRect())
				rect.X = -rect.Width * 0.75
				rect.Width = rect.Width * 0.25
				image.SetSourceRect(source_rect)
				image.SetRect(rect)				
				repeat_sequences.images[i] = image
			end
		end
	end

	repeat_sequences.ShowNextSequence(_owner)
end

function repeat_sequences.ShowNextSequence(_owner)
	assert(repeat_sequences.current_sequence <= #repeat_sequences.params.sequences)	
	repeat_sequences.input = {}
	local t = repeat_sequences.timer.Get().GetTime()
	local sequence = repeat_sequences.params.sequences[repeat_sequences.current_sequence]
	local effect = repeat_sequences.PlaySequenceEffect(_owner, sequence, 
		t, -- время создания эффекта
		t + repeat_sequences.params.pause_before_show, -- время начала показывания последовательности
		t + repeat_sequences.params.pause_before_show + #sequence * repeat_sequences.params.wink_period) -- время завершения показывания последовательности
	table.insert(repeat_sequences.effects, effect)		
end

function repeat_sequences.ClearText(_owner)
	local text_widget_id = _T("text_widget")
	local text_widget_ptr = _owner.GetWidget(text_widget_id)
	if text_widget_ptr then
		_owner.RemoveWidget(text_widget_ptr)
		text_widget_ptr = nil
	end		
end

function repeat_sequences.BuildText(_owner)
	repeat_sequences.ClearText(_owner)
	
	local text_widget_id = _T("text_widget")
	
	local text_widget = sf.gui.CWidget(text_widget_id, 15, 0)
	text_widget.SetOffset(repeat_sequences.params.text_rect.X, repeat_sequences.params.text_rect.Y)
	text_widget.SetSize(repeat_sequences.params.text_rect.Width, repeat_sequences.params.text_rect.Height)	
	
	local text_widget_ptr = sf.gui.CWidgetPtrT(text_widget)	
	_owner.AddWidget(text_widget_ptr)
	
	repeat_sequences.text = {}
	local sequence = repeat_sequences.params.sequences[repeat_sequences.current_sequence]
	local offset = sf.misc.FloatVector(0.0, 0.0)
	for i=1, #sequence do
		local button_id = sequence[i]
		local image = repeat_sequences.images[button_id]
		assert(image)
		if offset.X + image.GetRect().Width > repeat_sequences.params.text_rect.Width then 
			offset.X = 0.0
			offset.Y = offset.Y + repeat_sequences.params.text_line_width
		end
		local image_widget = sf.gui.CImageWidget(image, _T(""), 0, 0)
		image_widget.AddFlags(sf.gui.CBaseWidget.FlagHidden)
		image_widget.SetOffset(offset.X, offset.Y)
		local image_widget_ptr = sf.gui.CImageWidgetPtrT(image_widget)
		text_widget.AddWidget(image_widget_ptr)
		offset.X = offset.X + image.GetRect().Width + repeat_sequences.params.text_space_width
		repeat_sequences.text[i] = image_widget
	end
end

function repeat_sequences.PlaySequenceEffect(_owner, _sequence, _create_time, _start_time, _target_time)
	return
	{
		_owner = _owner,
		_sequence = _sequence,
		_create_time = _create_time,
		_start_time = _start_time,
		_target_time = _target_time,
		
		is_dead = false,
		
		Update = function(_self, _time)
			if _time < _self._start_time then
				
				-- пауза перед началом показа последовательности
				-- делаем все элементы недоступными
				
				for i = 1, repeat_sequences.max_value do
					local button = __cast(_self._owner.GetWidget(tostring(i)), sf.gui.CButtonWidget)
					if button then
                        button.DisableButton(false)
                        button.AddFlags(sf.gui.CBaseWidget.FlagDisabled)
                    end
				end
				
			elseif _self._start_time <= _time and _time < _self._target_time then
			
				if not _self._stage2 then
					_self._stage2 = true
					repeat_sequences.BuildText(_owner)
				end
				
				-- считаем, какой элемент должен сейчас подсвечиваться
				
				local len = #_self._sequence
				local t1 = (_self._target_time - _self._start_time) / len
				local t2 = math.mod(_time - _self._start_time + t1, t1)
				local index = math.floor((_time - _self._start_time) / t1) + 1
				local button_id = _self._sequence[index]
				for i = 1, repeat_sequences.max_value do
					local button = __cast(_self._owner.GetWidget(tostring(i)), sf.gui.CButtonWidget)
					if button then
						local disable = (i == button_id) and (t2 < (t1 / 2.0))
						if disable and button.GetButtonState() ~= sf.gui.CButtonWidget.StateDisabled then
							sound(repeat_sequences.params.sound_click)
						end
					    button.DisableButton(disable)
                    end
				end
				
			else
			
				-- закончили показывать последовательность
				-- делаем все элементы доступными
				
				for i = 1, repeat_sequences.max_value do
					local button = __cast(_self._owner.GetWidget(tostring(i)), sf.gui.CButtonWidget)
					if button then
						button.DisableButton(false)
                        button.RemFlags(sf.gui.CBaseWidget.FlagDisabled)
                    end
				end

				_self.is_dead = true
			end
			
			_owner.OnMouseMove(sf.misc.IntVector(-1000,-1000), 0, true)
		end
	}
end
