using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace DummyTMPlugin
{
    /// <summary>
    /// This class represents the options form of the dummy TM plugin.
    /// </summary>
    public partial class DummyTMOptionsForm : Form
    {
        private delegate void LoginDelegate(string userName, string password);

        private class LoginResult
        {
            public string UserName;
            public string Password;
            public bool LoginSuccessful;
            public List<string> SupportedLanguages;
            public Exception Exception;
        }

        private IAsyncResult asyncResult;

        public DummyTMOptionsForm()
        {
            InitializeComponent();

            // localization
            localizeContent();

            if (DummyTMSettings.PluginIsConfigured)
            {
                // the plugin is already configured
                tbUserName.Text = DummyTMSettings.Instance.UserName;
                tbPassword.Text = DummyTMSettings.Instance.DecryptedPassword;
                foreach (string lang in DummyTMSettings.Instance.SupportedLanguages)
                {
                    lbLanguages.Items.Add(lang);
                }

                btnOK.Enabled = true;
            }
            else
            {
                // the plugin is not configured yet
                lnkRetrieveLangs.Enabled = btnOK.Enabled = false;
            }
        }

        private void localizeContent()
        {
            this.Text = LocalizationHelper.Instance.GetResourceString("OptionsFormCaption");
            this.lblUserName.Text = LocalizationHelper.Instance.GetResourceString("UserNameLabelText");
            this.lblPassword.Text = LocalizationHelper.Instance.GetResourceString("PasswordLabelText");
            this.lnkRetrieveLangs.Text = LocalizationHelper.Instance.GetResourceString("RetrieveLanguagesLinkText");
            this.lblSupportedLanguages.Text = LocalizationHelper.Instance.GetResourceString("SupportedLanguagesLabelText");
            this.btnOK.Text = LocalizationHelper.Instance.GetResourceString("OkButtonText");
            this.btnCancel.Text = LocalizationHelper.Instance.GetResourceString("CancelButtonText");
        }

        private void tbUserNamePassword_TextChanged(object sender, EventArgs e)
        {
            lnkRetrieveLangs.Enabled = !string.IsNullOrEmpty(tbUserName.Text) && !string.IsNullOrEmpty(tbPassword.Text);
            btnOK.Enabled = false;
        }

        private void lnkRetrieveLangs_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            setControlsEnabledState(false);
            btnOK.Enabled = false;
            lbLanguages.Items.Clear();

            // do the update in the background
            asyncResult = new LoginDelegate(loginCore).BeginInvoke(
                tbUserName.Text, tbPassword.Text, new AsyncCallback(handleLoginFinished),
                new LoginResult() { UserName = tbUserName.Text, Password = tbPassword.Text });
        }

        private void loginCore(string userName, string password)
        {
            try
            {
                // try to login
                string tokenCode = DummyTMServiceHelper.Login(userName, password);

                if (string.IsNullOrEmpty(tokenCode))
                {
                    // invalid user name or password
                    (asyncResult.AsyncState as LoginResult).LoginSuccessful = false;
                }
                else
                {
                    // successful login
                    (asyncResult.AsyncState as LoginResult).LoginSuccessful = true;
                    // try to get the list of the supported languages
                    (asyncResult.AsyncState as LoginResult).SupportedLanguages = DummyTMServiceHelper.ListSupportedLanguages(tokenCode);
                }
            }
            catch (Exception ex)
            {
                (asyncResult.AsyncState as LoginResult).Exception = ex;
            }
        }

        private void handleLoginFinished(IAsyncResult result)
        {
            // it is possible that the form has disposed during the background operation (e.g. the user clicked on the cancel button)
            if (!IsDisposed)
            {
                Invoke(new MethodInvoker(delegate()
                {
                    LoginResult loginResult = asyncResult.AsyncState as LoginResult;

                    if (loginResult.Exception != null)
                    {
                        // there was an error, display for the user
                        string caption = LocalizationHelper.Instance.GetResourceString("CommunicationErrorCaption");
                        string text = LocalizationHelper.Instance.GetResourceString("CommunicationErrorText");
                        MessageBox.Show(this, string.Format(text, loginResult.Exception.Message), caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else if (!loginResult.LoginSuccessful)
                    {
                        // the user name of the password is invalid, display for the user
                        string caption = LocalizationHelper.Instance.GetResourceString("InvalidUserNameCaption");
                        string text = LocalizationHelper.Instance.GetResourceString("InvalidUserNameText");
                        MessageBox.Show(this, text, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        // we have managed to get the supported languages, display them in the listbox
                        lbLanguages.Items.Clear();
                        foreach (string lang in loginResult.SupportedLanguages)
                        {
                            lbLanguages.Items.Add(lang);
                        }

                        btnOK.Enabled = loginResult.SupportedLanguages.Count > 0;
                    }

                    setControlsEnabledState(true);
                }));
            }
        }

        private void setControlsEnabledState(bool enabled)
        {
            tbUserName.Enabled = enabled;
            tbPassword.Enabled = enabled;
            lnkRetrieveLangs.Enabled = enabled;
            progressBar.Visible = !enabled;
        }

        private void DummyTMOptionsForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (DialogResult == System.Windows.Forms.DialogResult.OK && asyncResult != null)
            {
                // if there was a modification, we have to save the changes

                LoginResult loginResult = asyncResult.AsyncState as LoginResult;

                DummyTMSettings.Instance.UserName = loginResult.UserName;
                DummyTMSettings.Instance.DecryptedPassword = loginResult.Password;
                DummyTMSettings.Instance.SupportedLanguages = loginResult.SupportedLanguages;

                DummyTMSettings.Instance.SaveSettings();
            }
        }
    }
}
