using System;
using System.Collections.Generic;
using DanroJump.Settings;
using DanroJump.UI.Modals;
using UnityEngine;
using UnityEngine.UIElements;
namespace DanroJump.UI.MainMenu
{
///
/// Модальное окно сервисных настроек главного меню.
/// Строит список полей динамически по базе .
///
public sealed class SettingsModalWindow : ModalWindowBase, IDisposable
{
private const string GroupHeaderTemplateResourcePath = "UI/MainMenu/Templates/SettingsGroupHeader";
private const string BoolControlTemplateResourcePath = "UI/MainMenu/Templates/SettingsBoolControl";
private const string StepperControlTemplateResourcePath = "UI/MainMenu/Templates/SettingsStepperControl";
private const string TextControlTemplateResourcePath = "UI/MainMenu/Templates/SettingsTextControl";
private const string ButtonControlTemplateResourcePath = "UI/MainMenu/Templates/SettingsButtonControl";
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 static VisualTreeAsset groupHeaderTemplate;
private static VisualTreeAsset boolControlTemplate;
private static VisualTreeAsset stepperControlTemplate;
private static VisualTreeAsset textControlTemplate;
private static VisualTreeAsset buttonControlTemplate;
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 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;
///
/// Контейнер реального содержимого 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