-- модуль реализует белый тотем
totems_widget = totems_widget or {}
totems_widget._totem_effect_create_functions = totems_widget._totem_effect_create_functions or {}
totems_widget._totem_load_options_functions = totems_widget._totem_load_options_functions or {}

-- настрйоки тотема
totems_widget._white_totem_options = {
	paint_ball_start_pos = sf.misc.FloatVector(0, 0), -- стартовая позиция для шарика
	paint_ball_fly_speed = 800, -- скорость полета шарика с краской
	
	colors_map = 
	{
		[s11.CFieldCap.CapTypeGreen] = sf.graphics.Color(255, 155, 255, 255),
		[s11.CFieldCap.CapTypeYellow] = sf.graphics.Color(255, 255, 155, 255),
		[s11.CFieldCap.CapTypeRed] = sf.graphics.Color(255, 255, 255, 155),
		[s11.CFieldCap.CapTypeBlue] = sf.graphics.Color(255, 155, 155, 255),
		[s11.CFieldCap.CapTypeOrange] = sf.graphics.Color(255, 255, 155, 155),
		[s11.CFieldCap.CapTypeWhite] = sf.graphics.Color(255, 155, 255, 155),
		[s11.CFieldCap.CapTypeViolet] = sf.graphics.Color(255, 155, 155, 155)
	}
}

-- карта соотнасящая индексы цветов с их id
local colors_id_map = 
{
	[s11.CFieldCap.CapTypeGreen] = "green",
	[s11.CFieldCap.CapTypeYellow] = "yellow",
	[s11.CFieldCap.CapTypeRed] = "red",
	[s11.CFieldCap.CapTypeBlue] = "blue",
	[s11.CFieldCap.CapTypeOrange] = "orange",
	[s11.CFieldCap.CapTypeWhite] = "white",
	[s11.CFieldCap.CapTypeViolet] = "violet"
}

-- функция загрузки специфичных для тотема параметров
totems_widget._totem_load_options_functions[s11.CFieldCap.CapTypeWhite] = function (_totems_info)

	local options = totems_widget._white_totem_options
	
	options.paint_ball_start_pos = totems_widget.GetAbsOffset(StringToFloatVector(_totems_info.GetValue("paint_ball_start_pos").c_str()))
	options.paint_ball_fly_speed = tonumber(_totems_info.GetValue("paint_ball_fly_speed").c_str()) or 0
	options.paint_water_time = tonumber(_totems_info.GetValue("paint_water_time").c_str()) or 0
	local color_info = _totems_info.GetChildRef("paint_colors", false)
	if not color_info then
		__message("Color information for white totem not found")
	else
		for index, color_id in pairs(colors_id_map) do
			options.colors_map[index] = string_to_color(color_info.GetValue(color_id).c_str())
		end
	end
	local drop_image = sf.graphics.CImage("TEMP_paint_drop")
	totems_widget._drop_image_texture = drop_image.GetTexture()
	local texture_size = drop_image.GetTextureSize()

	totems_widget._drop_image_offset_x = -texture_size.X/2
	totems_widget._drop_image_offset_y = -texture_size.Y/2
	
end

-- добавление эффекта перекрашивания фишки
-- _cell - ячейка по которой будет нанесен удар
-- _color - итоговый цвет
-- _start_pos - начальаня позиция
-- _speed - скорость полета капли
local CreatePaintCellEffect = function(_cell, _color, _start_pos, _speed)
    local new_child_effect = 
    {
        Init = function(_self, _total_time, _start_pos, _cell, _color)
					
			_self._image = sf.graphics.CImage(totems_widget._drop_image_texture)
			
			_self._image_color = totems_widget._white_totem_options.colors_map[_color]
			_self._image.SetColor(_self._image_color)
	
			_self._end_pos = game_helpers.GetFieldPos() + _cell.GetCapPos(true)
			_self._cell = _cell
			_self._color = _color
			_self._start_pos = _start_pos
            _self._start_time = effects_widget.effects_timer.Get().GetTime()
			_self._total_time = CalcTimeForVector(_self._start_pos, _self._end_pos, _speed)
            _self._end_time = _self._start_time + _self._total_time
			
			
			local p1 = sf.misc.FloatVector(_start_pos)
			local p2 = sf.misc.FloatVector(_self._end_pos)
			local p3 = sf.misc.FloatVector(_self._end_pos)

			
			if p3.Y < p1.Y then
				p2.X = p2.X - 4
				p2.Y = p2.Y - 1
			else
				p2.X = p2.X - 5
				p2.Y = p2.Y - 3
			end
			
			_self._a = (p3.Y - (p3.X * (p2.Y - p1.Y) + p2.X * p1.Y - p1.X * p2.Y) / (p2.X - p1.X))/(p3.X * (p3.X - p1.X - p2.X) + p1.X * p2.X)

			_self._b = (p2.Y - p1.Y) / (p2.X - p1.X) - _self._a * (p1.X + p2.X)

			_self._c = (p2.X * p1.Y - p1.X * p2.Y) / (p2.X - p1.X) + _self._a * p1.X * p2.X
			
			_self._particle_effect = effects_widget.visual_effects:CreateEffect("PaintFlyEffect", _start_pos)            
			local child_effect = _self._particle_effect:GetChildEffect("colored_trail")
			child_effect:SetColor(_self._image_color)
        end,

        Draw = function(_self, _renderer)
			if _self._fly_obj_pos ~= nil then
				local pos = _self._fly_obj_pos
				_renderer.PushState()
				_renderer.ApplyMatrix( sf.misc.MatrixTranslation(pos.X + totems_widget._drop_image_offset_x, pos.Y + totems_widget._drop_image_offset_y))
				_self._image.Draw(_renderer)
				_renderer.PopState()
			end
        end,

        Update = function(_self, _time)
            local koef = (_time - _self._start_time)/_self._total_time
			_self._fly_obj_pos = totems_widget.ParabolaFlyFunction( _self._start_pos, _self._end_pos, koef, _self._a, _self._b, _self._c)
			_self._particle_effect:SetPos(_self._fly_obj_pos)
            if _time > _self._end_time then
                _self:InstantApply()
            end
        end,

        InstantApply = function(_self)
            if not _self._is_dead then
				-- проверяем что пока краска летела ячейка осталось такой же 
				-- и ее можно перекрашивать(в ней ест ьцветная фишка)
				_self._particle_effect:Kill(false)
				local cap = _self._cell.GetCap()
				-- !!! код проверки фишки на возможность покраски дублируется
				-- !!! похожая проверка инициируется из s11.game_helpers.GetRandomColoredCell и реализуется в функции
				-- !!! IsAvailableForChangeColor расположеной в модуле GameHelpers.cpp
				-- !!! нужно это учесть если потребуется внести изменние в проверку фишку на фозможност перекраски
				if _self._cell.IsFree() and cap and cap.IsColored() then
					-- перекрашвиаем
					game_window.game_field.ChangeCapType(_self._cell, _self._color)
					local new_effect = effects_widget.visual_effects:CreateInstantEffect("PaintHit", _self._fly_obj_pos)
					new_effect:SetColor(_self._image_color)
				end
			end

            _self._is_dead = true
        end,

		IsDead = function(_self)
			return _self._is_dead
		end,
    }
	-- инициализация эффекта
	new_child_effect:Init(_fly_time, 
						  _start_pos, 
						  _cell, 
						  _color)
	-- добавление эффекта
	effects_widget.add_effect(new_child_effect)
	return new_child_effect
end

-- функция созданяи эффекта белого тотема
totems_widget._totem_effect_create_functions[s11.CFieldCap.CapTypeWhite] = function ()
    local new_child_effect = 
    {
		_options = totems_widget._white_totem_options,
	
        Init = function(_self, _work_info)
			assert(totems_widget.active_totem._bonus_color)
			local random_color = totems_widget.active_totem._bonus_color
				--game_window.game_field.GetRandomColor()
			_self._end_time = totems_widget._totem_work_time + totems_widget.effects_timer.Get().GetTime()
			_self._child_effects = {}
			-- перекрашиваем нужное количество ячеек
			
			for i = 1,_work_info.perk1 do
				-- получаем ячейку, которую можно перекрасить
				local target_cell = s11.game_helpers.GetRandomColoredCell(game_window.game_field)
				if not target_cell then
					break
				end
				-- добавляем эффект перекрашивания ячейки
				local new_effect = _self._CreatePaintCellEffect(target_cell, 
				                             random_color, 
											 _self._options.paint_ball_start_pos, 
											 _self._options.paint_ball_fly_speed)
				table.insert(_self._child_effects, new_effect)
			end
        end,

        Draw = function(_self, _renderer)
        end,

        Update = function(_self, _time)
			local all_is_dead = true
			for _,o in ipairs(_self._child_effects) do
				if not o:IsDead() then
					all_is_dead = false
					break
				end
			end
			if all_is_dead then
				game_window.game_field.InitMatchesCheck()
				_self:InstantApply()
			end
        end,

        InstantApply = function(_self)
            _self._is_dead = true
        end,
		
		IsDead = function(_self)
			return _self._is_dead
		end,
		
		_CreatePaintCellEffect = CreatePaintCellEffect
    }
    return new_child_effect
end

