corrade-vassal – Rev 4

Subversion Repositories:
Rev:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using OpenMetaverse;

namespace Vassal
{
    public partial class SettingsForm : Form
    {
        private static SettingsForm mainForm;
        
        ///////////////////////////////////////////////////////////////////////////
        //    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    //
        ///////////////////////////////////////////////////////////////////////////
        /// <summary>
        ///     Get enumeration value from its description.
        /// </summary>
        /// <typeparam name="T">the enumeration type</typeparam>
        /// <param name="description">the description of a member</param>
        /// <returns>the value or the default of T if case no description found</returns>
        private static T wasGetEnumValueFromDescription<T>(string description)
        {
            var field = typeof(T).GetFields()
                .AsParallel().SelectMany(f => f.GetCustomAttributes(
                    typeof(DescriptionAttribute), false), (
                       f, a) => new { Field = f, Att = a }).SingleOrDefault(a => ((DescriptionAttribute)a.Att)
                             .Description.Equals(description));
            return field != null ? (T)field.Field.GetRawConstantValue() : default(T);
        }

        ///////////////////////////////////////////////////////////////////////////
        //    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    //
        ///////////////////////////////////////////////////////////////////////////
        /// <summary>
        ///     Get the description from an enumeration value.
        /// </summary>
        /// <param name="value">an enumeration value</param>
        /// <returns>the description or the empty string</returns>
        private static string wasGetDescriptionFromEnumValue(Enum value)
        {
            DescriptionAttribute attribute = value.GetType()
                .GetField(value.ToString())
                .GetCustomAttributes(typeof(DescriptionAttribute), false)
                .SingleOrDefault() as DescriptionAttribute;
            return attribute != null ? attribute.Description : string.Empty;
        }

        private readonly Action SetUserConfiguration = () =>
        {
            // general
            Vassal.vassalConfiguration.HTTPServerURL = mainForm.HTTPServerURL.Text;
            Vassal.vassalConfiguration.Group = mainForm.Group.Text;
            Vassal.vassalConfiguration.Password = mainForm.Password.Text;
            uint outUint;
            if (uint.TryParse(mainForm.TeleportTimeout.Text, out outUint))
            {
                Vassal.vassalConfiguration.TeleportTimeout = outUint;
            }
            if (uint.TryParse(mainForm.DataTimeout.Text, out outUint))
            {
                Vassal.vassalConfiguration.DataTimeout = outUint;
            }

            // filters
            Vassal.vassalConfiguration.InputFilters =
                mainForm.ActiveInputFilters.Items.Cast<ListViewItem>().Select(o => (Filter)o.Tag).ToList();
            Vassal.vassalConfiguration.OutputFilters =
                mainForm.ActiveOutputFilters.Items.Cast<ListViewItem>().Select(o => (Filter)o.Tag).ToList();

            // cryptography
            Vassal.vassalConfiguration.ENIGMA = new ENIGMA
            {
                rotors = mainForm.ENIGMARotorSequence.Items.Cast<ListViewItem>().Select(o => (char)o.Tag).ToArray(),
                plugs = mainForm.ENIGMAPlugSequence.Items.Cast<ListViewItem>().Select(o => (char)o.Tag).ToArray(),
                reflector = mainForm.ENIGMAReflector.Text[0]
            };

            Vassal.vassalConfiguration.VIGENERESecret = mainForm.VIGENERESecret.Text;

        };

        private readonly Action GetUserConfiguration = () =>
        {
            // general
            mainForm.HTTPServerURL.Text = Vassal.vassalConfiguration.HTTPServerURL;
            mainForm.Group.Text = Vassal.vassalConfiguration.Group;
            mainForm.Password.Text = Vassal.vassalConfiguration.Password;
            mainForm.TeleportTimeout.Text = Vassal.vassalConfiguration.TeleportTimeout.ToString(Utils.EnUsCulture);
            mainForm.DataTimeout.Text = Vassal.vassalConfiguration.DataTimeout.ToString(Utils.EnUsCulture);

            // filters
            mainForm.ActiveInputFilters.Items.Clear();
            foreach (Filter filter in Vassal.vassalConfiguration.InputFilters)
            {
                mainForm.ActiveInputFilters.Items.Add(new ListViewItem
                {
                    Text = wasGetDescriptionFromEnumValue(filter),
                    Tag = filter
                });
            }
            mainForm.ActiveOutputFilters.Items.Clear();
            mainForm.ActiveInputFilters.DisplayMember = "Text";
            foreach (Filter filter in Vassal.vassalConfiguration.OutputFilters)
            {
                mainForm.ActiveOutputFilters.Items.Add(new ListViewItem
                {
                    Text = wasGetDescriptionFromEnumValue(filter),
                    Tag = filter
                });
            }
            mainForm.ActiveOutputFilters.DisplayMember = "Text";

            // cryptography
            mainForm.ENIGMARotorSequence.Items.Clear();
            foreach (char rotor in Vassal.vassalConfiguration.ENIGMA.rotors)
            {
                mainForm.ENIGMARotorSequence.Items.Add(new ListViewItem
                {
                    Text = rotor.ToString(),
                    Tag = rotor
                });
            }
            mainForm.ENIGMARotorSequence.DisplayMember = "Text";
            mainForm.ENIGMAPlugSequence.Items.Clear();
            foreach (char plug in Vassal.vassalConfiguration.ENIGMA.plugs)
            {
                mainForm.ENIGMAPlugSequence.Items.Add(new ListViewItem
                {
                    Text = plug.ToString(),
                    Tag = plug
                });
            }
            mainForm.ENIGMAPlugSequence.DisplayMember = "Text";
            mainForm.ENIGMAReflector.Text = Vassal.vassalConfiguration.ENIGMA.reflector.ToString();
            mainForm.VIGENERESecret.Text = Vassal.vassalConfiguration.VIGENERESecret;
        };

        public SettingsForm()
        {
            InitializeComponent();
            mainForm = this;
        }

        private void LoadSettingsRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                switch (mainForm.LoadSettingsDialog.ShowDialog())
                {
                    case DialogResult.OK:
                        string file = mainForm.LoadSettingsDialog.FileName;
                        new Thread(() =>
                        {
                            mainForm.BeginInvoke((MethodInvoker)(() =>
                            {
                                try
                                {
                                    mainForm.StatusText.Text = @"loading settings...";
                                    mainForm.StatusProgress.Value = 0;

                                    // load settings
                                    VassalConfiguration.Load(file, ref Vassal.vassalConfiguration);
                                    mainForm.StatusProgress.Value = 50;
                                    GetUserConfiguration.Invoke();

                                    mainForm.StatusText.Text = @"settings loaded";
                                    mainForm.StatusProgress.Value = 100;
                                }
                                catch (Exception ex)
                                {
                                    mainForm.StatusText.Text = ex.Message;
                                }
                            }));
                        })
                        { IsBackground = true, Priority = ThreadPriority.Normal }.Start();
                        break;
                }
            }));
        }

        private void SaveSettingsRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                switch (mainForm.SaveSettingsDialog.ShowDialog())
                {
                    case DialogResult.OK:
                        string file = mainForm.SaveSettingsDialog.FileName;
                        new Thread(() =>
                        {
                            mainForm.BeginInvoke((MethodInvoker)(() =>
                            {
                                try
                                {
                                    mainForm.StatusText.Text = @"saving settings...";
                                    mainForm.StatusProgress.Value = 0;

                                    // apply configuration
                                    SetUserConfiguration.Invoke();
                                    mainForm.StatusProgress.Value = 50;

                                    // save settings
                                    VassalConfiguration.Save(file, ref Vassal.vassalConfiguration);

                                    mainForm.StatusText.Text = @"settings saved";
                                    mainForm.StatusProgress.Value = 100;
                                }
                                catch (Exception ex)
                                {
                                    mainForm.StatusText.Text = ex.Message;
                                }
                            }));
                        })
                        { IsBackground = true, Priority = ThreadPriority.Normal }.Start();
                        break;
                }
            }));
        }

        private void AddInputDecoderRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                if (string.IsNullOrEmpty(InputDecode.Text))
                {
                    InputDecode.BackColor = Color.MistyRose;
                    return;
                }
                InputDecode.BackColor = Color.Empty;
                ActiveInputFilters.Items.Add(new ListViewItem
                {
                    Text = InputDecode.Text,
                    Tag = wasGetEnumValueFromDescription<Filter>(InputDecode.Text)
                });
            }));
        }

        private void AddInputDecryptionRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                if (string.IsNullOrEmpty(InputDecryption.Text))
                {
                    InputDecryption.BackColor = Color.MistyRose;
                    return;
                }
                InputDecryption.BackColor = Color.Empty;
                ActiveInputFilters.Items.Add(new ListViewItem
                {
                    Text = InputDecryption.Text,
                    Tag = wasGetEnumValueFromDescription<Filter>(InputDecryption.Text)
                });
            }));
        }

        private void AddOutputEncryptionRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                if (string.IsNullOrEmpty(OutputEncrypt.Text))
                {
                    OutputEncrypt.BackColor = Color.MistyRose;
                    return;
                }
                OutputEncrypt.BackColor = Color.Empty;
                ActiveOutputFilters.Items.Add(new ListViewItem
                {
                    Text = OutputEncrypt.Text,
                    Tag = wasGetEnumValueFromDescription<Filter>(OutputEncrypt.Text)
                });
            }));
        }

        private void AddOutputEncoderRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                if (string.IsNullOrEmpty(OutputEncode.Text))
                {
                    OutputEncode.BackColor = Color.MistyRose;
                    return;
                }
                OutputEncode.BackColor = Color.Empty;
                ActiveOutputFilters.Items.Add(new ListViewItem
                {
                    Text = OutputEncode.Text,
                    Tag = wasGetEnumValueFromDescription<Filter>(OutputEncode.Text)
                });
            }));
        }

        private void DeleteSelectedOutputFilterRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                ListViewItem listViewItem = ActiveOutputFilters.SelectedItem as ListViewItem;
                if (listViewItem == null)
                {
                    ActiveOutputFilters.BackColor = Color.MistyRose;
                    return;
                }
                ActiveOutputFilters.BackColor = Color.Empty;
                ActiveOutputFilters.Items.RemoveAt(ActiveOutputFilters.SelectedIndex);
            }));
        }

        private void DeleteSelectedInputFilterRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                ListViewItem listViewItem = ActiveInputFilters.SelectedItem as ListViewItem;
                if (listViewItem == null)
                {
                    ActiveInputFilters.BackColor = Color.MistyRose;
                    return;
                }
                ActiveInputFilters.BackColor = Color.Empty;
                ActiveInputFilters.Items.RemoveAt(ActiveInputFilters.SelectedIndex);
            }));
        }

        private void AddENIGMARotorRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                if (string.IsNullOrEmpty(ENIGMARotor.Text))
                {
                    ENIGMARotor.BackColor = Color.MistyRose;
                    return;
                }
                ENIGMARotor.BackColor = Color.Empty;
                ENIGMARotorSequence.Items.Add(new ListViewItem
                {
                    Text = ENIGMARotor.Text,
                    Tag = ENIGMARotor.Text[0]
                });
            }));
        }

        private void DeleteENIGMARotorRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                ListViewItem listViewItem = ENIGMARotorSequence.SelectedItem as ListViewItem;
                if (listViewItem == null)
                {
                    ENIGMARotorSequence.BackColor = Color.MistyRose;
                    return;
                }
                ENIGMARotorSequence.BackColor = Color.Empty;
                ENIGMARotorSequence.Items.RemoveAt(ENIGMARotorSequence.SelectedIndex);
            }));
        }

        private void AddENIGMAPlugRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                if (string.IsNullOrEmpty(ENIGMARing.Text))
                {
                    ENIGMARing.BackColor = Color.MistyRose;
                    return;
                }
                ENIGMARing.BackColor = Color.Empty;
                ENIGMAPlugSequence.Items.Add(new ListViewItem
                {
                    Text = ENIGMARing.Text,
                    Tag = ENIGMARing.Text[0]
                });
            }));
        }

        private void DeleteENIGMAPlugRequested(object sender, EventArgs e)
        {
            mainForm.BeginInvoke((MethodInvoker)(() =>
            {
                ListViewItem listViewItem = ENIGMAPlugSequence.SelectedItem as ListViewItem;
                if (listViewItem == null)
                {
                    ENIGMAPlugSequence.BackColor = Color.MistyRose;
                    return;
                }
                ENIGMAPlugSequence.BackColor = Color.Empty;
                ENIGMAPlugSequence.Items.RemoveAt(ENIGMAPlugSequence.SelectedIndex);
            }));
        }

        private void SettingsFormShown(object sender, EventArgs e)
        {
            GetUserConfiguration.Invoke();
        }
    }
}