using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Input;
using Robust.Shared.Maths;
using Robust.Shared.Timing;

namespace Robust.Client.UserInterface.CustomControls
{
    /// <summary>
    ///     The default debug console that drops down from the top of the screen.
    /// </summary>
    [GenerateTypedNameReferences]
    public sealed partial class DropDownDebugConsole : Control
    {
        private bool _targetVisible;
        private float _curAnchorOffset = -ScreenRatio;

        public const float ScreenRatio = 0.35f;

        public DropDownDebugConsole()
        {
            RobustXamlLoader.Load(this);

            LayoutContainer.SetAnchorPreset(MainControl, LayoutContainer.LayoutPreset.TopWide);
            LayoutContainer.SetAnchorPreset(BelowConsole, LayoutContainer.LayoutPreset.TopWide);

            MainControl.CommandBar.OnKeyBindDown += CommandBarPubOnOnKeyBindDown;
        }

        private void UpdateAnchorOffset()
        {
            LayoutContainer.SetAnchorBottom(MainControl, _curAnchorOffset+ScreenRatio);
            LayoutContainer.SetAnchorTop(MainControl, _curAnchorOffset);
            LayoutContainer.SetAnchorTop(BelowConsole, _curAnchorOffset+ScreenRatio);
        }

        private void CommandBarPubOnOnKeyBindDown(GUIBoundKeyEventArgs args)
        {
            if (args.Function == EngineKeyFunctions.ShowDebugConsole)
            {
                Toggle();
                args.Handle();
            }
            else if (args.Function == EngineKeyFunctions.TextReleaseFocus)
            {
                Toggle();
                args.Handle();
            }
        }

        protected override void FrameUpdate(FrameEventArgs args)
        {
            base.FrameUpdate(args);

            if (!MainControl.Visible)
            {
                return;
            }

            var targetOffset = _targetVisible ? 0 : -ScreenRatio;

            if (MathHelper.CloseTo(targetOffset, _curAnchorOffset))
            {
                if (!_targetVisible)
                {
                    MainControl.Visible = false;
                }

                _curAnchorOffset = targetOffset;
            }
            else
            {
                _curAnchorOffset = MathHelper.Lerp(_curAnchorOffset, targetOffset, args.DeltaSeconds * 20);
            }

            UpdateAnchorOffset();
        }

        public void Toggle()
        {
            var bar = MainControl.CommandBar;
            _targetVisible = !_targetVisible;
            if (_targetVisible)
            {
                MainControl.Visible = true;
                bar.IgnoreNext = true;
                bar.GrabKeyboardFocus();
            }
            else
            {
                bar.ReleaseKeyboardFocus();
            }
        }
    }
}
