using System;
using System.Collections.Generic;
using DanroJump.Settings;
using DanroJump.UI.Modals;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UIElements;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace DanroJump.UI.MainMenu
{
///
/// Модальное окно сервисных настроек главного меню.
/// Строит список полей динамически по базе .
///
public sealed class SettingsModalWindow : ModalWindowBase, IDisposable
{
private const string GroupHeaderTemplateAssetPath = "Assets/UI/MainMenu/Templates/SettingsGroupHeader.uxml";
private const string BoolControlTemplateAssetPath = "Assets/UI/MainMenu/Templates/SettingsBoolControl.uxml";
private const string StepperControlTemplateAssetPath = "Assets/UI/MainMenu/Templates/SettingsStepperControl.uxml";
private const string TextControlTemplateAssetPath = "Assets/UI/MainMenu/Templates/SettingsTextControl.uxml";
private const string ButtonControlTemplateAssetPath = "Assets/UI/MainMenu/Templates/SettingsButtonControl.uxml";
private const string GroupHeaderRootName = "SettingsGroupHeaderRoot";
private const string GroupHeaderTitleName = "SettingsGroupTitle";
private const string GroupHeaderDisclosureName = "SettingsGroupDisclosure";
private const string BoolControlRootName = "SettingsBoolControlRoot";
private const string StepperControlRootName = "SettingsStepperControlRoot";
private const string StepperPreviousButtonName = "SettingsStepperPreviousButton";
private const string StepperValueLabelName = "SettingsStepperValueLabel";
private const string StepperNextButtonName = "SettingsStepperNextButton";
private const string TextControlRootName = "SettingsTextControlRoot";
private const string TextFieldName = "SettingsTextField";
private const string ButtonControlRootName = "SettingsButtonControlRoot";
private const string ActionButtonName = "SettingsActionButton";
private const string ControlTitleName = "SettingsControlTitle";
private const string BoolIndicatorName = "SettingsBoolIndicator";
private const float FocusPointerGap = 18f;
private const float FocusPointerMinLeft = 12f;
private const float FocusPointerWidth = 46f;
private const float FocusPointerHeight = 64f;
private const float FocusPointerAnimationDuration = 0.12f;
private const int FocusPointerAnimationFrameMs = 16;
private const float ScrollVisibilityPadding = 18f;
private const float ScrollOffsetEpsilon = 0.5f;
private const float VerticalNavigationCooldown = 0.18f;
private const float DuplicateNavigationSourceWindow = 0.3f;
private const float RelativeSpacingFallbackWidth = 620f;
private const float GroupHeaderTopSpacingRatio = 0.035f;
private const float GroupHeaderBottomSpacingRatio = 0.019f;
private const float SettingControlVerticalSpacingRatio = 0.01f;
private const float ActionButtonVerticalSpacingRatio = 0.019f;
private const float GroupHeaderTopSpacingMin = 16f;
private const float GroupHeaderTopSpacingMax = 34f;
private const float GroupHeaderBottomSpacingMin = 8f;
private const float GroupHeaderBottomSpacingMax = 20f;
private const float SettingControlVerticalSpacingMin = 4f;
private const float SettingControlVerticalSpacingMax = 10f;
private const float ActionButtonVerticalSpacingMin = 8f;
private const float ActionButtonVerticalSpacingMax = 20f;
private static VisualTreeAsset groupHeaderTemplate;
private static VisualTreeAsset boolControlTemplate;
private static VisualTreeAsset stepperControlTemplate;
private static VisualTreeAsset textControlTemplate;
private static VisualTreeAsset buttonControlTemplate;
private static AsyncOperationHandle? groupHeaderTemplateHandle;
private static AsyncOperationHandle? boolControlTemplateHandle;
private static AsyncOperationHandle? stepperControlTemplateHandle;
private static AsyncOperationHandle? textControlTemplateHandle;
private static AsyncOperationHandle? buttonControlTemplateHandle;
private readonly ScrollView settingsList;
private readonly Label statusLabel;
private readonly Label currentGroupTitleLabel;
private readonly Button saveButton;
private readonly Button resetButton;
private readonly Button reloadButton;
private readonly Button closeButton;
private readonly Dictionary groupHeaders = new(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary> groupRows = new(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary groupDisclosureLabels = new(StringComparer.OrdinalIgnoreCase);
private readonly HashSet collapsedGroups = new(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary settingAdjustments = new();
private readonly Dictionary settingActivations = new();
private readonly List settingsNavigationTargets = new();
private readonly List settingControls = new();
private readonly Label focusPointer;
private VisualElement firstFocusableControl;
private VisualElement currentFocusPointerTarget;
private IVisualElementScheduledItem focusPointerAnimation;
private Vector2 focusPointerPosition;
private bool hasFocusPointerPosition;
private int lastNavigationFrame = -1;
private SettingsNavigationCommand lastNavigationCommand;
private SettingsNavigationSource lastNavigationSource;
private float lastNavigationCommandTime = -DuplicateNavigationSourceWindow;
private float lastVerticalNavigationTime = -VerticalNavigationCooldown;
private IServiceSettingsService settingsService;
public event Action ServiceActionActivated;
///
/// Контейнер реального содержимого ScrollView.
/// Нужен, чтобы не очищать внутреннюю служебную структуру UI Toolkit.
///
private VisualElement SettingsContainer => settingsList?.contentContainer ?? settingsList;
///
/// Создает окно настроек и привязывает кнопки управления к сервису настроек.
///
/// Корневой VisualElement окна в UXML.
/// Сервис чтения, применения и сохранения настроек.
public SettingsModalWindow(VisualElement root, IServiceSettingsService settingsService)
: base(root)
{
if (root == null)
{
return;
}
settingsList = root.Q("SettingsList");
statusLabel = root.Q