using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using InABox.Core;

namespace InABox.DynamicGrid;

public class CodeEditorControl : DynamicEditorControl<string, BaseCodeEditor>
{
    
    static CodeEditorControl()
    {
        //DynamicEditorControlFactory.Register<CodeEditorControl, BaseCodeEditor, CodeEditor>();
        //DynamicEditorControlFactory.Register<CodeEditorControl, BaseCodeEditor, UniqueCodeEditor>();
    }
    
    private TextBox Editor;

    public override void Configure()
    {
    }

    protected override FrameworkElement CreateEditor()
    {
        var dock = new DockPanel
        {
            HorizontalAlignment = HorizontalAlignment.Stretch,
            VerticalAlignment = VerticalAlignment.Stretch
        };

        var buttons = CreateButtons(out var DisableEditor);
        foreach (var button in buttons)
        {
            button.SetValue(DockPanel.DockProperty, Dock.Right);
            dock.Children.Add(button);
            dock.Width += button.Width + 5;
        }

        Editor = new TextBox
        {
            CharacterCasing = CharacterCasing.Upper,
            VerticalContentAlignment = VerticalAlignment.Center
        };
        Editor.SetValue(DockPanel.DockProperty, Dock.Left);
        if (DisableEditor)
        {
            Editor.Background = new SolidColorBrush(Colors.Silver);
            Editor.IsEnabled = false;
        }

        Editor.TextChanged += (o, e) => { CheckChanged(); };

        Editor.PreviewTextInput += Editor_PreviewTextInput;
        DataObject.AddPastingHandler(Editor, Editor_TextPaste);

        dock.Children.Add(Editor);

        return dock;
    }

    private void Editor_TextPaste(object sender, DataObjectPastingEventArgs e)
    {
        if (e.DataObject.GetDataPresent(typeof(string)))
        {
            var allowable = (EditorDefinition as BaseCodeEditor)?.ValidChars;
            var text = (string)e.DataObject.GetData(typeof(string));
            if (!IsTextAllowed(text, allowable))
                e.CancelCommand();
        }
        else
        {
            e.CancelCommand();
        }
    }

    private bool IsTextAllowed(string text, string allowable)
    {
        if (string.IsNullOrWhiteSpace(allowable))
            return true;
        return Array.TrueForAll(text.ToCharArray(), delegate(char c) { return allowable.Contains(c); });
    }

    private void Editor_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        var allowable = (EditorDefinition as BaseCodeEditor)?.ValidChars;
        e.Handled = !IsTextAllowed(e.Text, allowable);
    }

    public override int DesiredHeight()
    {
        return 25;
    }

    public override int DesiredWidth()
    {
        var result = 150;
        var btnEditor = EditorDefinition as IButtonEditor;
        if (btnEditor?.Buttons != null)
            foreach (var button in ((IButtonEditor)EditorDefinition).Buttons)
                result += button.Width + 5;
        return result;
    }

    protected override string RetrieveValue()
    {
        return Editor.Text;
    }

    protected override void UpdateValue(string value)
    {
        Editor.Text = value;
    }

    public override void SetFocus()
    {
        Editor.Focus();
    }

    public override void SetColor(Color color)
    {
        Editor.Background = new SolidColorBrush(color);
    }
}