--- модуль реализует рабоу окна с информацией об уровне на карте
level_info_window = {}
level_info_window._actions = {}

__inherite(level_info_window, null_lua_widget_handler(level_info_window._actions))

level_info_window._level_label_text = sf.misc.g_StringTable.Instance().FormatByStringsID("$281")

level_info_window._bonus_level_name_id = "$280" -- название бонусоного уровня

--изображения для подложки окна в активном и пассивном состоянии
level_info_window._back_info_window_on = "screens_town_town_window"
level_info_window._back_info_window_off = "screens_town_town_window_off"

-- изображение для стрелочки окна в пассивном состоянии
level_info_window._bubblehelp_arrow_off = "screens_town_bubblehelp_arrow_off"

-- смещние уровня относительно иконки здания
level_info_window._level_offset = sf.misc.FloatVector(43, 39)

-- изображения уровней
level_info_window._level_images = 
{
	-- когда здание куплено
	on_images = 
	{
		[1] = "screens_town_item_level1",
		[2] = "screens_town_item_level2",
		[3] = "screens_town_item_level3",
		[4] = "screens_town_item_level4"
	},
	
	-- когда здание требуется
	off_images = 
	{
		[1] = "screens_town_item_level1_off",
		[2] = "screens_town_item_level2_off",
		[3] = "screens_town_item_level3_off",
		[4] = "screens_town_item_level4_off"
	}
}

function level_info_window.__CreateInstance()
    return "level_info_window"
end

level_info_window._widgets_list = {}  -- список всех виджетов

-- виджеты для окошка с информацие о puzzle уровне
level_info_window._puzzle_widget_id_list = 
{
	level_number_label = sf.gui.CLabelWidget,
	moves_label = sf.gui.CLabelWidget,
	moves_value_label = sf.gui.CLabelWidget,
	min_moves_label = sf.gui.CLabelWidget,
	min_moves_value_label = sf.gui.CLabelWidget,
	bubblehelp_arrow_widget = sf.gui.CImageWidget,
}

--- виджеты, которые нужно будет загрузить для инициализации
level_info_window._widget_id_list = 
{
	level_number_label = sf.gui.CLabelWidget,
	best_time_label = sf.gui.CLabelWidget,
	best_time_value_label = sf.gui.CLabelWidget,
	next_time_label = sf.gui.CLabelWidget,
	next_time_value_label = sf.gui.CLabelWidget,
	building_icon_image = sf.gui.CImageWidget,
	building_name_label = sf.gui.CLabelWidget,
	money_image = sf.gui.CImageWidget,
	money_label = sf.gui.CLabelWidget,
	bubblehelp_arrow_widget = sf.gui.CImageWidget,
	money_disabled = sf.gui.CImageWidget,
	building_level_image = sf.gui.CImageWidget,
	price_text_label = sf.gui.CLabelWidget,
}

-- разные группы виджетов для управлеия их совместным отображением
level_info_window._widget_groups = 
{
	-- виджеты времени
	time_widgets = 
	{
		"best_time_label",
		"best_time_value_label",
		"next_time_label",
		"next_time_value_label"
	},
	
	-- виджеты для здания
	building_widgets =
	{
		"building_icon_image",
		"building_name_label",
		"building_level_image"
	},
	
	-- виджеты, для отображения цены здания	
	cost_widgets = 
	{
		"money_image",
		"money_label",
		"money_disabled",
		"price_text_label",
	},
	
	-- виджеты, которые удаляются если здание можно купить
	cost_disable_widgets = 
	{
		"money_disabled",
	},

	-- виджеты для числа ходов
	puzzle_moves_widgets = 
	{
		"moves_label",
		"moves_value_label",
	},
	
	-- виджеты для наикротчайшег очисла ходов
	puzzle_min_moves_widgets = 
	{
		"min_moves_label",
		"min_moves_value_label",
	},
	
	--- виджеты, которые просто удаляются в любом сулчае
	remove_widgets = 
	{
	}
}

-- информация для отображения рамок для недостаточных ресурсов
level_info_window._disable_table = 
{
	money = {widget = "money_disabled", start_widget = "money_image", offset = sf.misc.FloatVector(-7, 0)},
}

-- функция, которая прячет группу виджетов
function level_info_window._HideWidgetsGroup(_widget, _widgets_group_id)
	local widgets_group = level_info_window._widget_groups[_widgets_group_id]
	__assert(widgets_group, "Unknown widgets group :".._widgets_group_id)
	for _,widget_id in pairs(widgets_group) do
		_widget.RemoveWidget(level_info_window._widgets_list[widget_id])
	end
end

-- установка текста виджету
function level_info_window._SetWidgetText(_widget_id, _text)
	local widget = level_info_window._widgets_list[_widget_id]
	__assert(widget, "Widget ".._widget_id.." not found")
	widget.SetText(_text)
	widget.ResizeToFitText(true)
end

--- сформировать виджет окна информации о здании
function level_info_window.FormLevelInfoWidget(_dif_infex, _level_index, _profile, _levels_struct)

	local _level_info = _levels_struct.GetLevel(_dif_infex, _level_index)

    local building_info_resources = g_App.GetSettings().GetChild("GUI", false)
	                                                       .GetChildByAttribute("window", "id", "level_info_window", true)
    local building_info_widget = sf.gui.CLuaWidget("building_info_widget", 10, 0)

    building_info_widget.Load(building_info_resources, g_App.GetSettings().GetChild("GUITemplates", false))
	
	level_info_window._widgets_list = {}
	-- загружаем виджеты которые нужно будет менять
	for widget_id,widget_type in pairs(level_info_window._widget_id_list) do
		local loaded_widget = get_child_widget(building_info_widget, widget_id, widget_type) 
		--- если какого-то из их нет, то ругаемся и возвращаем nil
		if not loaded_widget then
			__message("Widget ".. widget_id .." not found")
			return nil
		end
		level_info_window._widgets_list[widget_id] = loaded_widget
	end
	
	local set_disable_info = nil
	-- флаг того что подложка нужна серая
	local background_off = nil
	
	-- таблица значений ресурсов для которых нужна красная рамка
	local cost_disable = {}
	
	-- уровень здания для отображения
	local building_level = nil
	
	local widgets_list = level_info_window._widgets_list
	
	if __cast(_level_info, s11.CHogLevelInfo) then
		--если урвоень - хог
		--прячем все виджеты кроме названия
		level_info_window._HideWidgetsGroup(building_info_widget, "time_widgets")
		level_info_window._HideWidgetsGroup(building_info_widget, "building_widgets")
		level_info_window._HideWidgetsGroup(building_info_widget, "cost_widgets")
		--меняем навазние урвоня
		local chapter_index = _level_info.GetChapterIndex() + 1 
		local level_in_chapter_index = _level_info.GetLevelIndexInChapter() + 1
		
		level_info_window._SetWidgetText("level_number_label", s11.StringFormat(level_info_window._level_label_text, chapter_index, level_in_chapter_index) .."\n"..level_info_window._bonus_level_name_id)
	else
		-- если уровень мач
		local mach_level_info = __cast(_level_info, s11.CMatchLevelInfo)

		local chapter_index = mach_level_info.GetChapterIndex() + 1 
		local level_in_chapter_index = mach_level_info.GetLevelIndexInChapter() + 1
	
		level_info_window._SetWidgetText("level_number_label", s11.StringFormat(level_info_window._level_label_text, chapter_index, level_in_chapter_index))
		
		local level_progress_info = _profile.GetLevelProgress(_dif_infex, _level_index)
		
		level_progress = level_progress_info.GetProgress()
		
		if level_progress_info.IsFinished() then
		
		    -- если урвоень был пройден
			-- прячем виджеты цены и здания
			level_info_window._HideWidgetsGroup(building_info_widget, "building_widgets")
			level_info_window._HideWidgetsGroup(building_info_widget, "cost_widgets")
			
			-- инициализируем виджеты времени
			level_info_window._SetWidgetText("best_time_value_label", TimeToString(level_progress_info.GetBestTime()))

			
			if level_progress == 1 then
				-- если урвоень пройден с золотым временем, то убираем целевое вермя
				building_info_widget.RemoveWidget(widgets_list["next_time_label"])
				building_info_widget.RemoveWidget(widgets_list["next_time_value_label"])
			else
				-- иначе отображаем в целевом уровне следующее вермя
				local prize_time_info = mach_level_info.GetPrizeTimeInfo(level_progress -2 )
				level_info_window._SetWidgetText("next_time_value_label", TimeToString(prize_time_info.Time))
			end
		else
			-- если уровень еще не был прйоден
			-- прячим виджеты вермени
			level_info_window._HideWidgetsGroup(building_info_widget, "time_widgets")		
			if mach_level_info.EnumDependences() == 0 then
				-- если уровень не имеет зависимостей, то прячим виджеты цены и здания
				level_info_window._HideWidgetsGroup(building_info_widget, "building_widgets")
				level_info_window._HideWidgetsGroup(building_info_widget, "cost_widgets")
			else
			    -- если есть зависимости, то инициируем их отображение
				
				local current_dep = mach_level_info.GetDependences()
				local dependence  = current_dep.Get()
				__assert(not current_dep.Next(), "Several dependences")
				
				local dep_item_id = dependence.BuildingId.c_str()
				local dep_item_level = dependence.BuildingLevel
				building_level = dep_item_level
				local player_item_level = _profile.GetItemLevel(dep_item_id)
				__assert(player_item_level ~= -1, "Wrong dependence id :"..dependence.BuildingId.c_str())
			
				local building_item_info = town_info.GetItemInfo(dep_item_id)
				__assert(building_item_info, "Unknown item :"..dep_item_id)
				level_info_window._SetWidgetText("building_name_label", building_item_info.caption)
				-- проверяем есть ли у игрока нужное задние
				if player_item_level >= dep_item_level then
					-- если куплено то
					-- инициализируем цветную иконку
					widgets_list["building_icon_image"].SetImage(building_item_info.icon_id)
					-- прячем цену
					level_info_window._HideWidgetsGroup(building_info_widget, "cost_widgets")
				else
					-- если не куплено
					-- устанаваливаем серый цвет подолжки
					background_off = true
					-- устанавливаем серую иконку
					widgets_list["building_icon_image"].SetImage(building_item_info.icon_off_id)
					
					level_info_window._SetWidgetText("building_name_label", building_item_info.caption)
					
					local upgrade_cost = building_item_info.upgrades_cost[dep_item_level]
					
					
					local res_table, buyable = town_info.GetResourcesTable(dep_item_id, _profile)
					cost_disable = res_table
					if not buyable then
						set_disable_info = true
					end
					
					level_info_window._SetWidgetText("money_label", tostring(upgrade_cost.money_cost))
				end
			end
		end
	end
	
	level_info_window._HideWidgetsGroup(building_info_widget, "remove_widgets")
	
    --- вызываем апдейт, что бы удалить ненужные виджеты
    building_info_widget.Update()
    --- вызываем ватоматическое размещение оставшихся виджетов(которое повлияет на размер окна)
	building_info_widget.UpdateLayout()

	-- отображаем или прячем нехватку ресурсов
	if not set_disable_info then
		level_info_window._HideWidgetsGroup(building_info_widget, "cost_disable_widgets")
	else
		for res_id,disable_info in pairs(building_info_window._disable_table) do
			local widget = widgets_list[disable_info.widget]
			if not cost_disable[res_id] then
				building_info_widget.RemoveWidget(widget)
			else
				local power_base_offset = widgets_list[disable_info.start_widget].GetOffset() + disable_info.offset
				widget.SetOffset(power_base_offset.X, power_base_offset.Y)
			end
		end
	end
	-- отображаем если унжно уровень здания
	if building_level then
		local image_id = level_info_window._level_images["on_images"][building_level]
		if background_off then
			image_id = level_info_window._level_images["off_images"][building_level]
		end
		local level_offset = widgets_list["building_icon_image"].GetOffset() + level_info_window._level_offset
		widgets_list["building_level_image"].SetOffset(level_offset.X, level_offset.Y)
		widgets_list["building_level_image"].SetImage(image_id)
	end
	
	--- получаем размер получившегося окна
	local info_window_size = building_info_widget.GetSize()
	
	local back_ground_id = level_info_window._back_info_window_on
	if background_off then
		back_ground_id = level_info_window._back_info_window_off
		widgets_list["bubblehelp_arrow_widget"].SetImage(level_info_window._bubblehelp_arrow_off)
	end
	
	
	level_info_window._background_image = sf.graphics.CImage(back_ground_id);

	level_info_window._background_image.SetFlags(__or(__or(level_info_window._background_image.GetFlags(), 
																sf.graphics.CImage.FlagBoxImage), sf.graphics.CImage.FlagIntDest))

	level_info_window._background_image.SetRect( sf.misc.FloatRect(0, 0, info_window_size.X, info_window_size.Y))

	return building_info_widget
end

function level_info_window.DoDraw(_this, _renderer)
    if level_info_window._background_image then
        level_info_window._background_image.Draw(_renderer)
    end
    return false
end

function level_info_window.DoUpdate(_this)
    return false    
end

function level_info_window.Load(_this, _info, _templates)
    return false    
end

--- сформировать виджет окна информации о пазле
function level_info_window.FormPuzzleLevelInfoWidget(_dif_infex, _level_index, _profile, _levels_struct)

	local _level_info = _levels_struct.GetLevel(_dif_infex, _level_index)

    local building_info_resources = g_App.GetSettings().GetChild("GUI", false)
	                                                       .GetChildByAttribute("window", "id", "puzzle_level_info_window", true)
    local building_info_widget = sf.gui.CLuaWidget("building_info_widget", 10, 0)

    building_info_widget.Load(building_info_resources, g_App.GetSettings().GetChild("GUITemplates", false))
	
	level_info_window._widgets_list = {}
	-- загружаем виджеты которые нужно будет менять
	for widget_id,widget_type in pairs(level_info_window._puzzle_widget_id_list) do
		local loaded_widget = get_child_widget(building_info_widget, widget_id, widget_type) 
		--- если какого-то из их нет, то ругаемся и возвращаем nil
		if not loaded_widget then
			__message("Widget ".. widget_id .." not found")
			return nil
		end
		level_info_window._widgets_list[widget_id] = loaded_widget
	end
	
	local set_disable_info = nil
	-- флаг того что подложка нужна серая
	--local background_off = nil
	
	-- таблица значений ресурсов для которых нужна красная рамка
	local cost_disable = {}
	
	-- уровень здания для отображения
	local building_level = nil
	
	local widgets_list = level_info_window._widgets_list
	
	if __cast(_level_info, s11.CHogLevelInfo) then
		--если урвоень - хог
		--прячем все виджеты кроме названия
		level_info_window._HideWidgetsGroup(building_info_widget, "puzzle_moves_widgets")
		level_info_window._HideWidgetsGroup(building_info_widget, "puzzle_min_moves_widgets")
		
		--меняем навазние урвоня
		level_info_window._SetWidgetText("level_number_label", level_info_window._bonus_level_name_id)
	else
		-- если уровень мач
		local mach_level_info = __cast(_level_info, s11.CMatchLevelInfo)

		local chapter_index = mach_level_info.GetChapterIndex() + 1 
		local level_in_chapter_index = mach_level_info.GetLevelIndexInChapter() + 1
	
		level_info_window._SetWidgetText("level_number_label", s11.StringFormat(level_info_window._level_label_text, chapter_index, level_in_chapter_index))
		
		local level_progress_info = _profile.GetLevelProgress(_dif_infex, _level_index)
		
		if level_progress_info.IsFinished() then
		
			local min_moves = mach_level_info.GetMinMovesForWin()
			local current_moves = level_progress_info.GetMovesCount()
			
			level_info_window._SetWidgetText("moves_value_label", tostring(current_moves))

			if min_moves == -1 then
				level_info_window._HideWidgetsGroup(building_info_widget, "puzzle_min_moves_widgets")
			else
				level_info_window._SetWidgetText("min_moves_value_label", tostring(min_moves))
			
			end
		else
			-- если уровень еще не был прйоден
			-- прячим виджеты вермени
			level_info_window._HideWidgetsGroup(building_info_widget, "puzzle_moves_widgets")		
			level_info_window._HideWidgetsGroup(building_info_widget, "puzzle_min_moves_widgets")		
		end
	end
	
    --- вызываем апдейт, что бы удалить ненужные виджеты
    building_info_widget.Update()
    --- вызываем ватоматическое размещение оставшихся виджетов(которое повлияет на размер окна)
	building_info_widget.UpdateLayout()
	--- получаем размер получившегося окна

	local info_window_size = building_info_widget.GetSize()
	
	local back_ground_id = level_info_window._back_info_window_on
	
	level_info_window._background_image = sf.graphics.CImage(back_ground_id);

	level_info_window._background_image.SetFlags(__or(__or(level_info_window._background_image.GetFlags(), 
																sf.graphics.CImage.FlagBoxImage), sf.graphics.CImage.FlagIntDest))

	level_info_window._background_image.SetRect( sf.misc.FloatRect(0, 0, info_window_size.X, info_window_size.Y))

	return building_info_widget
end
