main_menu = main_menu or {}
main_menu.actions = main_menu.actions or {}

main_menu._name_title_string_id = sf.misc.g_StringTable.Instance().FormatByStringsID("$42")
main_menu._simple_title_string_id = sf.misc.g_StringTable.Instance().FormatByStringsID("$41")

main_menu.alpha_hide_delay = 4000
main_menu.alpha_show_delay = 2000
main_menu.start_effect_state = nil
main_menu.start_effect_time = nil
main_menu.total_effect_time = nil
main_menu.timer = __create_timer()

main_menu.alpha_widgets_id_table = { }
main_menu.hide_widgets_id_table = { }
main_menu.last_frame_id_table = { }
main_menu.alpha_widgets_table = {}

function main_menu.init_welcome(_target_window)
	local label_widget = __cast(_target_window.GetWidget("welcome_label").get(), "sf.gui.CLabelWidget")
	local change_button_widget = __cast(_target_window.GetWidget("change_player_button").get(), "sf.gui.CButtonWidget")
	local clip_widget = __cast(_target_window.GetWidget("player_clip").get(), "sf.gui.CClipWidget")
	local current_profile = s11.g_ProfileManager.Instance().GetCurrentProfile()
	if label_widget then
		local num_profiles = s11.g_ProfileManager.Instance().EnumProfiles()
		
		if num_profiles ~= 0 and current_profile then
			local profile = s11.g_ProfileManager.Instance().GetCurrentProfile()
			local is_female = profile.IsFemale()
			if is_female then
				clip_widget.GetClip().Load("mainmenu_woman")
			else
				clip_widget.GetClip().Load("mainmenu_man")
			end
			local profile_name = profile.GetName()
			label_widget.SetText(
				s11.StringFormat(main_menu._name_title_string_id, profile_name)
				)
			set_widget_flag_value(change_button_widget, sf.gui.CBaseWidget.FlagHidden, false)
			set_widget_flag_value(change_button_widget, sf.gui.CBaseWidget.FlagDisabled, false)

			if main_menu.start_effect_state then
				set_widget_flag_value(change_button_widget, sf.gui.CBaseWidget.FlagDisabled, true)
			end
				
		else
			label_widget.SetText(main_menu._simple_title_string_id)
			set_widget_flag_value(change_button_widget, sf.gui.CBaseWidget.FlagHidden, true)
			set_widget_flag_value(change_button_widget, sf.gui.CBaseWidget.FlagDisabled, true)
		end
	end
	main_menu._disabled_buttons = {}
	
	local allow_puzzle = nil
	local allow_endless = nil
	if current_profile then
		allow_puzzle = current_profile.GetGameModeFlags().ReadFlag(s11.CProfile.GameModeFlagPuzzle)
		allow_endless = current_profile.GetGameModeFlags().ReadFlag(s11.CProfile.GameModeFlagEndless)
	end
	local puzzle_button = get_child_widget(_target_window, "puzzle_play", sf.gui.CButtonWidget)
	if not allow_puzzle then
		if sf.core.g_Application.GetDebugLevel() == 0 then
			puzzle_button.DisableButton(true)
			main_menu._AddDisabledWidget(puzzle_button, 
				function () dialog_do_modal("mainmenu_puzzle_disable_dialog", main_menu._self) end )
		end
	else
		puzzle_button.DisableButton(false)
	end

	local endless_button = get_child_widget(_target_window, "endless_play", sf.gui.CButtonWidget)
	if not allow_endless then
		if sf.core.g_Application.GetDebugLevel() == 0 then
			endless_button.DisableButton(true)
			main_menu._AddDisabledWidget(endless_button, 
				function () dialog_do_modal("mainmenu_endless_disable_dialog", main_menu._self) end )
		end
	else
		endless_button.DisableButton(false)
	end
end

function main_menu.DoDraw(_this, _renderer)
	if __and(_this.GetFlags(), sf.gui.CBaseWidget.FlagHidden) == 0 then
		s11.effects.StartShaderSurface(_renderer)
		s11.effects.SetShaderSurface(_renderer, true)
		main_menu._shader_clip.Draw(_renderer)
		s11.effects.SetShaderSurface(_renderer, false)
	end
end

function main_menu.DoUpdate(_this)
	main_menu._shader_clip.Update()
	if main_menu.start_effect_state and main_menu.start_effect_time then
        local current_time = main_menu.timer.Get().GetTime()
        local koef = (current_time - main_menu.start_effect_time)/main_menu.total_effect_time
        if koef >= 1 then
            koef = 1
        end
        if main_menu.start_effect_state == 1 then
            if koef == 1 then
                main_menu.start_effect_state = 2
                main_menu.start_effect_time = current_time
                main_menu.total_effect_time = main_menu.alpha_show_delay
            end
        elseif main_menu.start_effect_state == 2 then
            for i,o in pairs(main_menu.alpha_widgets_id_table) do
                local color = sf.graphics.Color(o.widget.GetColor())
                color.Alpha = koef * 255
                o.widget.SetColor(color)
            end

            if koef == 1 then
                for i,o in pairs(main_menu.alpha_widgets_id_table) do
                    set_widget_flag_value(o.widget, sf.gui.CBaseWidget.FlagDisabled, false)      
                end

				for i,o in pairs(main_menu.hide_widgets_id_table) do
                    local w = _this.GetWidget(i).get()
                    if w then
                        o.widget = w
                        set_widget_flag_value(w, sf.gui.CBaseWidget.FlagDisabled, true)
                        set_widget_flag_value(w, sf.gui.CBaseWidget.FlagHidden, true)
                    end
                end
				
                main_menu.start_effect_state = nil
                main_menu.start_effect_time = nil
                main_menu.total_effect_time = nil
                main_menu.init_welcome(_this)
            end
        end
    end
end

main_menu.cheat_queue = {"m", "o", "n", "t", "e", "z", "u", "m", "a"}
main_menu.cheat_index = 1

function main_menu.OnChar(_this, _char, _keyboard_state, _state, _broadcast)
    if _this.SuperOnChar(_char, _keyboard_state, _state, _broadcast) then return true end	
	if main_menu.cheat_index < #main_menu.cheat_queue+1 then
        if _char == main_menu.cheat_queue[main_menu.cheat_index] then
            main_menu.cheat_index = main_menu.cheat_index + 1
            if main_menu.cheat_index > #main_menu.cheat_queue then
                if sf.core.g_Application.GetDebugLevel() >= 1 then
                    sf.core.g_Application.SetDebugLevel(0)
                else
                    sf.core.g_Application.SetDebugLevel(1)
                end
                main_menu.cheat_index = 1
            end
        else
            main_menu.cheat_index = 1
        end
    end
    return false
end

function main_menu.OnKeyDown(_this, _key, _keyboard_state, _state, _broadcast)
	if _this.SuperOnKeyDown( _key, _keyboard_state, _state, _broadcast) then
        return true
    end
	if sf.core.g_Application.GetDebugLevel() >= sf.core.g_Application.DebugCheats then
		if _key == 112 then
			local current_profile = s11.g_ProfileManager.Instance().GetCurrentProfile()
			if current_profile then
				current_profile.GetClassicData().GetTutorialFlags().SetFlags(0)
				current_profile.GetEndlessData().GetTutorialFlags().SetFlags(0)
				current_profile.GetPuzzleData().GetTutorialFlags().SetFlags(0)
			end
			
		end
	end
	
    return false
end

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

function main_menu.OnMouseMove(_this, _pos, _state, _broadcast)
	return _this.SuperOnMouseMove( _pos, _state, _broadcast) 
end

function main_menu.OnMouseDown(_this, _pos, _button, _state, _broadcast)

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

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

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

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

function main_menu.OnChildAction(_this, _action, _child)
	if not _child then return end
	local handler = main_menu.actions[_child.GetId().c_str()]
	if handler then handler = handler[_action.c_str()] end
	if handler then handler(_this, _child) end
end
		
function main_menu.Show(_show_alpha_widgets, _show_records_panel, _no_effect)

	local window = __ChangeWindowWithEffect(_no_effect, not no_effect)
	if not window then
		return
	end
	s11.g_GameBackground.Instance().DisableSounds(true)

	main_menu._shader_clip = sf.misc.anim.CClip()
	main_menu._shader_clip.Load("shader_mainmenu", true)
	
	main_menu._shader_clip.SetPos(sf.misc.FloatVector(512, 384))
	main_menu._shader_clip.Stop()
	main_menu._shader_clip.Play()

	sf.core.g_Application.GetTimeManager().GetTimer("game_timer").SetK(1)
	window.Load(
		g_App.GetSettings().GetChild("GUI", false).GetChildByAttribute("window", "id", "main_menu", true), 
		g_App.GetSettings().GetChild("GUITemplates", false))
	window.SetSize(1024, 768)
	window.UpdateLayout()
	
	local main_menu_info =  g_App.GetSettings().GetChild(_T("Constants"), false).GetChild(_T("main_menu"), false)
    
	if main_menu_info then
        local res = tonumber(main_menu_info.GetValue("alpha_hide_delay").c_str())
        if res ~= nil then main_menu.alpha_hide_delay = res end

        res = tonumber(main_menu_info.GetValue("alpha_show_delay").c_str())
        if res ~= nil then main_menu.alpha_show_delay = res end

        main_menu.alpha_widgets_id_table = {}
        local alpha_item = main_menu_info.GetChild(_T("alpha_group"), false).GetFirstChildRef()
        while alpha_item do
            local id_value = alpha_item.GetValue("id").c_str()
            if id_value ~= "" then
                main_menu.alpha_widgets_id_table[id_value] = {}
            end            
            alpha_item = alpha_item.GetNextSiblingRef()
        end
		
        main_menu.hide_widgets_id_table = {}
        local hide_item = main_menu_info.GetChild(_T("hide_group"), false).GetFirstChildRef()
        while hide_item do
            local id_value = hide_item.GetValue("id").c_str()
            if id_value ~= "" then
                main_menu.hide_widgets_id_table[id_value] = {}
            end    
            hide_item = hide_item.GetNextSiblingRef()
        end
		
        main_menu.last_frame_id_table = {}
        local last_frame_item = main_menu_info.GetChild(_T("last_frame_group"), false).GetFirstChildRef()
        while last_frame_item do
            local id_value = last_frame_item.GetValue("id").c_str()
            if id_value ~= "" then
                main_menu.last_frame_id_table[id_value] = {}
            end
            last_frame_item = last_frame_item.GetNextSiblingRef()
        end
    end
		
	if _show_alpha_widgets then
        main_menu.start_effect_state = 1
        main_menu.start_effect_time = main_menu.timer.Get().GetTime()
        main_menu.total_effect_time = main_menu.alpha_hide_delay

        for i,o in pairs(main_menu.alpha_widgets_id_table) do
            local w = window.GetWidget(i).get()
            if w then
                o.widget = w
				local color = sf.graphics.Color(w.GetColor())
				color.Alpha = 0
                w.SetColor(color)
                set_widget_flag_value(w, sf.gui.CBaseWidget.FlagDisabled, true)
            end
        end
    else
        for i,o in pairs(main_menu.hide_widgets_id_table) do
            local w = window.GetWidget(i).get()
            if w then
                o.widget = w
                set_widget_flag_value(w, sf.gui.CBaseWidget.FlagDisabled, true)
                set_widget_flag_value(w, sf.gui.CBaseWidget.FlagHidden, true)
            end
        end

        for i,o in pairs(main_menu.last_frame_id_table) do
            local w = window.GetWidget(i).get()
            if w then                                 
                local clip = __cast(w, "sf.gui.CClipWidget")
                if clip then
                    local duration = qe.GetClipTime(clip.GetClip())
                    clip.GetClip().MoveTime(duration)
                end
            end
        end
    end

	main_menu._self = window
	
	main_menu.init_welcome(window)
	
	s11.g_TrackManager.Instance().UpdateCurrentTrack("mainmenu", false)
	
	if _show_records_panel then
		records_window.Show(window, _show_records_panel, true)
	end

	if _no_effect then
		g_App.SetMainWindow(window)
	end
	
	window = 0

	collectgarbage()
end

function main_menu._AddDisabledWidget(_widget, _click_func)
	local new_disabled_button = {}
	new_disabled_button.size = _widget.GetSize()
	new_disabled_button.offset = _widget.GetOffset()
	new_disabled_button.func = _click_func
	table.insert(main_menu._disabled_buttons, new_disabled_button)
end

function main_menu.create_profile(_owner)
        local modal_res = user_profiles.run_modify_name_dialog(_owner, "new")
        if modal_res == 1 then
                main_menu.init_welcome(_owner)
                s11.g_ProfileManager.Instance().Save()
        elseif modal_res == 0 then
        end
end

main_menu.actions.exit_button = 
{
	pressed = function(_window) 
		if dialog_do_modal("quit_dialog", _window) == 1 then
			s11.g_Achievements.Instance().SaveProfilesAchievements()
			s11.g_ProfileManager.Instance().Save()
			sf.core.g_Application.Shutdown()
		end
	end
}

main_menu.actions.change_player_button = 
{
	pressed = function(_window) 
        user_profiles.run_profiles_dialog(_window)
	end
}

-- проверка на анличия текущего профайла и попытка его создания если это необходимо
function main_menu._GetOrCreateProfile()
	local num_profiles = s11.g_ProfileManager.Instance().EnumProfiles()

	if num_profiles == 0 then
			main_menu.create_profile(main_menu._self)
			num_profiles = s11.g_ProfileManager.Instance().EnumProfiles()
	end
	if num_profiles ~= 0 then
		local current_profile = s11.g_ProfileManager.Instance().GetCurrentProfile()
		if not current_profile then
			__message("Current profile not found")
			return nil
		end
		return current_profile
	end
end

-- запуск endless режима
main_menu.actions.endless_play = 
{
	pressed = function(_window) 
		
		local current_profile = main_menu._GetOrCreateProfile()
		if not current_profile then
			return
		end
		local allow_endless = current_profile.GetGameModeFlags().ReadFlag(s11.CProfile.GameModeFlagEndless)
		if not allow_endless and sf.core.g_Application.GetDebugLevel() == 0 then
			-- сообщение о том что пока бесконечный режим недоступен
			dialog_do_modal("mainmenu_endless_disable_dialog", _window)
		else
			local endless_data = current_profile.GetEndlessData()
			if endless_data.HasSavedLevelInfo() then
				local modal_res = dialog_do_modal("endless_continue_dialog", _window)
				if modal_res == 1 then
					local level_index = endless_data.GetSavedLevelIndex()
					local dif_level_index = endless_data.GetSavedLevelDifficulty()
					endless_window.Show(dif_level_index, level_index, true, nil, nil, true)
					return
				elseif modal_res == 2 then
					return
				end
			end
			endless_data.DropPlayerData()
			endless_window.Show(0, 0, nil, nil, nil, true)
		end
	end
}

-- запуск puzzle режим
main_menu.actions.puzzle_play = 
{
	pressed = function(_window) 
		local current_profile = main_menu._GetOrCreateProfile()
		if not current_profile then
			return
		end
		local allow_puzzle = current_profile.GetGameModeFlags().ReadFlag(s11.CProfile.GameModeFlagPuzzle)
		if not allow_puzzle and sf.core.g_Application.GetDebugLevel() == 0 then
			-- выводим сообщение о том что режим головоломок пока не досутпен
			dialog_do_modal("mainmenu_puzzle_disable_dialog", _window)
		else
			map_window.ShowPuzzleMap(true, true)
		end
	end
}

-- событие на кнопку Play
main_menu.actions.play_button = 
{
	pressed = function(_window) 
		local current_profile = main_menu._GetOrCreateProfile()
		if not current_profile then
			return
		end
		local classic_data = current_profile.GetClassicData()
		if not classic_data.GetLevelProgress(0, 0).IsFinished() and not classic_data.HasSavedLevelInfo() then
			-- если нет прохождения первого уровня и нет сохранения
			-- то запускаем сходу первый уровень
			game_window.Show(0, 0, nil, nil, true)
		else
			-- запуск окна карты с диалогом предлагающим продолжить игру
			map_window.Show(true, true)
		end
	end
}

-- вызов окна с ачивментами
main_menu.actions.achievements_button = 
{
	pressed = function(_window)
		local current_profile = main_menu._GetOrCreateProfile()
		if not current_profile then
			return
		end
		achievements.statistics_window.Show(_window, true)	
	end
}

-- вызов окна настроек
main_menu.actions.options_button = 
{
	pressed = function(_window) 
		local current_profile = main_menu._GetOrCreateProfile()
		if not current_profile then
			return
		end
		options_window_dialog.Show(_window)
	end
}

main_menu.actions.help_button = 
{
	pressed = function(_window) 
        help_window.Show(_window)
	end
}

main_menu.actions.scores_button = 
{
	pressed = function(_window) 
        records_window.Show(_window)
	end
}

--- виджет для ловли кликов по залоченым кнопками
up_catch_widget = {}

function up_catch_widget.__CreateInstance()
    return "up_catch_widget"
end

__inherite(up_catch_widget, null_lua_widget_handler())

function up_catch_widget.OnMouseUp(_this, _pos, _button, _state, _broadcast)
	if _broadcast == false then
		for _,disabled_obj in ipairs(main_menu._disabled_buttons) do
			if __IsPointInRect( _pos, disabled_obj.offset, disabled_obj.size) == true then
				disabled_obj.func()
				return true
			end
		end
	end

	return false
end

