using CefSharpWrap;
using CefSharpWrap.AceEditorWrap;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MarkdownRenderer.Test
{
    public partial class RendererTestForm : Form
    {
        private readonly MarkdownRendererForm _renderer;
        private readonly CefSharpAceEditorWrap _editor;

        public RendererTestForm()
        {
            InitializeComponent();
            Icon = MarkdownRendererResources.MainIcon;
            _renderer = new MarkdownRendererForm();
            _editor = new CefSharpAceEditorWrap();
            _editor.FillToControl(EditorPanel);
            _editor.TextChanged += Editor_TextChanged;
            _editor.ScrollPositionChanged += Editor_ScrollPositionChanged;
        }

        private void RendererTestForm_Shown(object sender, EventArgs e)
        {
            _renderer.TopLevel = false;
            _renderer.FormBorderStyle = FormBorderStyle.None;
            _renderer.Dock = DockStyle.Fill;
            MainSplitContainer.Panel1.Controls.Add(_renderer);
            _renderer.Show();

            ThemeComboBox.DataSource = Enum.GetValues(typeof(AceEditorTheme));
        }

        private void Editor_TextChanged(object sender, EventArgs e)
        {
            _renderer.PutMarkdown(_editor.Text);
        }

        private void Editor_ScrollPositionChanged(object sender, EventArgs e)
        {
            _renderer.ScrollToPercent(_editor.ScrollPosition);
            var action = new Action(() => ScrollPercentLabel.Text = _editor.ScrollPosition.ToString("N2"));
            if (InvokeRequired)
            {
                Invoke(action);
            }
            else
            {
                action();
            }
        }

        private void LoadSampleButton_Click(object sender, EventArgs e)
        {
            _editor.Text = Encoding.UTF8.GetString(Properties.Resources.Sample);
            FilePathTextBox.Text = "<unsaved>";
        }

        private void DropLoadLabel_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop)
                           ? DragDropEffects.Copy
                           : DragDropEffects.None;
        }

        private void DropLoadLabel_DragDrop(object sender, DragEventArgs e)
        {
            var files = (string[])e.Data.GetData(DataFormats.FileDrop);

            Invoke(new Action(() =>
            {
                _editor.Text = File.ReadAllText(files[0]
                    , ModifierKeys == Keys.None
                        ? Encoding.UTF8
                        : Encoding.Default
                );

                FilePathTextBox.Text = files[0];
                FileNameTextBox.Text = Path.GetFileName(files[0]);
            }));
        }

        private void RendererTestForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            _renderer.Close();
            _renderer.Dispose();
        }

        private void F12Button_Click(object sender, EventArgs e)
        {
            _editor.ShowF12();
        }

        private void FontSizeUpDown_ValueChanged(object sender, EventArgs e)
        {
            _editor.FontSize = (int)FontSizeUpDown.Value;
        }

        private void ThemeComboBox_SelectedValueChanged(object sender, EventArgs e)
        {
            _editor.Theme = ((AceEditorTheme)ThemeComboBox.SelectedValue);
        }

        private void SwapPanelCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            _renderer.Parent.Controls.Remove(_renderer);
            MainEditorRightPanel.Parent.Controls.Remove(MainEditorRightPanel);

            SplitterPanel spEdt, spRen;

            if (SwapPanelCheckBox.Checked)
            {
                spEdt = MainSplitContainer.Panel1;
                spRen = MainSplitContainer.Panel2;
            }
            else
            {
                spRen = MainSplitContainer.Panel1;
                spEdt = MainSplitContainer.Panel2;
            }

            spRen.Controls.Add(_renderer);
            spEdt.Controls.Add(MainEditorRightPanel);
        }

        private void FileNameTextBox_TextChanged(object sender, EventArgs e)
        {
            var invalidFileNameChars = Path.GetInvalidFileNameChars();

            DragOutLabel.Enabled =
                !string.IsNullOrWhiteSpace(FileNameTextBox.Text) &&
                !FileNameTextBox.Text.Any(invalidFileNameChars.Contains);
        }

        private void FilePathTextBox_TextChanged(object sender, EventArgs e)
        {
            var invalidFileNameChars = Path.GetInvalidPathChars();

            SaveButton.Enabled =
                !FilePathTextBox.Text.Any(invalidFileNameChars.Contains);
        }

        private void DragOutLabel_MouseDown(object sender, MouseEventArgs e)
        {
            var drag = new VirtualFileDataObject(null, null);

            var enc = ModifierKeys == Keys.None
                ? Encoding.UTF8
                : Encoding.Default;

            var data = enc.GetBytes(_editor.Text);

            drag.SetData(new[]
            {
                new VirtualFileDataObject.FileDescriptor
                {
                    Name =FileNameTextBox.Text,
                    Length = data.Length,
                    ChangeTimeUtc = DateTime.UtcNow,
                    StreamContents = stream =>
                    {
                        stream.Write(data, 0, data.Length);
                    }
                },
            });

            VirtualFileDataObject.DoDragDrop(drag, System.Windows.DragDropEffects.Copy);
        }

        private void SaveButton_Click(object sender, EventArgs e)
        {

        }
    }
}