---- модуль реализует работу окна города
town_window = {}

town_window._total_forbid_sell = true
town_window._info_window_id = nil       --- id объекта для которого вызывано текущее окно купли-продажи здания
town_window._info_window_widget = nil   --- widget окна купли-продажи
town_window._sell_koef = 0.5              --- коэфициент цены продажи для зданий


town_window._show_window_effect = 300  
town_window._hide_window_effect = 300   

town_window._gold_fly_effect =
{
	effect_id ="TownGoldFly",
	text_space = 30
}

town_window._power_fly_effect = 
{
	effect_id ="TownPowerFly",
	text_space = 20
}

-- скорость полета ресурсов в городе
town_window._res_fly_speed = 550

-- скорость полета иконки
town_window._icon_fly_speed = 550

town_window._fly_res_font_id = "mpc_gradient_30"


town_window._state_change_time = 950       -- задержка на смену состояния зданяия
town_window._buy_clip = "building_constraction"   -- клип на покупку здания
town_window._sell_clip = "building_selling"       -- клип на продажу здания

town_window._gold_res_pos = sf.misc.FloatVector(120,50)

town_window._res_tutorial_strings = 
{
	money = {str = "$500"},
	power = {str = "$499"},
	level = {str = "$502"},
	level_low = {str = "$501"},
}

for _, obj in pairs(town_window._res_tutorial_strings) do
	obj.str = sf.misc.g_StringTable.Instance().FormatByStringsID(obj.str)
end


sf.misc.g_StringTable.Instance().FormatByStringsID(game_window.press_any_key.params.text)
sf.misc.g_StringTable.Instance().FormatByStringsID(game_window.press_any_key.params.text)

-- смещение стрекли досказки для покупки здания
town_window._hint_arrow_offset = sf.misc.FloatVector(0, -56)

-- смещения точек куда указвает стрелочка инфомрациооного окна для каждого задния отностиельно его центра
town_window._building_output_params = 
	{
		green_totem 		= {buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(-10,-85),
									[1] = sf.misc.FloatVector(-10,-85),
									[2] = sf.misc.FloatVector(-10,-105),
									[3] = sf.misc.FloatVector(-10,-105),
									[4] = sf.misc.FloatVector(-10,-105),
								},
								arr_off = sf.misc.FloatVector(-35,20),
		                        sell_buy_off = sf.misc.FloatVector(-10,-20),
								fly_icon = "screens_town_totem_green_icon_icon_totem_green_on",
								fly_icon_start_offset = sf.misc.FloatVector(55.5, -20.5)
								},
								

		orange_totem 		= { buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(20,-135),
									[1] = sf.misc.FloatVector(20,-135),
									[2] = sf.misc.FloatVector(20,-135),
									[3] = sf.misc.FloatVector(20,-135),
									[4] = sf.misc.FloatVector(20,-135),
								},
								arr_off = sf.misc.FloatVector(20,-20), 
		                        sell_buy_off = sf.misc.FloatVector(30,-60),
								fly_icon = "screens_town_totem_orange_icon_icon_totem_orange_on",
								fly_icon_start_offset = sf.misc.FloatVector(-60.5, -40.5)
								},
								
		violet_totem 		= { buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(-60,-90),
									[1] = sf.misc.FloatVector(-60,-90),
									[2] = sf.misc.FloatVector(-60,-90),
									[3] = sf.misc.FloatVector(-60,-90),
									[4] = sf.misc.FloatVector(-60,-90),
								},
								arr_off = sf.misc.FloatVector(-57,25), 
		                        sell_buy_off = sf.misc.FloatVector(-55,-15),
								fly_icon = "screens_town_totem_violet_icon_icon_totem_violet_on",
								fly_icon_start_offset = sf.misc.FloatVector(53, -25)
								},
								
								
		red_totem 			= { buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(-20,-120),
									[1] = sf.misc.FloatVector(-20,-120),
									[2] = sf.misc.FloatVector(-20,-150),
									[3] = sf.misc.FloatVector(-20,-150),
									[4] = sf.misc.FloatVector(-20,-150),
								},
		                        arr_off = sf.misc.FloatVector(-15,0),
		                        sell_buy_off = sf.misc.FloatVector(-15,-40),
								fly_icon = "screens_town_totem_red_icon_icon_totem_red_on",
								fly_icon_start_offset = sf.misc.FloatVector(60, -40)
								},
								
		blue_totem 			= { buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(-35,-50),
									[1] = sf.misc.FloatVector(-20,-120),
									[2] = sf.misc.FloatVector(-20,-120),
									[3] = sf.misc.FloatVector(-20,-120),
									[4] = sf.misc.FloatVector(-20,-120),
								},
								arr_off = sf.misc.FloatVector(-20,40), 
		                        sell_buy_off = sf.misc.FloatVector(-30,0),
								fly_icon = "screens_town_totem_blue_icon_icon_totem_blue_on",
								fly_icon_start_offset = sf.misc.FloatVector(45, -15)
								},
								
		white_totem 		= { buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(-35,-70),
									[1] = sf.misc.FloatVector(-35,-70),
									[2] = sf.misc.FloatVector(-35,-70),
									[3] = sf.misc.FloatVector(-35,-70),
									[4] = sf.misc.FloatVector(-35,-70),
								},
								arr_off = sf.misc.FloatVector(-35,40), 
		                        sell_buy_off = sf.misc.FloatVector(-35,-20),
								fly_icon = "screens_town_totem_white_icon_icon_totem_white_on",
								fly_icon_start_offset = sf.misc.FloatVector(47.5, -15.5)
								},
								
		yellow_totem 		= {  buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(40,-90),
									[1] = sf.misc.FloatVector(40,-90),
									[2] = sf.misc.FloatVector(40,-90),
									[3] = sf.misc.FloatVector(40,-90),
									[4] = sf.misc.FloatVector(40,-90),
								},
								arr_off = sf.misc.FloatVector(40,20), 
		                        sell_buy_off = sf.misc.FloatVector(40,-20),
								fly_icon = "screens_town_totem_yellow_icon_icon_totem_yellow_on",
								fly_icon_start_offset = sf.misc.FloatVector(60, -25)
								},
								
		dynamite_bonus 		= {buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(-20,-45),
									[1] = sf.misc.FloatVector(-20,-45),
									[2] = sf.misc.FloatVector(-20,-75),
									[3] = sf.misc.FloatVector(-20,-75),
									[4] = sf.misc.FloatVector(-20,-75),
								},
								arr_off = sf.misc.FloatVector(-5,60), 
		                        sell_buy_off = sf.misc.FloatVector(-10,20),
								fly_icon = "screens_town_bonus_dynamite_icon_bonus_dinamite_on",
								fly_icon_start_offset = sf.misc.FloatVector(58, -30)
								},
								
		lightning_bonus 	= { buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(0,-55),
									[1] = sf.misc.FloatVector(0,-55),
									[2] = sf.misc.FloatVector(0,-55),
									[3] = sf.misc.FloatVector(0,-55),
									[4] = sf.misc.FloatVector(0,-55),
								},
								arr_off = sf.misc.FloatVector(-5,50), 
		                        sell_buy_off = sf.misc.FloatVector(5,-20),
								fly_icon = 
								{
									[1] = "screens_town_bonus_firepost_icon_bonus_firepost01_without_number",
									[2] = "screens_town_bonus_firepost_icon_bonus_firepost02_without_number",
									[3] = "screens_town_bonus_firepost_icon_bonus_firepost03_without_number",
									[4] = "screens_town_bonus_firepost_icon_bonus_firepost04_without_number",
								},
								fly_icon_start_offset = sf.misc.FloatVector(50, -10)
								},
								
		time_bonus 			= { buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(-55,-60),
									[1] = sf.misc.FloatVector(-55,-60),
									[2] = sf.misc.FloatVector(-55,-60),
									[3] = sf.misc.FloatVector(-55,-60),
									[4] = sf.misc.FloatVector(-55,-60),
								},
								arr_off = sf.misc.FloatVector(-60,15), 
		                        sell_buy_off = sf.misc.FloatVector(-55,-40),
								fly_icon = "screens_town_bonus_time_descrease_icon_bonus_time_on",
								fly_icon_start_offset = sf.misc.FloatVector(55, -5)
								
								
								},
								
		hint_bonus 			= {buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(-32,-65),
									[1] = sf.misc.FloatVector(-32,-65),
									[2] = sf.misc.FloatVector(-32,-65),
									[3] = sf.misc.FloatVector(-32,-65),
									[4] = sf.misc.FloatVector(-32,-65),
								},
								arr_off = sf.misc.FloatVector(-35,20), 
		                        sell_buy_off = sf.misc.FloatVector(-50,-40),
								fly_icon = "screens_town_bonus_hint_icon_bonus_hint_on",
								fly_icon_start_offset = sf.misc.FloatVector(38, -15)
								},
								
		solidarity_bonus 	= {buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(10,-50),
									[1] = sf.misc.FloatVector(10,-50),
									[2] = sf.misc.FloatVector(10,-50),
									[3] = sf.misc.FloatVector(10,-50),
									[4] = sf.misc.FloatVector(10,-50),
								},
								arr_off = sf.misc.FloatVector(8,40), 
		                        sell_buy_off = sf.misc.FloatVector(0,-25),
								fly_icon = "screens_town_bonus_solidarity_icon_bonus_solidary_on",
								fly_icon_start_offset = sf.misc.FloatVector(48, -15)
								},
								
		score_mul_bonus 	= {  buy_hint_off = 
								{
									[0] = sf.misc.FloatVector(-35,-40),
									[1] = sf.misc.FloatVector(-35,-40),
									[2] = sf.misc.FloatVector(-35,-40),
									[3] = sf.misc.FloatVector(-35,-40),
									[4] = sf.misc.FloatVector(-35,-40),
								},
								arr_off = sf.misc.FloatVector(-45,30), 
		                        sell_buy_off = sf.misc.FloatVector(-50,-20),
								fly_icon = 
								{
									[1] = "screens_town_bonus_multiplier_icon_bonus_miltiplier_x3_without_number",
									[2] = "screens_town_bonus_multiplier_icon_bonus_miltiplier_x5_without_number",
									[3] = "screens_town_bonus_multiplier_icon_bonus_miltiplier_x7_without_number",
									[4] = "screens_town_bonus_multiplier_icon_bonus_miltiplier_x10_without_number",
								},
								fly_icon_start_offset = sf.misc.FloatVector(10, -15)
								},
								
		frenzy_time_upgrade = { arr_off = sf.misc.FloatVector(-70,0), 
		                        sell_buy_off = sf.misc.FloatVector(-100,0),
								fly_icon = "screens_town_upgrade_frenzy_time_icon_upgrade_frenzy_on",
								fly_icon_start_offset = sf.misc.FloatVector(-35, -20)
								},
								
		gems_count_upgrade 	= { arr_off = sf.misc.FloatVector(0,100), 
		                        sell_buy_off = sf.misc.FloatVector(0,10),
								fly_icon = "screens_town_upgrade_gems_on_level_icon_upgrade_gems_on",
								fly_icon_start_offset = sf.misc.FloatVector(0, 15)
								},
								
		level_time_upgrade 	= { arr_off = sf.misc.FloatVector(-7,50), 
		                        sell_buy_off = sf.misc.FloatVector(0,-25),
								fly_icon = "screens_town_upgrade_increase_time_icon_upgrade_increase_on",
								fly_icon_start_offset = sf.misc.FloatVector(45, -10)
								}
								
	}
	
town_window.upgrade_buildings = 
	{
		"frenzy_time_upgrade", 
		"gems_count_upgrade", 	
		"level_time_upgrade"
	}

town_window.bonus_buildings = 
	{
		"dynamite_bonus",
		"lightning_bonus",
		"time_bonus",
		"hint_bonus",
		"solidarity_bonus",
		"score_mul_bonus",
	}
	
town_window.totem_buildings =
	{
		"green_totem",
		"yellow_totem",
		"red_totem",
		"blue_totem",
		"orange_totem",
		"white_totem",
		"violet_totem"
	}
	
town_window._top_bound = 60				--- отступы для окон сверху	
town_window._bottom_bound = 568         ---  и снизу

town_window._level_for_show_power_tutorial = 4 -- уровень игрока на котором покажется туториал на могущество
town_window._level_for_show_res_tutorial = 1 -- уровень игрока начиная с которого может появитсья туториал про ресурсы

town_window._actions = {}

-- цвет подсветки по умочанию для здания, которое можно купить 
town_window._buyable_color = sf.graphics.Color(255, 10, 255, 255)
-- цвет подсветки по умочанию для здания, на которое наведен курсор
town_window._over_color = sf.graphics.Color(255, 255, 10, 255)

-- смещение стрелочки по окну
town_window._arrow_offset = sf.misc.FloatVector(90,-7)
-- ограничение для окон сострелочкой
town_window._arrow_limits = {left = 50, top = 20, right = 1020, bottom = 768}

town_window._tutorial_shadow_for_buy = false

town_window._actions.map_button = 
{
	pressed = function(_window) 
		s11.g_Achievements.Instance().SaveProfilesAchievements()
		town_window._profile.SaveGameType(s11.CGameStruct.GameTypeClassic)
		town_window._RemoveInfoeWindow()
		map_window.Show()
	end
}

town_window._actions.menu_button = 
{
	pressed = function(_window) 
		s11.g_Achievements.Instance().SaveProfilesAchievements()
		town_window._profile.SaveGameType(s11.CGameStruct.GameTypeClassic)
		town_window._RemoveInfoeWindow()
		main_menu.Show()
	end
}
town_window._buy_sounds_options = {
["frenzy_time_upgrade"] = "buy_building_upgrade",
["gems_count_upgrade"] = "buy_building_upgrade",
["level_time_upgrade"] = "buy_building_upgrade"
}

function town_window._RemoveInfoeWindow()
	town_window._self.RemoveWidget(town_window._info_window_widget)
	town_window._info_window_widget = nil
	town_window._info_window_id = nil
end

-- функция для загрузки настроек карты
function town_window._LoadConstants()
	local town_info = g_App.GetSettings().GetChild("Constants", false).GetChildRef("town_options", false)
	if not town_info then
		__message("Town options not found")
		return
	end
	-- загрузка цвета подсветки для задний
	local glow_info = town_info.GetChildRef("glow_colors", false)
	if glow_info then
		town_window._buyable_color = string_to_color(glow_info.GetValue("buy_color").c_str())
		town_window._over_color = string_to_color(glow_info.GetValue("select_color").c_str())
	end
end

town_window._LoadConstants()

function town_window.OnChildAction(_this, _action, _child)
	if not _child then return end
	local handler = town_window._actions[_child.GetId().c_str()]
	if handler then handler = handler[_action.c_str()] end
	if handler then handler(_this, _child) end
end

--- получение коэфициента для цены продажи
function town_window.GetSellKoef()
	return town_window._sell_koef
end

-- проверка возможности купить
function town_window.IsBuyable(_id, _info_table)
	local res = town_info.IsBuyable(_id, town_window._current_profile, _info_table)	
	local item_info = town_window._items_info[_id]
	if res == true and item_info.was_buyed == false then
		item_info.was_buyed = true
		town_window._current_profile.SetItemLevel(_id, item_info.current_level)		
	end
	return res
end

function town_window.ShowDisableSellTutorial(_id)
	for _, bonus_id in pairs(town_window.bonus_buildings) do
		if _id	== bonus_id then
			dialog_do_modal("bonus_sell_dialog", town_window._self)
		end
	end
end

-- проверка возможности продать задние
function town_window.IsSellable(_id)
	if town_window._total_forbid_sell then
		return false
	end
	local object = town_window._items_info[_id]
	if not object then
		__message(_id .. " не определен")
		return false
	end
	local building_level = object.current_level
	if building_level <= 0 then
		return false
	end

	local town_object = town_info.GetItemInfo(_id)
	if not town_object then
		__message(_id .. " неизввестный объект города")
		return false
	end

	local current_level_info = town_object.upgrades_cost[building_level]
	return not current_level_info.forbid_sell, current_level_info.forbid_sell
end

-- функция для смены состояния группы
function town_window._SetGroupColor(_id, _color)
	if not _id then
		return
	end
	local object = quest.FindObjectById(_id)
	if not object then
		return
	end
	local current_object = __cast(object, qe.CSceneGroup)
	if current_object then
		-- если подсвечиваемый объект группа
		local state = current_object.GetStateById(current_object.GetFirstVisibleState())
		if state then
			-- подсвечиваем нужное состояние в цвет покупки
			state.SetColor(_color)
		end
	else
		object.SetColor(_color)
	end
end

-- меняет видимость контура здания и иконки
-- _item_info_object - информация о подсвечиваемом объекте
-- _value - значение нужно ли отобразить подсветку или спрятать
-- _mouse_event - флаг, который говорит, что подсветка иницирована наведенной мышкой
function town_window._SetGlowVisibility(_item_info_object, _value, _mouse_event, _building_value)
	
	local color = town_window._over_color
	-- если подсветка иницирована мышкой
	if _mouse_event then
		if _value == false then
			-- если подсветка должна пропасть
			if town_window.IsBuyable(_item_info_object.id)	then
			    -- если здание можно купить, то не прячем подсветку а меняем ее цвет на цвет доступного для покупки здания
				_value = true
				color = town_window._buyable_color
			end
		end
	else
		color = town_window._buyable_color
	end
	
	if _item_info_object.buyable then
		_value = true
		_building_value = true
	end
	
	
	local icon_value = _value
	if _building_value == nil then
		_building_value = _value
	end

	if _value then
		town_window._SetGroupColor(_item_info_object.glow_object_id, color)
		town_window._SetGroupColor(_item_info_object.icon_glow_object_id, color)
	end
--[[
		local current_object = __cast(quest.FindObjectById(_item_info_object.glow_object_id), qe.CSceneGroup)
		if current_object then
		    -- если подсвечиваемый объект группа
			local state = current_object.GetStateById(current_object.GetFirstVisibleState())
			if state then
				-- подсвечиваем нужное состояние в цвет покупки
				state.SetColor(color)
			end
		end
]]
	if _item_info_object.glow_object_id then
		town_window.vis_func[_building_value](0, false, _item_info_object.glow_object_id)
	end
	
	if _item_info_object.icon_glow_object_id then
		town_window.vis_func[icon_value](0, false, _item_info_object.icon_glow_object_id)
	end
end

-- диалог который рповеряет есть ли сохраненная игра перед действием
-- если игрок хочет сделать какое то действие то сохраннеие будет сброшено
function town_window._DropSavedGameDialog()
	--- если нет информации о сохраненном уровне, то выходим и разрешаем действие
	if not town_window._current_profile.HasSavedLevelInfo() then
		return true
	end

	--- запускаем диалог с предложением перети к сохраненному вровню
    local window = sf.gui.CWindow()

	window.Load(
		g_App.GetSettings().GetChild("GUI", false).GetChildByAttribute("window", "id", "drop_save_dialog", true), 
		g_App.GetSettings().GetChild("GUITemplates", false))
	window.UpdateLayout()
	
	local label_widget = get_child_widget(window, "message_label", sf.gui.CLabelWidget)
	if not label_widget then
		__message("Label message_label not found in drop_save_dialog window")
		return
	end

	local level_index = town_window._current_profile.GetSavedLevelIndex()
	local dif_level_index = town_window._current_profile.GetSavedLevelDifficulty()

	label_widget.SetText(s11.StringFormat(label_widget.GetText(), town_window._levels_struct.GetLevelName(dif_level_index, level_index)))
	
	local res = dialog_do_modal(window, town_window._self)
	if res == 1 then
		town_window._current_profile.DropSavedLevelInfo()
		town_window._profile.SaveGameType(s11.CGameStruct.GameTypeClassic)
		-- выходим и разрешаем действие
		return true
	end
	-- выходим и запрещаем действие
	return false
end

-- покупка урвоня здания
function town_window.BuyItem(_id)
	--__message(_id)
	
	if not town_window._DropSavedGameDialog() then
		return
	end

	local town_object = town_info.GetItemInfo(_id)
	if not town_object then
		__message(_id .. " неизввестный объект города")
		return false
	end

	local item_object = town_window._items_info[_id]
	if not item_object then
		__message(_id .. " не определен")
		return
	end
	if not town_window.IsBuyable(_id) then
		__message(_id .. " попытка купить при недостатке ресурсов")
		return
	end
	local current_item_level_info = town_object.upgrades_cost[item_object.current_level + 1]
	local profile = town_window._current_profile
	--- меняем количество ресурсов
	profile.SetMoney(profile.GetMoney() - current_item_level_info.money_cost)
	--profile.SetPower(profile.GetPower() - current_item_level_info.power_cost)
	
	--- меняем урвоень задния
	item_object.current_level = item_object.current_level + 1
	item_object.was_buyed = true
	profile.SetItemLevel(_id, item_object.current_level )
	local sound_id = town_window._buy_sounds_options[_id]
	if not sound_id or sound_id =="" then
		sound_id = "buy_building"
	end
	__sound(sound_id)
	
	if item_object.current_level == 4 then
		__sound("build_building")
	end
	
	--- вызываем смену состояния в городе
	town_window._ChangeObjectState(item_object, item_object.current_level)
	--town_window._ChangeIconState(item_object, item_object.current_level) -- изменится когда иконка прилетит
	
	local building_pos = quest.get_object_pos(item_object.building_object_id) + town_window._building_output_params[_id]["sell_buy_off"]
	
	town_effects.visual_effects:CreateClipEffect(town_window._buy_clip, building_pos, nil, true)

	local effect_1 = town_effects.AddFlyRes(building_pos, 
	                        town_window._res_fly_speed, 
							town_window._gold_res_pos, 
							town_window._gold_fly_effect,
							tostring(current_item_level_info.money_cost)
							)
	local fly_icon_id, icon_offset = town_window.GetFlyIconId(item_object.id, item_object.current_level)
	town_effects.AddFlyingIcon(building_pos + icon_offset, item_object.icon_pos, {effect_1}, town_window._icon_fly_speed, item_object, item_object.current_level, fly_icon_id)
	
	--- обновляем виджеты ресурсов
	town_window._UpdateBuildingProgress()
	town_window._UpdateInfoOutput()

	town_window._UpdateCostHints()
	town_window._UpdateBuyHint()

	--town_window._InitSceneObjects()
	town_window._InitObjectsVisibility()
	-- прячем инф окно пр ипокупке или продаже
	--town_window._CloseBuildingInfoWindow()
end

function town_window.OnFinishBuy(_item_object, _item_object_level)
	if not town_window._all_upgrades then
		town_window._all_upgrades = town_window.CheckBuildings(town_window.upgrade_buildings, 1)	
		if town_window._all_upgrades then
			achievements.GetAchievement("all_upgrades")
		end
	end

	if not town_window._all_bonuses then
		town_window._all_bonuses = town_window.CheckBuildings(town_window.bonus_buildings, 1)	
		if town_window._all_bonuses then
			achievements.GetAchievement("all_bonuses")
		end
	end
	
	if not town_window._all_totems then
		town_window._all_totems = town_window.CheckBuildings(town_window.totem_buildings, 1)	
		if town_window._all_totems then
			achievements.GetAchievement("all_totems")
		end
	end
	if town_window._first_buy_tutorial == true and _item_object.id == "dynamite_bonus" and _item_object_level == 1 then
		town_window._first_buy_tutorial = false
		tutorial_window.Show(town_window._self, "first_buy_dialog")
		town_window._tutorial_flags.RaiseFlag(s11.CProfileDataClassic.TutorialFlagBuy)
	end
end

function town_window.CheckBuildings(_ids, _min_level)
	local all_buildings = true
	for _,o in pairs(_ids) do
		
		if town_window._items_info[o].current_level < _min_level then
			all_buildings = false
			break
		end
	end
	return all_buildings
end

-- продажа уровня здания
function town_window.SellItem(_id)
	if not town_window._DropSavedGameDialog() then
		return
	end
	local town_object = town_info.GetItemInfo(_id)
	if not town_object then
		__message(_id .. " неизввестный объект города")
		return false
	end
	
	local item_object = town_window._items_info[_id]
	if not item_object then
		__message(_id .. " не определен")
		return
	end
	if not town_window.IsSellable(_id) then
		__message(_id .. " попытка продать несуществующие здание")
		return
	end
	local current_item_level_info = town_object.upgrades_cost[item_object.current_level]
	local profile = town_window._current_profile
	
	--- меняем количество ресурсов
	profile.SetMoney(profile.GetMoney() + current_item_level_info.money_cost*town_window._sell_koef)
	--profile.SetPower(profile.GetPower() + current_item_level_info.power_cost)
	
	--- меняем урвоень задния
	item_object.current_level = item_object.current_level - 1
	profile.SetItemLevel(_id, item_object.current_level )
	__sound("sell_building")

	local building_pos = quest.get_object_pos(item_object.building_object_id) + town_window._building_output_params[_id]["sell_buy_off"]
	
	town_effects.visual_effects:CreateClipEffect(town_window._sell_clip, building_pos, nil, true)
	
	--- вызываем смену состояния в городе
	town_window._ChangeObjectState(item_object, item_object.current_level)
	town_window._ChangeIconState(item_object, item_object.current_level)
	
	town_effects.AddFlyRes(town_window._gold_res_pos, 
	                        town_window._res_fly_speed, 
							building_pos, 
							town_window._gold_fly_effect,
							tostring(current_item_level_info.money_cost*town_window._sell_koef),
							true
							)
	
	--- обновляем виджеты ресурсов
	town_window._UpdateBuildingProgress()
	--town_window._UpdateInfoOutput() --- после эффекта обновится
	town_window._UpdateCostHints()
	town_window._UpdateBuyHint()
	--town_window._InitSceneObjects()
	town_window._InitObjectsVisibility()
	-- прячем инф окно пр ипокупке или продаже
	--town_window._CloseBuildingInfoWindow()
end

--- обновление отображаемой в виджетах информации
function town_window._UpdateInfoOutput()
	town_window._money_label.SetText( tostring(town_window._current_profile.GetMoney()))
	--[[
	if town_window._power_label then
		town_window._power_label.SetText( tostring(town_window._current_profile.GetPower()))
	end
	if town_window._level_label then
		town_window._level_label.SetText( tostring(town_window._current_profile.GetPlayerLevel()))	
	end
	]]
end

--- обновление отображаемой в виджетах информации
function town_window._UpdateBuildingProgress()
	-- обновить значение прогресс-бара
	local curr_level = 0
	for _,item in pairs(town_window._items_info) do
		curr_level = curr_level + item.current_level
	end
	town_building_progress.SetValue(curr_level)
end

function town_window._UpdateCostHints()
	for id, info in pairs(town_window._items_info) do
		info.buyable = town_window.IsBuyable(id)
		town_window._SetGlowVisibility(info, false)	
		cost_hint_widget.InitHint(id, info)
	end
end

--- поиск виджетов для отображения информации
function town_window._FindWidgets(_window)
	town_window._money_label = get_child_widget(_window, "money_label", sf.gui.CLabelWidget, "ошибка")
	town_window._power_label = nil 
	town_window._level_label = nil 
end

--- вызывается при наведении мышкой на здание
function town_window.OnMouseOverItem(_id)
	local info_object = town_window._items_info[_id]
	town_window._SetGlowVisibility(info_object, true, true)
	cost_hint_widget.FadeInHint(_id)
	__sound("building_over")
	town_window._hand_cursor = true
end

--- вызывается при наведении мышкой на иконку
function town_window.OnMouseOverIconItem(_id)
	local info_object = town_window._items_info[_id]
	town_window._SetGlowVisibility(info_object, true, true, info_object.was_buyed)
	cost_hint_widget.FadeInHint(_id)
	__sound("building_over")
	town_window._hand_cursor = true
end

--- вызывается, когда курсор покидает здание/иконку
function town_window.OnMouseLeaveItem(_id)
	local info_object = town_window._items_info[_id]
	town_window._SetGlowVisibility(info_object, false, true)
	cost_hint_widget.FadeOutHint(_id)
	town_window._hand_cursor = false
end

--- вызывается при клике на здание/иконку
function town_window.OnItemClick(_id)
	local info_object = town_window._items_info[_id]	
	if info_object.was_buyed or info_object.buyable then
		town_window._OpenBuildingInfoWindow(_id)
		__sound("building_press")
	else
		child_dialog("disabled_building", town_window._self)
	end
end

-- установка скриптов на объект сцены
function town_window._SetScriptsOnObjects(_scene_object, _item_info_id, _icon_script)
	_scene_object.SetLuaScript([[town_window.OnItemClick("]].._item_info_id..[[")]], qe.CBaseSceneObject.ScriptMouseClick)
	if _icon_script then
		_scene_object.SetLuaScript([[town_window.OnMouseOverIconItem("]].._item_info_id..[[")]], qe.CBaseSceneObject.ScriptMouseEnter)
	else
		_scene_object.SetLuaScript([[town_window.OnMouseOverItem("]].._item_info_id..[[")]], qe.CBaseSceneObject.ScriptMouseEnter)
	end
	_scene_object.SetLuaScript([[town_window.OnMouseLeaveItem("]].._item_info_id..[[")]], qe.CBaseSceneObject.ScriptMouseLeave)
end

--- поиск объектов сцены для элементов
function town_window._LinkItemsAndSceneObjects()
	for id,o in pairs(town_window._items_info) do
		-- ищем здание
		local building_object = quest.FindRootObjectById(id.."#B")
		if building_object then
			o.building_object_id = id.."#B"
			town_window._SetScriptsOnObjects(building_object, id)
		end
		
		-- ищем иконку
		local icon_object = quest.FindRootObjectById(id.."#B_icon")
		if icon_object then
			o.icon_object_id = id.."#B_icon"
			
			town_window._SetScriptsOnObjects(icon_object, id, true)
		end

		-- ищем простую иконку(имеет два состояния)
		local simple_icon = quest.FindRootObjectById(id.."#B_icon_simple")
		if simple_icon then
			o.icon_simple = id.."#B_icon_simple"
			town_window._SetScriptsOnObjects(simple_icon, id, true)
		end
		
		-- ищем сияние здания
		if quest.FindRootObjectById(id.."#B_glow") then
			o.glow_object_id = id.."#B_glow"
		end
		
		-- ищем сияние иконки
		if quest.FindRootObjectById(id.."#B_icon_glow") then
			o.icon_glow_object_id = id.."#B_icon_glow"

			o.icon_pos = quest.get_object_pos(o.icon_glow_object_id)
			
		end

	end
end

-- инициализация объектов сцены в соответсвии с итемами
function town_window._InitSceneObjects(_fast_change)
	for _,o in pairs(town_window._items_info) do
		town_window._ChangeObjectState(o, o.current_level, _fast_change)
		town_window._ChangeIconState(o, o.current_level)
		--town_window._ChangeObjectVisibility(o, _hide_glow)
	end
end

-- инициализация объектов сцены в соответсвии с итемами
function town_window._InitObjectsVisibility(_hide_glow)
	for _,o in pairs(town_window._items_info) do
		town_window._ChangeObjectVisibility(o, _hide_glow)
	end
end


function town_window._ChangeObjectVisibility(_item_info_object, _hide_glow)
	if _hide_glow then
		town_window._SetGlowVisibility(_item_info_object, false)
	end
	local buyable = town_window.IsBuyable(_item_info_object.id)
	town_window._SetObjectVisibility(_item_info_object, buyable or _item_info_object.was_buyed)
end


-- меняет состояние объектове сцены соответсвующих итему
function town_window._ChangeObjectState(_item_info_object, _state_number, _fast_change)
	if _item_info_object.building_object_id then
		if not _fast_change then
			change_state_ex(false, town_window._state_change_time, false, _item_info_object.building_object_id, "_s"..tostring(_state_number))
		else
			change_state_ex(true, 0, false, _item_info_object.building_object_id, "_s"..tostring(_state_number))
		end
	end
	if _item_info_object.glow_object_id then
		if not _fast_change then
			change_state_ex(false, town_window._state_change_time, false, _item_info_object.glow_object_id, "_s"..tostring(_state_number))
		else
			change_state_ex(true, 0, false, _item_info_object.glow_object_id, "_s"..tostring(_state_number))
		end
	end
end

-- меняет состояние объектове сцены соответсвующих итему
function town_window._ChangeIconState(_item_info_object, _state_number)
	
	if _item_info_object.icon_object_id then
		if _item_info_object.was_buyed or _item_info_object.buyable then
			change_state_ex(true, 0, false, _item_info_object.icon_object_id, "_s"..tostring(_state_number))
		else
			change_state_ex(true, 0, false, _item_info_object.icon_object_id, "_s")
		end
	end
	-- устанавливаем состояние простой иконки
	-- если состояние здания 0 то у простоя иконки будет неактивное состояние
	-- иначе активное
	if _item_info_object.icon_simple then
		if _item_info_object.was_buyed or _item_info_object.buyable then
			local state = "_s0"
			if _state_number > 0 then
				state = "_s1"
			end
			change_state_ex(true, 0, false, _item_info_object.icon_simple, state)
		else
			change_state_ex(true, 0, false, _item_info_object.icon_simple, "_s")
		end
	end
end

-- меняет видимость объекта
-- _item_info_object - информация о подсвечиваемом объекте
-- _value - значение нужно ли отобразить подсветку или спрятать
function town_window._SetObjectVisibility(_item_info_object, _value)
	if _item_info_object.building_object_id then
		town_window.vis_func[_value](0, false, _item_info_object.building_object_id)
	end
end

-- функция, которая вызывается окном здания при нажатии кнопки купить
function town_window.OnBuyInInfoWindow()
	local id = town_window._info_window_id
	town_window.BuyItem(id)
	town_window._CloseBuildingInfoWindow()
end

-- функция, которая вызывается окном здания при нажатии кнопки продать
function town_window.OnSellInInfoWindow()
	local id = town_window._info_window_id
	town_window.SellItem(id)
	town_window._CloseBuildingInfoWindow()
end

-- азкрытие информационного онка
function town_window._CloseBuildingInfoWindow()
	if town_window._info_window_id and town_window._info_window_widget then
		cost_hint_widget.ShowHint(town_window._info_window_id)
		--town_window._self.RemoveWidget(town_window._info_window_widget)
		set_widget_flag_value(town_window._info_window_widget, sf.gui.CBaseWidget.FlagDisabled, true)
		s11.AddEffectToWidget(town_window._info_window_widget, sf.graphics.Color(0, 255, 255, 255), town_window._hide_window_effect, 0)
		s11.AddRemoveEffectToWidget(town_window._info_window_widget, town_window._hide_window_effect)
		
		
		__sound("bubble_help_disappear")
		town_window._info_window_widget = nil
		town_window._info_window_id = nil
	end
end

--- открытие нового окна покупки/продажи здания
function town_window._OpenBuildingInfoWindow(_item_id)
	
	-- если это окно уже открыто, то выходим
	if town_window._info_window_id == _item_id then
		return
	end
	--- если есть другое открытое окно, то закрываем его
	town_window._CloseBuildingInfoWindow()
	
	-- прячем ценовой хинт
	cost_hint_widget.HideHint(_item_id)
	
	local item_info = town_window._items_info[_item_id]
	
	--- если нет информации о элементе, то ругаемся и выходим
	if not item_info then
		__message("Unknown item id: ".._item_id)
		return
	end
	
	-- создаем окно с информацией о здании
	local building_info_widget = building_info_window.FormBuildingInfoWidget(item_info, town_window._current_profile)
	--- если из-за чего-то окно не создалось, то ругаемся и выходим
	if not building_info_widget then
		__message("Building info creation error.")
		return
	end
	
	-- располгаем окно по центру над зданием и так что бы оно не выходило за края экрана + отступы сверух и снизу
	local info_window_size = building_info_widget.GetSize()
	
	local building_pos = quest.get_object_pos(item_info.building_object_id)

	building_pos = building_pos + town_window._building_output_params[_item_id]["arr_off"]

	arrow_setter.MoveArrow(building_info_widget, building_pos, town_window._arrow_offset, town_window._arrow_limits)
	
	-- устанавливаем текущее открытое окно здания
	town_window._info_window_widget = building_info_widget
	town_window._info_window_id = _item_id	
    --- добавляем окно задния
	building_info_widget.SetColor(sf.graphics.Color(0, 255, 255, 255))
	s11.AddEffectToWidget(building_info_widget, sf.graphics.Color(255, 255, 255, 255), town_window._show_window_effect, 0)
	town_window._self.AddWidget(building_info_widget)
	town_window._self.HideToolTip()
	cost_hint_widget.HideHints()
end

function town_window.GetBuyHintArrowOffset(_item_id, _level)
--	__message(tostring(_level))
	local off_info = town_window._building_output_params[_item_id]["buy_hint_off"]
	if not off_info then
		return town_window._hint_arrow_offset
	end
	if type(off_info) == "table" then
		if off_info[_level] then
			return off_info[_level]
		else
			__message("bad buy hint arrow offset ".._item_id.. " level = "..tostring(_level) )
			return town_window._hint_arrow_offset
		end
		
	else
		return off_info
	end
end

function town_window.GetFlyIconId(_item_id, _level)
--	__message(tostring(_level))
	
	local icon_offset = town_window._building_output_params[_item_id]["fly_icon_start_offset"] or sf.misc.FloatVector(0, 0)
	local icon_info = town_window._building_output_params[_item_id]["fly_icon"]
	if not icon_info then
		return "screens_town_icons_bonuses_incomplete", icon_offset
	end
	if type(icon_info) == "table" then
		if icon_info[_level] then
			return icon_info[_level], icon_offset
		else
			__message("bad fly icon info ".._item_id.. " level = "..tostring(_level) )
			return "screens_town_icons_bonuses_incomplete", icon_offset
		end
		
	else
		return icon_info, icon_offset
	end
end

function town_window.ShowDisableBuyTutorial(_pos, _res_table)
	-- по позиции _pos нужно отобразить эффект подсветки недостающих ресурсов в окне здания
	-- и птому убить этот эффект, когда закончится туториал
	if not town_window._disable_buy_tutorial then
		return
	end
	local text = ""
	if _res_table["level"] then
		
		if _res_table["level_low"] then
			text = text..town_window._res_tutorial_strings["level_low"].str.."\n"
		else
			local level_coord  = town_window._current_profile.GetMatchLevelByIndex(_res_table["level_target"])
			local classic_level_system = s11.g_GameStruct.Instance().GetLevelsSystem(s11.CGameStruct.GameTypeClassic)
			local dif_level_name = classic_level_system.GetDifLevelName(level_coord.DifLevel)
			local level = classic_level_system.GetLevel(level_coord.DifLevel, level_coord.LevelIndex)
			local chapter_index = level.GetChapterIndex()
			local index_in_chapter = level.GetLevelIndexInChapter()
			text = text..s11.StringFormat(town_window._res_tutorial_strings["level"].str, string.format("%i-%i", chapter_index+1, index_in_chapter+1) ,dif_level_name).."\n"
		end
		town_window._disable_tutorial_show_flag = true
		tutorial_window.Show(town_window._self, "town_buy_disable_level", nil, nil, nil, nil, nil, text)
		return
		
	elseif _res_table["money"] then
		
		sf.misc.g_StringTable.Instance().FormatByStringsID(game_window.press_any_key.params.text)
		
		text = text..town_window._res_tutorial_strings["money"].str.."\n"

		town_window._disable_tutorial_show_flag = true
		tutorial_window.Show(town_window._self, "town_buy_disable", 
			{widget=town_window._info_window_widget, flags={draw=true}}, _pos, _pos, nil, nil, text)
		return
	end
end

function town_window.GetPlayerLevel()
	return town_window._current_profile.GetPlayerLevel()
end

function town_window._CreateImageForEffect(_image_id, _effect_table)
	_effect_table["image"] = sf.graphics.CImage(_image_id)
	
	local image_size_int = _effect_table["image"].GetTextureSize()
	
	_effect_table["image_size"] = sf.misc.FloatVector(image_size_int.X, image_size_int.Y)
	
end

function town_window.Show()
	
	town_window._CreateImageForEffect("screens_town_icon_coin", town_window._gold_fly_effect)
	town_window._CreateImageForEffect("screens_town_icon_power", town_window._power_fly_effect)
	
	town_window.effects_list = {}

	local window = __ChangeWindowWithEffect()
	if not window then
		return
	end

	town_window._hand_cursor = false

	town_window._town_timer = sf.core.CTimerWrapper(sf.core.g_Application.GetTimeManager().GetTimer("game_timer").AttachTimer(""))

	town_window.vis_func = {}
	town_window.vis_func[true] = show_ex
	town_window.vis_func[false] = hide_ex

	town_window._levels_struct = s11.g_GameStruct.Instance().GetLevelsSystem(s11.CGameStruct.GameTypeClassic)
	--- инициализируем текущий профайл
	town_window._profile = s11.g_ProfileManager.Instance().GetCurrentProfile()
	avatar_widget.InitAvatar(town_window._profile.IsFemale())
	town_window._current_profile = town_window._profile.GetClassicData()
	

	town_window._tutorial_flags = town_window._current_profile.GetTutorialFlags()

	-- флаг туториала на превую покупку
	town_window._first_buy_tutorial = not town_window._tutorial_flags.ReadFlag(s11.CProfileDataClassic.TutorialFlagBuy)
	
	town_window._after_first_buy_tutorial = nil
	if not town_window._first_buy_tutorial then
		town_window._after_first_buy_tutorial = not town_window._tutorial_flags.ReadFlag(s11.CProfileDataClassic.TutorialFlagAfterFirstBuy)
	end
	
	-- туториал на недоступную кнопку купить
	town_window._disable_buy_tutorial = not town_window._tutorial_flags.ReadFlag(s11.CProfileDataClassic.TutorialFlagLowResources)

	--local window = sf.gui.CWindow()

	town_window._self  = window
	window.Load(
		g_App.GetSettings().GetChild("GUI", false).GetChildByAttribute("window", "id", "town_window", true), 
		g_App.GetSettings().GetChild("GUITemplates", false))
	
	
	
	town_window._gui_tutorial = get_child_widget(window, "gui_tutorial", sf.gui.CLuaWidget) 
	__visible(town_window._gui_tutorial, false)
	town_window._scene_tutorial = get_child_widget(window, "scene_tutorial", sf.gui.CLuaWidget) 
	__visible(town_window._scene_tutorial, false)
	
	town_window._power_tutorial = false
	if not town_window._tutorial_flags.ReadFlag(s11.CProfileDataClassic.TutorialFlagPower) and
		town_window._level_for_show_power_tutorial <= town_window._current_profile.GetPlayerLevel()  then
		town_window._power_tutorial = true
		-- инициация окна с описанием могущества
	end

	
	--- ищем виджеты ресурсов игрока
	town_window._FindWidgets(window)
	
	window.UpdateLayout()
	
	local window_size = window.GetSize()
	window.SetOffset((1024 - window_size.X)/2, (768 - window_size.Y)/2)

	

	if not town_window._current_profile then
		__message("текущий профайл не задан")
		return
	end
	
	-- формируем пустую таблицу для задний города id = {}
	town_window._items_info	= town_info.FormEmptyBuildingsTable()
	
	--- инициализация уровней апгрейда итемов
	local max_level = 0
	local curr_level = 0
	for i,_ in pairs(town_window._items_info) do
		local level = town_window._current_profile.GetItemLevel(i)
		local was_buyed = town_window._current_profile.WasNotZero(i)
		if level == -1 then
			--__message("попытка загрузить из профала неизвестный параметр"..i)
		else
			curr_level = curr_level + level
			max_level = max_level + 4
			town_window._items_info[i].current_level = level
			town_window._items_info[i].was_buyed = was_buyed
		end
	end
	
	town_building_progress.SetMaxValue(max_level)
	town_building_progress.SetValue(curr_level, true)
	
	--- инициализируем виджеты ресурсов игока
	town_window._UpdateInfoOutput()
	
	--- инициализируем сцену города
	local scene_widget = get_child_widget(window, "town_scene_widget", qe.CSceneWidget) 
	if not scene_widget then
		--- если нет виджета сцены города, то ругаемся и выходим
		__message("Scene widget "..[["town_scene_widget"]].." for town view not found")
		return
	else
		quest.StartScene(window, scene_widget, "Town_Level", "Town_Scene")
	end
	
	town_window._scene_widget_pos = scene_widget.GetAbsPos(false)
	
	--- ищем объекты на сцене и связываем их с итемами
	town_window._LinkItemsAndSceneObjects()
	--- устанавливаем первончалаьное состояние объектов в соответсвии с уровнями итемов
	town_window._InitSceneObjects(true)
	town_window._InitObjectsVisibility(true)
	
	town_window._UpdateCostHints()
	
	s11.g_TrackManager.Instance().UpdateCurrentTrack("town_map", false)
	
	

	town_window._all_upgrades = town_window.CheckBuildings(town_window.upgrade_buildings, 1)	
	town_window._all_bonuses = town_window.CheckBuildings(town_window.bonus_buildings, 1)	
	town_window._all_totems = town_window.CheckBuildings(town_window.totem_buildings, 1)	
	
	--- все есть что нужно, показываем окно
	--g_App.SetMainWindow(window)

	
	local resume_widget = sf.gui.CLuaWidget("cursor_drop", 1, sf.gui.CWidget.BroadcastOnMouseMove)

	-- настраиваем всякое что бы он работал
	resume_widget.SetOffset(0, 0)
	resume_widget.SetSize(1024, 768)
	resume_widget.SetLua(g_Lua.GetId())
	resume_widget.SetOverloadTable("cursor_drop_widget")
	
	-- доавляем его в кнопку
	window.AddWidget(resume_widget)
	
	window = 0

	collectgarbage()
	
	town_window._UpdateBuyHint()
	
	town_window.OnShowWindow = function ()
		if town_window._after_first_buy_tutorial == true then
			dialog_do_modal("after_first_buy_dialog", town_window._self)
			town_window._tutorial_flags.RaiseFlag(s11.CProfileDataClassic.TutorialFlagAfterFirstBuy)
		end
	end
end

function town_window._UpdateBuyHint()
	local hint_widget = get_child_widget(town_window._self, "hint_clip_widget", sf.gui.CClipWidget) 
	local show_hint_id = ""
	local show_hint_level = -1
	local next_level_info = town_window._current_profile.GetNextNotPlayedLevel()
	local next_level_dif_index = next_level_info.DifLevel
	local next_level_index = next_level_info.LevelIndex
	local update_need = false
	if next_level_dif_index ~= -1 and next_level_index ~= -1 then
		
		local _level_info = town_window._levels_struct.GetLevel(next_level_dif_index, next_level_index)
		
		local match_level_info = __cast(_level_info, s11.CMatchLevelInfo)
		
		if not match_level_info then
			set_widget_flag_value(hint_widget, sf.gui.CBaseWidget.FlagHidden, true)  
		else
			if match_level_info.EnumDependences() == 0 then
				set_widget_flag_value(hint_widget, sf.gui.CBaseWidget.FlagHidden, true)  
			else
				local current_dep = match_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
				local player_item_level = town_window._current_profile.GetItemLevel(dep_item_id)
				
				local building_item_info = town_window._items_info[dep_item_id]
				__assert(building_item_info, "Unknown item :"..dep_item_id)
				-- проверяем есть ли у игрока нужное задние
				if player_item_level < dep_item_level then
					building_item_info.was_buyed = true
					update_need = true
					set_widget_flag_value(hint_widget, sf.gui.CBaseWidget.FlagHidden, false)  
					local building_pos = quest.get_object_pos(building_item_info.building_object_id) 
											 - hint_widget.GetSize()/2
												+ town_window.GetBuyHintArrowOffset(dep_item_id, player_item_level )

					hint_widget.SetOffset(building_pos.X, building_pos.Y)
				else
					set_widget_flag_value(hint_widget, sf.gui.CBaseWidget.FlagHidden, true)  
				end
			end
		end
		
	end
	if update_need then
		--town_window._InitSceneObjects(true)
		town_window._InitObjectsVisibility()
	end
end

function town_window.DoDraw(_this, _renderer)
end

function town_window.EmptyClick()
	town_window._CloseBuildingInfoWindow()
end

function town_window.DoUpdate(_this)

	if town_window.OnShowWindow then
		if not s11.WindowHasEffects(town_window._self) then
			local show_func = town_window.OnShowWindow
			town_window.OnShowWindow = nil
			show_func()
		end
	end
	
	quest.Update()
end

function town_window.OnChar(_this, _char, _keyboard_state, _state, _broadcast)
    if _this.SuperOnChar(_char, _keyboard_state, _state, _broadcast) then return true end	
    return false
end

function town_window.OnKeyDown(_this, _key, _keyboard_state, _state, _broadcast)
	if sf.core.g_Application.GetDebugLevel() >= sf.core.g_Application.DebugCheats then
		if _key == 112 then
			town_window._current_profile.DropSavedLevelInfo()
			town_window._profile.SaveGameType(s11.CGameStruct.GameTypeClassic)

			town_window._current_profile.SetMoney(town_window._current_profile.GetMoney() + 1000)
			town_window._UpdateInfoOutput()
			town_window._UpdateCostHints()
			--town_window._InitSceneObjects()
			town_window._InitObjectsVisibility()
		end
		if _key == 114 then
			town_window._current_profile.DropSavedLevelInfo()
			town_window._profile.SaveGameType(s11.CGameStruct.GameTypeClassic)
		
			town_window._current_profile.SetPlayerLevel(town_window._current_profile.GetPlayerLevel() + 1)
			town_window._UpdateInfoOutput()
			town_window._UpdateCostHints()
			--town_window._InitSceneObjects()
			town_window._InitObjectsVisibility()
		end
		
	end
	if _this.SuperOnKeyDown( _key, _keyboard_state, _state, _broadcast) then
        return true
    end
    return false
end

function town_window.OnKeyUp(_this, _key, _keyboard_state, _state, _broadcast)
	return _this.SuperOnKeyUp( _key, _keyboard_state, _state, _broadcast)
end

function town_window.OnMouseMove(_this, _pos, _state, _broadcast)
	if town_window._hand_cursor then
		sf.gui.g_Cursor.Instance().SetCursor( sf.gui.CCursor.CursorHand )
	end
	return _this.SuperOnMouseMove( _pos, _state, _broadcast) 
end

function town_window.OnMouseDown(_this, _pos, _button, _state, _broadcast)
    -- отключение хинта на могущество
	if town_window._power_tutorial == true then
		__visible(town_window._gui_tutorial, false)
		town_window._power_tutorial = false
		town_window._tutorial_flags.RaiseFlag(s11.CProfileDataClassic.TutorialFlagPower)
	end
	
	if town_window._disable_tutorial_show_flag and not _broadcast then
		-- тут нужно еще убить эффект на недостающие ресурсы в окне с информацией о городе
		town_window._disable_tutorial_show_flag = false
		__visible(town_window._gui_tutorial, false)
	end

	return _this.SuperOnMouseDown( _pos, _button, _state, _broadcast) 
end

function town_window.OnMouseUp(_this, _pos, _button, _state, _broadcast)
	return _this.SuperOnMouseUp( _pos, _button, _state, _broadcast) 
end

function town_window.OnDoubleClick(_this, _pos, _state, _broadcast)
	return _this.SuperOnDoubleClick( _pos, _state, _broadcast) 
end

function town_window.OnMouseWheel(_this, _pos, _delta, _state, _broadcast)
	return _this.SuperOnMouseWheel( _pos, _delta, _state, _broadcast)
end

--- виджет для отключение курсора руки
cursor_drop_widget = {}

function cursor_drop_widget.__CreateInstance()
    return "cursor_drop_widget"
end

__inherite(cursor_drop_widget, null_lua_widget_handler())

function cursor_drop_widget.OnMouseMove(_this, _pos, _state, _broadcast)
	if _broadcast and cursor_drop_widget.drop_cursor then
		sf.gui.g_Cursor.Instance().SetCursor( sf.gui.CCursor.CursorPointer )
		cursor_drop_widget.drop_cursor = nil
		return true
	end
	return false
end

