town_effects = {}

__inherite(town_effects, null_lua_widget_handler())

town_effects._icon_hit_effect_offset = sf.misc.FloatVector(22, 22)
town_effects._icon_show_time = 400
town_effects._icon_max_alpha = 200

function town_effects.__CreateInstance()
    return "town_effects"
end

function town_effects.Load(_this, _info, _templates)

	town_effects.visual_effects = visual_effects.CreateEffectsList()
	town_effects._fly_res_font = sf.core.g_Application.GetResourceManager().GetFont(town_window._fly_res_font_id)
	return true

end

function town_effects.GetEffectsList()
	return town_effects.visual_effects
end

function town_effects.DoUpdate(_this)

	
	town_effects.visual_effects:Update()

	local size = #(town_window.effects_list)
	if size ~= 0 then
		local current_time = town_window._town_timer.Get().GetTime()
		local i = 1
		while i <= size do
			town_window.effects_list[i]:Update(current_time)
			if town_window.effects_list[i]:IsDead() then
				table.remove(town_window.effects_list, i)
				size = size - 1
				i = i - 1
			end
			i = i + 1
		end
	end

	return false
end

function town_effects.DoDraw(_this, _renderer)
	town_effects.visual_effects:PostDraw(_renderer)

	local size = #(town_window.effects_list)
	if size ~= 0 then
		for i = 1, size do
			town_window.effects_list[i]:Draw(_renderer)
		end
	end
	
    return false
end

function town_effects.OnMouseMove(_this, _pos, _state, _broadcast)
    return false
end

function town_effects.OnMouseUp(_this, _pos, _button, _state, _broadcast)
    return false
end

function town_effects.OnMouseDown(_this, _pos, _button, _state, _broadcast)
    return false
end

function town_effects.OnDoubleClick(_this, _pos, _state, _broadcast)
    return true
end

function town_effects.add_effect(_effect)
	table.insert(town_window.effects_list, _effect)
end

function town_effects.ResFlyFunction( _start_pos, _end_pos, _t)
    return _start_pos + (_end_pos - _start_pos)*_t
end

function town_effects.AddFlyRes(_end_pos, _speed, _start_pos, _options_table, _text, _update_info)
    local new_child_effect = 
    {
        Init = function(_self, _start_pos, _speed, _end_pos, _options_table, _text, _update_info)
			_self._image_offset = - _options_table.image_size/2
			_self._update_info = _update_info
			_self._text_offset_x = town_effects._fly_res_font.GetStringWidth(_text)/2 + _options_table.text_space
			
			_self._options_table = _options_table
			_self._text_text = _text
			_self._start_pos = _start_pos
			_self._end_pos = _end_pos
            _self._start_time = town_window._town_timer.Get().GetTime()
            _self._total_time = CalcTimeForVector(_self._start_pos, _self._end_pos, _speed)
            _self._end_time = _self._start_time + _self._total_time
			_self._particle_effect = town_effects.visual_effects:CreateEffect(_options_table.effect_id, _start_pos)            
        end,

        Draw = function(_self, _renderer)
			_renderer.RenderString( town_effects._fly_res_font, 
								   _self._text_text, 
								   _self._fly_obj_pos.X + _self._text_offset_x, 
								   _self._fly_obj_pos.Y, 
								   0, 
								   0, 
								   1, 
								   sf.graphics.Color(255, 255, 255, 255), 0)
			_renderer.PushState()
			_renderer.ApplyMatrix( sf.misc.MatrixTranslation(_self._fly_obj_pos.X + _self._image_offset.X, _self._fly_obj_pos.Y + _self._image_offset.Y))
			_options_table.image.Draw(_renderer)
			_renderer.PopState()
								   
        end,

        Update = function(_self, _time)
            --__message("time")
			local koef = (_time - _self._start_time)/_self._total_time
			if koef > 1 then
				koef = 1
			end
			
            _self._fly_obj_pos = town_effects.ResFlyFunction( _self._start_pos, _self._end_pos, koef)
			_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)
				if _self._update_info then
					town_window._UpdateInfoOutput()				
				end
			end
            _self._is_dead = true
        end,

		IsDead = function(_self)
			return _self._is_dead
		end,
    }
	new_child_effect:Init(_start_pos, 
	                      _speed,
						  _end_pos,
						  _options_table,
						  _text,
						  _update_info
						  )
	town_effects.add_effect(new_child_effect)
	return new_child_effect
end


function town_effects.AddFlyingIcon(_start_pos, _end_pos, _depending_effects, _speed, _item_object, _item_object_level, _icon_image_id)
    local new_child_effect = 
    {
        Init = function(_self, _start_pos, _end_pos, _depending_effects, _speed, _item_object, _item_object_level, _icon_image_id)
			_self._item_object = _item_object
			_self._item_object_level = _item_object_level
			_self._icon_image = sf.graphics.CImage(_icon_image_id)
			 
			_self._offset = - sf.misc.FloatVector(_self._icon_image.GetTextureSize())/2
			_self._start_pos = _start_pos
			_self._fly_obj_pos = _start_pos
			_self._end_pos = _end_pos
			_self._speed = _speed
			_self._color_start_time = town_window._town_timer.Get().GetTime()
            _self._total_time = CalcTimeForVector(_self._start_pos, _self._end_pos, _speed)
			_self._color_koef = 0
			_self._icon_color = sf.graphics.Color(0, 255, 255, 255)
			_self._start_time = nil
			_self._depending_effects = _depending_effects
			_self._stage = 1 -- ожидание завершения эффектов
        end,

        Draw = function(_self, _renderer)

			_renderer.PushState()
			--if _self._color_koef ~= nil then
				_renderer.SetColor(_self._icon_color)
			--end
			_renderer.ApplyMatrix( sf.misc.MatrixTranslation(_self._fly_obj_pos.X + _self._offset.X, _self._fly_obj_pos.Y + _self._offset.Y))
			_self._icon_image.Draw(_renderer)
			_renderer.PopState()
        end,

        Update = function(_self, _time)
			if _self._color_koef then
				_self._color_koef = (_time - _self._color_start_time)/town_effects._icon_show_time
				_self._icon_color = sf.graphics.Color(town_effects._icon_max_alpha*_self._color_koef, 255, 255, 255)
				if _self._color_koef >= 1 then
					_self._color_koef = nil
				end
			end
			if _self._stage == 1 then
				local all_is_dead = true
				for _,obj in pairs(_self._depending_effects) do
					if not obj:IsDead() then
						all_is_dead = false
						break
					end
				end
				if all_is_dead then
					_self._stage = 2
					_self._particle_effect = town_effects.visual_effects:CreateEffect("FlyIconTrail", _start_pos)            

				end
			elseif _self._stage == 2 and _self._color_koef == nil then
				if not _self._start_time then
				    _self._start_time = _time
				end

				local koef = (_time - _self._start_time)/_self._total_time
				if koef > 1 then
					koef = 1
				end
				_self._fly_obj_pos = town_effects.ResFlyFunction( _self._start_pos, _self._end_pos, koef)
				_self._particle_effect:SetPos(_self._fly_obj_pos)
				if koef >= 1 then
					_self:InstantApply()
				end
			
			end
        end,

        InstantApply = function(_self)
            if not _self._is_dead then
				if _self._item_object.current_level >= _self._item_object_level then
					town_window._ChangeIconState(_self._item_object, _self._item_object_level)
					town_window.OnFinishBuy(_self._item_object, _self._item_object_level)
					town_effects.visual_effects:CreateInstantEffect("FlyIconHit", _self._end_pos + town_effects._icon_hit_effect_offset)			
					_self._particle_effect:Kill(false)
				end
			end
            _self._is_dead = true
        end,

		IsDead = function(_self)
			return _self._is_dead
		end,
    }
	new_child_effect:Init(_start_pos, 
						  _end_pos, 
						  _depending_effects,
						  _speed,
						  _item_object, 
						  _item_object_level,
						  _icon_image_id
						  )
	town_effects.add_effect(new_child_effect)
end

