Spring – Rev 1

Subversion Repositories:
Rev:
using System;
using System.ComponentModel;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using Spring.Properties;
using Spring.Serialization;
using Spring.Serialization.Combos;
using Spring.Utilities;
using Spring.Utilities.Collections;
using SpringCombos;

namespace Spring.Editing
{
    public partial class EditorForm : Form
    {
#region Public Events & Delegates

        public event EventHandler<EditEventArgs> Edited;

#endregion

#region Public Enums, Properties and Fields

        public static Random Random { get; set; }

        public Configuration.Configuration Configuration { get; }

        public IndexedList<Combos> History { get; set; }

#endregion

#region Private Delegates, Events, Enums, Properties, Indexers and Fields

        private Combos Combos { get; set; }

#endregion

#region Constructors, Destructors and Finalizers

        public EditorForm()
        {
            InitializeComponent();
            Utilities.WindowState.FormTracker.Track(this);

            Random = new Random();
            History = new IndexedList<Combos>();

            Edited += EditorForm_Edited;
        }

        public EditorForm(Combos chargeCombos) : this()
        {
            if (chargeCombos == null)
            {
                Combos = new Combos();

                return;
            }

            Combos = chargeCombos;
        }

        public EditorForm(Configuration.Configuration springConfiguration, Combos chargeCombos) : this(
            chargeCombos) =>
            Configuration = springConfiguration;

        /// <summary>
        ///     Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && components != null)
            {
                // Dispose event handlers.
                Edited -= EditorForm_Edited;

                components.Dispose();
            }

            base.Dispose(disposing);
        }

#endregion

#region Event Handlers

        private async void InfinityToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Combos.ComboRepeat = 0;

            await UpdateCombos(EditType.Transform);
        }

        private async void RedoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            editorBox.TextChanged -= EditorBox_TextChanged;

            Combos = History.Forward;

            await UpdateCombos(EditType.History);

            editorBox.TextChanged += EditorBox_TextChanged;
        }

        private async void UndoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            editorBox.TextChanged -= EditorBox_TextChanged;

            Combos = History.Back;

            await UpdateCombos(EditType.History);

            editorBox.TextChanged += EditorBox_TextChanged;
        }

        private async void RepeatsToolStripTextBox_TextChanged(object sender, EventArgs e)
        {
            var toolStripTextBox = (ToolStripTextBox) sender;

            if (!int.TryParse(toolStripTextBox.Text, out var repeatCounts) ||
                repeatCounts < 0)
            {
                return;
            }

            Combos.ComboRepeat = repeatCounts;

            await UpdateCombos(EditType.Transform);
        }

        private void EditorBox_MouseUp(object sender, MouseEventArgs e)
        {
            var textBox = (TextBox) sender;

            textBox.Focus();
        }

        private void EditorBox_MouseDown(object sender, MouseEventArgs e)
        {
            var textBox = (TextBox) sender;

            textBox.Focus();
        }

        private async void EditorBox_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode != Keys.Back)
            {
                return;
            }

            var textBox = (TextBox) sender;

            if (string.IsNullOrEmpty(textBox.SelectedText))
            {
                return;
            }

            textBox.SelectedText = string.Empty;

            await UpdateCombos(EditType.Edited);
        }

        private async void FuzzToolStripMenuItem_TextChanged(object sender, EventArgs e)
        {
            var fuzzAdjustToolStripTextBox = (ToolStripTextBox) sender;

            if (!int.TryParse(fuzzAdjustToolStripTextBox.Text, out var adjustFuzz) ||
                adjustFuzz < 0)
            {
                return;
            }

            foreach (var combo in Combos.Combo)
            {
                switch (combo)
                {
                    case PauseCombo pauseCombo:
                        pauseCombo.Fuzz = Random.Next(0, adjustFuzz);

                        break;
                }
            }

            await UpdateCombos(EditType.Transform);
        }

        private async void MouseRemoveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RemoveCombo<MouseCombo>(sender, e);
            await UpdateCombos(EditType.Transform);
        }

        private void RemoveCombo<T>(object sender, EventArgs e)
        {
            var localSpringCombos = new Combo[Combos.Combo.Count];

            Combos.Combo.CopyTo(localSpringCombos);

            foreach (var combo in localSpringCombos)
            {
                switch (combo)
                {
                    case T _:
                        Combos.Combo.Remove(combo);

                        break;
                }
            }
        }

        private async void KeyRemoveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RemoveCombo<KeyboardCombo>(sender, e);
            await UpdateCombos(EditType.Transform);
        }

        private async void PauseRemoveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RemoveCombo<PauseCombo>(sender, e);
            await UpdateCombos(EditType.Transform);
        }

        private async void EquateToolStripTextBox_TextChanged(object sender, EventArgs e)
        {
            if (!int.TryParse(equateToolStripTextBox.Text, out var pauseValue))
            {
                return;
            }

            foreach (var combo in Combos.Combo)
            {
                switch (combo)
                {
                    case PauseCombo pauseCombo:
                        pauseCombo.TimeSpan = TimeSpan.FromMilliseconds(pauseValue);

                        break;
                }
            }

            await UpdateCombos(EditType.Transform);
        }

        private async void ReverseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Combos.Combo.Reverse();

            await UpdateCombos(EditType.Transform);
        }

        private void EditorForm_Edited(object sender, EditEventArgs e)
        {
            switch (e)
            {
                case EditSuccessEventArgs editSuccessEventArgs:

                    // Do not update the text box, instead just update the object or print out any errors.
                    this.InvokeIfRequired(form => { form.editorBox.Text = editSuccessEventArgs.Text; });
                    Combos = editSuccessEventArgs.Combos;

                    switch (editSuccessEventArgs.Type)
                    {
                        case EditType.History:
                        case EditType.Load:
                        case EditType.Save:
                            break;

                        case EditType.Edited:
                        case EditType.Transform:
                            History.Add(Combos);

                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                    }

                    $"History Count: {History.Count}".ToDebugConsole();

                    break;

                case EditFailureEventArgs editFailureEventArgs:
                    break;
            }
        }

        private async void SaveFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            switch (await Combos.Serialize(saveFileDialog1.FileName))
            {
                case SerializationSuccess<Combos> serializationSuccess:
                    toolStripStatusLabel1.Text = $"{Strings.Combos_wrote_successfully}";

                    Edited?.Invoke(this,
                        new EditSuccessEventArgs(EditType.Save, saveFileDialog1.FileName, serializationSuccess));

                    break;

                case SerializationFailure serializationFailed:
                    toolStripStatusLabel1.Text =
                        $"{Strings.Failed_to_write_combos}: {serializationFailed.Exception.Message}";

                    Edited?.Invoke(this, new EditFailureEventArgs(serializationFailed));
                    ;

                    break;
            }
        }

        private async void OpenFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            var file = new FileInfo(openFileDialog1.FileName);

            switch (await ComboSerialization.Deserialize(file, 0))
            {
                case SerializationSuccess<Combos> serializationSuccess:
                    toolStripStatusLabel1.Text = $"{Strings.Combos_read_successfully}";

                    Edited?.Invoke(this,
                        new EditSuccessEventArgs(EditType.Load, openFileDialog1.FileName, serializationSuccess));

                    break;

                case SerializationFailure deserializationFailure:
                    toolStripStatusLabel1.Text =
                        $"{Strings.Failed_to_read_combos}: {deserializationFailure.Exception.Message}";

                    Edited?.Invoke(this, new EditFailureEventArgs(deserializationFailure));

                    break;
            }
        }

        private void ImportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
        }

        private void ExportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.ShowDialog();
        }

        private async void EditorBox_TextChanged(object sender, EventArgs e)
        {
            var textBox = (TextBox) sender;

            switch (await ComboSerialization.Deserialize(textBox.Text))
            {
                case SerializationSuccess<Combos> serializationSuccess:
                    toolStripStatusLabel1.Text = $"{Strings.Combos_wrote_successfully}";

                    Edited?.Invoke(this, new EditSuccessEventArgs(EditType.Edited, serializationSuccess));
                    Combos = serializationSuccess.Result;

                    break;

                case SerializationFailure deserializationFailure:
                    toolStripStatusLabel1.Text =
                        $"{Strings.Failed_to_write_combos}: {deserializationFailure.Exception.Message}";

                    Edited?.Invoke(this, new EditFailureEventArgs(deserializationFailure));

                    break;
            }
        }

        private async void EditorForm_Shown(object sender, EventArgs e)
        {
            switch (await Combos.Serialize())
            {
                case SerializationSuccess<Combos> serializationSuccess:
                    // Set editor text.
                    this.InvokeIfRequired(form =>
                        {
                            form.editorBox.Text = serializationSuccess.Text;

                            form.repeatsToolStripTextBox.Text = $"{serializationSuccess.Result.ComboRepeat}";

                            form.fuzzToolStripTextBox.Text = $"{Configuration.Spring.Fuzz}";

                            form.toolStripStatusLabel1.Text = $"{Strings.Combos_read_successfully}";
                        });

                    break;

                case SerializationFailure serializationFailed:
                    this.InvokeIfRequired(form =>
                        {
                            form.toolStripStatusLabel1.Text =
                                $"{Strings.Failed_to_read_combos}: {serializationFailed.Exception.Message}";
                        });

                    break;
            }

            this.InvokeIfRequired(form =>
                {
                    form.fuzzToolStripTextBox.TextChanged += FuzzToolStripMenuItem_TextChanged;
                    form.repeatsToolStripTextBox.TextChanged += RepeatsToolStripTextBox_TextChanged;
                });
        }

        private void EditorForm_Closing(object sender, FormClosingEventArgs e)
        {
            fuzzToolStripTextBox.TextChanged -= FuzzToolStripMenuItem_TextChanged;
            repeatsToolStripTextBox.TextChanged -= RepeatsToolStripTextBox_TextChanged;
        }

#endregion

#region Private Methods

        private async Task UpdateCombos(EditType editType)
        {
            switch (await Combos.Serialize())
            {
                case SerializationSuccess<Combos> serializationSuccess:
                    editorBox.Text = serializationSuccess.Text;
                    Edited?.Invoke(this, new EditSuccessEventArgs(editType, serializationSuccess));
                    Combos = serializationSuccess.Result;

                    break;

                case SerializationFailure serializationFailure:
                    toolStripStatusLabel1.Text = $"{Strings.Could_not_modify_combos}";

                    break;
            }
        }

#endregion
    }
}