open_pairs_of_images = {}

open_pairs_of_images.params =
{
	cols = 4,
	rows = 3,
	open_time = 200,
	close_time = 50,
	close_time_shift = 50,
	
	sound_open_one = "turn_item",
	sound_open_pair = "turn_item"
}

function open_pairs_of_images.OnPreferredSize(_owner)
	return sminigames.OnPreferredSize(_owner)
end

function open_pairs_of_images.SetColor(_widget, _color_from, _color_to, _time, _shift)
	local color = _widget.GetColor()
	_widget.SetColor(_color_from)
    _widget.AddEffect(sf.gui.CColorChangeEffect(_color_to, _time, _shift, open_pairs_of_images.data.timer.AttachTimer(_T(""))))
	_widget.SetColor(color)
end

function open_pairs_of_images.Activate(_owner, _index)
	local data = open_pairs_of_images.data
	if	data.active ~= _index and (data.last_active_time == nil or data.timer.GetTime() >= data.last_active_time + data.open_time + data.close_time_shift + data.close_time) then		
        if	data.array[_index].skin then
			local effect = sf.gui.CColorChangeEffect(data.color.hide_skin, data.open_time, 0, data.timer.AttachTimer(_T("")))
            data.array[_index].skin.AddEffect(effect)
			table.insert(open_pairs_of_images.effects, effect)
        end
		local effect = sf.gui.CColorChangeEffect(data.color.open_image, data.open_time, 0, data.timer.AttachTimer(_T("")))		
        data.array[_index].widget.AddEffect(effect)
		table.insert(open_pairs_of_images.effects, effect)
        if	data.active == nil or data.active == 0 then
            data.active = _index
			if open_pairs_of_images.params.sound_open_one then
				sf.core.g_Application.GetAudioManager().Play(open_pairs_of_images.params.sound_open_one, -2, -2, -2, -2, -2)
			end
        else
            if	data.array[_index].widget.GetId() == data.array[data.active].widget.GetId() then
                table.remove(data.array, math.max(_index, data.active))
                table.remove(data.array, math.min(_index, data.active))
				open_pairs_of_images.CheckEnd(_owner)
				if open_pairs_of_images.params.sound_open_pair then
					sf.core.g_Application.GetAudioManager().Play(open_pairs_of_images.params.sound_open_pair, -2, -2, -2, -2, -2)
				end
            else
				open_pairs_of_images.SetColor(data.array[_index].skin, data.color.hide_skin, data.color.open_skin, data.close_time, data.open_time + data.close_time_shift)
				open_pairs_of_images.SetColor(data.array[open_pairs_of_images.data.active].skin, data.color.hide_skin, data.color.open_skin, data.close_time, data.open_time + data.close_time_shift)
				open_pairs_of_images.SetColor(data.array[_index].widget, data.color.open_image, data.color.hide_image, data.close_time, data.open_time + data.close_time_shift)
				open_pairs_of_images.SetColor(data.array[open_pairs_of_images.data.active].widget, data.color.open_image, data.color.hide_image, data.close_time, data.open_time + data.close_time_shift)
				data.last_active_time = data.timer.GetTime()
				if open_pairs_of_images.params.sound_open_one then
					sf.core.g_Application.GetAudioManager().Play(open_pairs_of_images.params.sound_open_one, -2, -2, -2, -2, -2)
				end
            end
            data.active = 0
        end
    end
end

function open_pairs_of_images.RemoveDeadEffects()
	local i = 1
	while i <= #open_pairs_of_images.effects do
		local e = open_pairs_of_images.effects[i]
		assert(e)
		if e.IsDead() == true then
			table.remove(open_pairs_of_images.effects, i)
		else
			i = i + 1
		end
	end
end

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

	open_pairs_of_images.RemoveDeadEffects()
	if open_pairs_of_images.resolved == true and #open_pairs_of_images.effects == 0 then			
		open_pairs_of_images.resolved = false
		_owner.SetGameResult(1)
		_owner.OnEndGame()
	end
end

function open_pairs_of_images.OnMouseDown(_owner, _pos, _button, _state, _broadcast)
    if  _button == sf.gui.CBaseWidget.LeftButton then
		for index in pairs(open_pairs_of_images.data.array) do
			if	open_pairs_of_images.data.array[index].skin	and misc.GetRect(open_pairs_of_images.data.array[index].skin).IsContains(_pos.X, _pos.Y) then
				open_pairs_of_images.Activate(_owner, index)
				break
			end
		end
		return true
    end
    return false
end

function open_pairs_of_images.CheckEnd(_owner)
	if	#open_pairs_of_images.data.array  == 0 then
		open_pairs_of_images.resolved = true
	end
end

function open_pairs_of_images.Init(_owner)
	local data = {}
	data.open_time = open_pairs_of_images.params.open_time
	data.close_time = open_pairs_of_images.params.close_time
	data.close_time_shift = open_pairs_of_images.params.close_time_shift

    data.color = {}
    data.color.hide_image = sf.graphics.Color(255,255,255,255)
    data.color.open_skin = sf.graphics.Color(255,255,255,255)
    data.color.open_image = sf.graphics.Color(255,255,255,255)
    data.color.hide_skin = sf.graphics.Color(0,255,255,255)

    data.second = {}
    data.second.hide_image = sf.graphics.Color(0,255,255,255)
    data.second.open_skin = sf.graphics.Color(255,255,255,255)
    data.second.open_image = sf.graphics.Color(255,255,255,255)
    data.second.hide_skin = sf.graphics.Color(255,255,255,255)
	
	open_pairs_of_images.data = data	
	data.timer = __create_timer("", "qe_level")

	sminigames.SetStandartScriptName(_owner, open_pairs_of_images)
	
	local iterator = _owner.GetWidgets()

	data.array = {}
	-- Поиск всех подходящих изображений
	while iterator.IsEnd() == false do
		local widget = __cast(iterator.Get(), sf.gui.CImageWidget)
		if  widget and widget.GetId() ~= _T("skin") and widget.GetId() ~= _T("back") and widget.GetId() ~= _T("") then
			local index = #data.array + 1
			data.array[index] = {}
			data.array[index].widget = widget
		end
        iterator.Next()
	end	
	
	-- Создание дубликатов для изображений
	local index = 1
	local size = #data.array
	while index <= size do
		data.array[index + size] = {}
		data.array[index + size].widget = sf.gui.CImageWidget(data.array[index].widget.GetImage(), data.array[index].widget.GetId(), data.array[index].widget.GetLayer(), 0)
		_owner.AddWidget(data.array[index + size].widget)
		index = index + 1
	end
	
	assert((open_pairs_of_images.params.rows * open_pairs_of_images.params.cols) == #data.array)
	
	-- Поиск изображения рубашки
	local skin = __cast(_owner.GetWidget(_T("skin"), true), sf.gui.CImageWidget)
	assert(skin)
	
	-- Создание рубашек для изображений
	index = 1
	while index <= #data.array do
		data.array[index].skin = sf.gui.CImageWidget(skin.GetImage(), skin.GetId(), skin.GetLayer(), 0)
		_owner.AddWidget(data.array[index].skin)
		index = index + 1
	end
	
	skin.AddFlags(sf.gui.CWidget.FlagHidden)
	
	-- Поиск изображения фона
	local back = __cast(_owner.GetWidget(_T("back"), true), sf.gui.CImageWidget)		
	assert(back)

	local size = back.GetSize()
	local elem_size = skin.GetSize()		
	local dist = sf.misc.FloatVector(0.0, 0.0)
	
	dist.X = (size.X - elem_size.X * open_pairs_of_images.params.cols) / (open_pairs_of_images.params.cols + 1.0)
	dist.Y = (size.Y - elem_size.Y * open_pairs_of_images.params.rows) / (open_pairs_of_images.params.rows + 1.0)
		
	data.place_array = {} 
	for i=1, open_pairs_of_images.params.rows do
		for j=1, open_pairs_of_images.params.cols do
			local n = (i-1) * open_pairs_of_images.params.cols + j
			data.place_array[n] = sf.misc.FloatVector(0.0, 0.0)
			data.place_array[n].X = elem_size.X * (j-1) + dist.X * j
			data.place_array[n].Y = elem_size.Y * (i-1) + dist.Y * i
		end
	end
	
    -- Расстановка по местам
	math.randomseed(os.time())
	index = 1
	while index <= #data.array do
		if	#data.place_array then
			local place = math.random(#data.place_array)
			data.array[index].widget.SetOffset(data.place_array[place].X, data.place_array[place].Y)
			if	data.array[index].skin then
				data.array[index].skin.SetOffset(data.place_array[place].X, data.place_array[place].Y)
			end
			table.remove(data.place_array, place)
		else
			break
		end
        index = index + 1
	end
    
    -- Раскраска 
	if	skin and #data.array then
        if  skin.GetLayer() < data.array[#data.array].widget.GetLayer() then
            data.color = data.second
        end 
    end
	index = 1
	while index <= #data.array do
        data.array[index].widget.SetColor(data.color.hide_image)
        local a = data.color.hide_image.Alpha
        local r = data.color.hide_image.Red
        local g = data.color.hide_image.Green
        local b = data.color.hide_image.Blue
        if  skin then
            data.array[index].skin.SetColor(data.color.open_skin)
            a = data.color.open_skin.Alpha
            r = data.color.open_skin.Red
            g = data.color.open_skin.Green
            b = data.color.open_skin.Blue
        end
        index = index + 1
    end

    local size = _owner.GetPreferredSize()
	_owner.SetSize(size.X, size.Y)
	
	open_pairs_of_images.effects = {}
	
	open_pairs_of_images.resolved = false
end
