-- модуль, отвечающий за работу прогресс-бара, отображающего уровень застройки города.
-- прогресс-бар состоит из 4-х контрольных точек и 3-х маленьких прогресс-баров между ними.
-- каждая контрольная точка имеет свою отметку. при достиженнии некоторой отметки контрольная точка, соответствующая этой отметке,
-- загорается - одно изображение подменяется другим. 
-- маленькие прогресс-бары, хоть и разделены изображениями конрольных точек,  представляют собой единный прогресс-бар, 
-- т.е. при наполнении одного маленького тут же начинает наполняться следующий.
-- перед открытием города надо вызвать town_building_progress.SetMaxValue для установки правой границы.
-- после каждой покупки/продажи надо вызывать town_building_progress.SetMaxValue для установки текщего уровня застройки города.
-- время, за которое заполненяется одно деление прогресс-бара, задается в файле constants.xml (town_options -> progress_one_step_time)

town_building_progress = town_building_progress or {}

function town_building_progress.__CreateInstance()
    return "town_building_progress"
end

__inherite(town_building_progress, null_lua_widget_handler())

town_building_progress.params = 
{
	images = 
	{	
		progress_bars = {
			{"screens_town_progressbar_progress", "screens_town_progressbar_progressbar"},
			{"screens_town_progressbar_progress", "screens_town_progressbar_progressbar"},
			{"screens_town_progressbar_progress", "screens_town_progressbar_progressbar"}},
		points = {
			{"screens_town_progressbar_state01_off","screens_town_progressbar_state01_on"},
			{"screens_town_progressbar_state02_off","screens_town_progressbar_state02_on"},
			{"screens_town_progressbar_state03_off","screens_town_progressbar_state03_on"},
			{"screens_town_progressbar_state04_off","screens_town_progressbar_state04_on"}}
	},
	
	point_effect = "TownProgessBarEffect"
}

function town_building_progress.Load(_this, _info, _templates)
	
	town_building_progress._points = {}
	town_building_progress._bars = {}
	
	-- отметки контрольных точек
	local points = {1,16,32,64}
	local bars = {{1,15},{17,31},{33,63}}
	
	local x = 0
	local y
	
	-- создаем по 2 виджета изоражений на каждую из 4х контрольных точек.
	-- создаем по маленькому прогресс-бару на каждый из 3х отрезков между контрольными точками.
	for i=1,4 do
		-- контрольные точки
		local point_widget1 = sf.gui.CImageWidget(town_building_progress.params.images.points[i][1], "", 0, 0)
		local point_widget2 = sf.gui.CImageWidget(town_building_progress.params.images.points[i][2], "", 0, 0)
		point_widget1.SetOffset(x, 0)
		point_widget2.SetOffset(x, 0)
		x = x + point_widget1.GetSize().X

		_this.AddWidget(point_widget1)
		_this.AddWidget(point_widget2)
		
		local point = 
		{
			widgets = {point_widget1, point_widget2},
			value = points[i]
		}
		
		table.insert(town_building_progress._points, point)
		
		-- промежуточные прогресс-бары
		if i < 4 then
			local progress_widget = sf.gui.CProgressBarWidget("", 0, 0)
			local image_progress = sf.graphics.CImage(town_building_progress.params.images.progress_bars[i][1])
			local image_progress_back = sf.graphics.CImage(town_building_progress.params.images.progress_bars[i][2])
			progress_widget.SetImages(image_progress_back, image_progress)
			progress_widget.SetSize(image_progress.GetTextureSize().X, image_progress.GetTextureSize().Y)
			
			if not y then
				y = (point_widget1.GetSize().Y - progress_widget.GetSize().Y) / 2.0
			end
			
			progress_widget.SetOffset(x, y)
			x = x + progress_widget.GetSize().X
			
			_this.AddWidget(progress_widget)

			local bar = 
			{
				-- bars[i][1] соответствует отметке 0 промежуточного прогресс-бара, bars[i][2] соответствует отметке 1 промежуточного прогресс-бара
				interval = {bars[i][1], bars[i][2]},
				widget = progress_widget
			}
			
			table.insert(town_building_progress._bars, bar)
		end
	end
	
	town_building_progress._max_value = 0
	town_building_progress._current_value = 0
	town_building_progress._last_value = 0
	town_building_progress._target_value = 0
	town_building_progress._timer = __create_timer()
	town_building_progress._last_update = 0
	town_building_progress._progress_time = 500
	
	local town_info = g_App.GetSettings().GetChild("Constants", false).GetChildRef("town_options", false)
	if town_info then
		town_building_progress._progress_time = tonumber(town_info.GetValue("progress_one_step_time").c_str())
	end
end

function town_building_progress.DoUpdate(_this)
	local t = town_building_progress._timer.Get().GetTime()
	local dt = t - town_building_progress._last_update
	
	-- приближаем текущее значение к целевому
	if town_building_progress._current_value < town_building_progress._target_value then
		town_building_progress._current_value = town_building_progress._current_value + dt / town_building_progress._progress_time
		if town_building_progress._current_value > town_building_progress._target_value then
			town_building_progress._current_value = town_building_progress._target_value
		end
	else
		town_building_progress._current_value = town_building_progress._current_value - dt / town_building_progress._progress_time
		if town_building_progress._current_value < town_building_progress._target_value then
			town_building_progress._current_value = town_building_progress._target_value
		end
	end
	
	-- обновляем изображения контрольных точек.
	-- если текущее значение прогресс-бара больше или равно отметке контрольной точки, то отображаем изображение "включенной" контрольной точки, иначе - "выключенной"
	for i,p in ipairs(town_building_progress._points)  do
		local completed = p.value <= town_building_progress._current_value
		__visible(p.widgets[1], not completed)
		__visible(p.widgets[2], completed)
		
		-- если контрольная точка пройденна именно за этот апдейт, то создаем эффект влючения контрольной точки.
		if completed and p.value > town_building_progress._last_value then
			local location = p.widgets[2].GetAbsPos(false)
			location = location + p.widgets[2].GetSize() / 2.0
			town_effects.visual_effects:CreateInstantEffect(town_building_progress.params.point_effect, location)
			
			-- если достигнута последняя точка, проигрываем звук полной застройки города
			if i == #town_building_progress._points then
				__sound("city_build")
				-- ачивмент полной застройки
				achievements.GetAchievement("full_upgrade")	
			end
		end
	end
	
	-- обновляем значения промежуточных прогресс-баров.
	for _,b in ipairs(town_building_progress._bars)  do
		local k = (town_building_progress._current_value - b.interval[1]) / (b.interval[2] - b.interval[1])
		b.widget.SetValue(k)
	end
	
	town_building_progress._last_update = t
	town_building_progress._last_value = town_building_progress._current_value
	
	return false
end

function town_building_progress.DoDraw(_this, _renderer)
    return false
end

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

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

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

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

function town_building_progress.SetMaxValue(_value)
	town_building_progress._max_value = _value
end

function town_building_progress.SetValue(_value, _immediately)
	town_building_progress._target_value = _value
	if _immediately then
		town_building_progress._current_value = _value
		town_building_progress._last_value = _value
	end
end
