repeat_sequences = {}

repeat_sequences.params = 
{
	sequences = 
	{
		{1, 2, 1},
		{1, 2, 1, 4},
		{1, 2, 1, 4, 2},
		{1, 2, 1, 4, 2, 3},
		{1, 2, 1, 4, 2, 3, 1, 4}
	},
	
	pause_before_show = 1000, -- мс. пауза перед показом последовательности
	wink_period = 900, -- мс. скорость моргания - сколько времени требуется на "загорание" и "потухание" одного камня
	
	-- настройки лампочек-индикаторов
	indicators_pos = sf.misc.FloatVector(97.0, 25.0), -- позиция первого индикатора
	indicators_dist = 27.0, -- расстояние между индикаторами
	
	sounds_on_click = 
	{
		"mini_game_repeat_sequences_button_01",
		"mini_game_repeat_sequences_button_02",
		"mini_game_repeat_sequences_button_03",
		"mini_game_repeat_sequences_button_04"
	},
	
	sound_error = "mini_game_repeat_sequences_error_01"
}

function repeat_sequences.UpdateIndicators()
	for i = 1, #repeat_sequences.params.sequences do
		if i == repeat_sequences.current_sequence then
			repeat_sequences.indicators[1][i].RemFlags(sf.gui.CBaseWidget.FlagHidden)
		else
			repeat_sequences.indicators[1][i].AddFlags(sf.gui.CBaseWidget.FlagHidden)
		end
		if i < repeat_sequences.current_sequence then
			repeat_sequences.indicators[2][i].RemFlags(sf.gui.CBaseWidget.FlagHidden)
		else
			repeat_sequences.indicators[2][i].AddFlags(sf.gui.CBaseWidget.FlagHidden)
		end
	end
end

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)
	
	table.insert(repeat_sequences.input, _number)
	
	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.UpdateIndicators()
			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.UpdateIndicators()
			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.indicator1_image = __cast(_owner.GetWidget(_T("indicator1"), true), sf.gui.CImageWidget)
	assert(repeat_sequences.indicator1_image)
	repeat_sequences.indicator1_image.AddFlags(sf.gui.CBaseWidget.FlagHidden)
	
	repeat_sequences.indicator2_image = __cast(_owner.GetWidget(_T("indicator2"), true), sf.gui.CImageWidget)
	assert(repeat_sequences.indicator2_image)
	repeat_sequences.indicator2_image.AddFlags(sf.gui.CBaseWidget.FlagHidden)	

	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.indicators = {}
	repeat_sequences.indicators[1] = {}
	repeat_sequences.indicators[2] = {}
	
	for i = 1, #repeat_sequences.params.sequences do	
		local offset = sf.misc.FloatVector(
			repeat_sequences.params.indicators_pos.X + (i-1) * repeat_sequences.params.indicators_dist,
			repeat_sequences.params.indicators_pos.Y )
		
		local widget1 = sf.gui.CImageWidget(repeat_sequences.indicator1_image.GetImage(), _T(""), 0, 0)		
		widget1.SetOffset(offset.X, offset.Y)
		local widget1_ptr = sf.gui.CImageWidgetPtrT(widget1)
		
		local widget2 = sf.gui.CImageWidget(repeat_sequences.indicator2_image.GetImage(), _T(""), 0, 0)
		widget2.SetOffset(offset.X, offset.Y)
		local widget2_ptr = sf.gui.CImageWidgetPtrT(widget2)
		
		_owner.AddWidget(widget1_ptr)		
		table.insert(repeat_sequences.indicators[1], widget1)
		_owner.AddWidget(widget2_ptr)		
		table.insert(repeat_sequences.indicators[2], widget2)
	end
	repeat_sequences.UpdateIndicators()
	
	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.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.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
				
				-- считаем, какой элемент должен сейчас подсвечиваться
				
				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
							if repeat_sequences.params.sounds_on_click and repeat_sequences.params.sounds_on_click[i] then
								sf.core.g_Application.GetAudioManager().Play(repeat_sequences.params.sounds_on_click[i], -2, -2, -2, -2, -2)
							end
						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
