/********************************************************************************\
*  This sample is supplied as is with no implied warranty.  
*  It is designed to assist you in using the Cisco AnyConnect VPN API. 
*  It is assumed that you will build a production application and 
*  refer to this sample as a reference only.
\********************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using VpnApiLib;

namespace CSharpComSample
{
    public partial class DynamicInputDlg : Form
    {
        private int currentRow;
        private VpnApiClass vpnApi;
        private IDictionary<string, Control> inputControls;
        private IConnectPromptInfo connectPromptInfo;

        public DynamicInputDlg(VpnApiClass vpnApi)
        {
            this.vpnApi = vpnApi;
            inputControls = new Dictionary<string, Control>();

            InitializeComponent();
        }

        public void CreateDynamicInputs(IConnectPromptInfo connectPromptInfo)
        {
            try
            {
                this.connectPromptInfo = connectPromptInfo;
                clearDynamicInputs();

                promptLabel.Text = connectPromptInfo.Message;

                for (int i = 1; i <= connectPromptInfo.CountPromptEntry; i++)
                {
                    IPromptEntry promptEntry = (IPromptEntry)connectPromptInfo.PromptEntries[i];
                    Control inputControl = null;
                    switch (promptEntry.PromptType)
                    {
                        case PromptType.Prompt_Banner:
                            bannerGroupBox.Show();
                            bannerGroupBox.Text = promptEntry.PromptLabel;
                            bannerTextBox.Text = promptEntry.Value;
                            break;
                        case PromptType.Prompt_Hidden:
                            // Intentionally ignore
                            break;
                        case PromptType.Prompt_Header:
                            addPromptHeader(promptEntry);
                            break;
                        case PromptType.Prompt_CheckBox:
                            inputControl = addPromptCheckBox(promptEntry);
                            break;
                        case PromptType.Prompt_Combo:
                            inputControl = addPromptCombo(promptEntry);
                            break;
                        case PromptType.Prompt_Input:
                            inputControl = addPromptInput(promptEntry);
                            break;
                        case PromptType.Prompt_Password:
                            inputControl = addPromptPassword(promptEntry);
                            break;
                    }

                    if (inputControl != null)
                    {
                        // Store control by name for later lookup
                        inputControls[promptEntry.PromptName] = inputControl;

                        inputControl.Anchor = AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top;
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void clearDynamicInputs()
        {
            dynamicInputTableLayoutPanel.Controls.Clear();
            dynamicInputTableLayoutPanel.RowCount = 0;
            currentRow = 0;
            inputControls.Clear();

            bannerGroupBox.Hide();
        }

        private Control addPromptPassword(IPromptEntry promptEntry)
        {
            int column = 0;
            Label inputLabel = new Label();
            inputLabel.Text = promptEntry.PromptLabel;

            dynamicInputTableLayoutPanel.Controls.Add(inputLabel, column, currentRow);

            TextBox passwordTextBox = new TextBox();
            passwordTextBox.PasswordChar = '*';
            passwordTextBox.Text = promptEntry.Value;
            
            setPromptAttributes(promptEntry, inputLabel, passwordTextBox);
            dynamicInputTableLayoutPanel.Controls.Add(passwordTextBox, ++column, currentRow);

            currentRow++;

            return passwordTextBox;
        }

        private void setPromptAttributes(IPromptEntry promptEntry, Label inputLabel, Control inputControl)
        {
            bool isEnabled = promptEntry.IsEnabled;
            bool isVisible = promptEntry.IsVisible;

            if (inputLabel != null)
            {
                inputLabel.Visible = isVisible;
                inputLabel.Enabled = isEnabled;
            }
            if (inputControl != null)
            {
                inputControl.Visible = isVisible;
                inputControl.Enabled = isEnabled;
            }
        }

        private Control addPromptInput(IPromptEntry promptEntry)
        {
            int column = 0;
            Label inputLabel = new Label();
            inputLabel.Text = promptEntry.PromptLabel;

            dynamicInputTableLayoutPanel.Controls.Add(inputLabel, column, currentRow);

            TextBox inputTextBox = new TextBox();
            inputTextBox.Text = promptEntry.Value;

            setPromptAttributes(promptEntry, inputLabel, inputTextBox);
            dynamicInputTableLayoutPanel.Controls.Add(inputTextBox, ++column, currentRow);

            currentRow++;

            return inputTextBox;
        }

        private void addPromptHeader(IPromptEntry promptEntry)
        {
            int column = 0;
            Label inputLabel = new Label();
            inputLabel.Text = promptEntry.PromptLabel;

            setPromptAttributes(promptEntry, inputLabel, null);
            dynamicInputTableLayoutPanel.Controls.Add(inputLabel, column, currentRow);
            dynamicInputTableLayoutPanel.SetColumnSpan(inputLabel, 2);

            currentRow++;
        }

        private Control addPromptCheckBox(IPromptEntry promptEntry)
        {
            int column = 0;
            CheckBox inputCheckBox = new CheckBox();
            inputCheckBox.Text = promptEntry.PromptLabel;
            inputCheckBox.Checked = (promptEntry.Value.ToLower() == "true");

            setPromptAttributes(promptEntry, null, inputCheckBox);
            dynamicInputTableLayoutPanel.Controls.Add(inputCheckBox, column, currentRow);
            dynamicInputTableLayoutPanel.SetColumnSpan(inputCheckBox, 2);

            currentRow++;

            return inputCheckBox;
        }

        private Control addPromptCombo(IPromptEntry promptEntry)
        {
            int column = 0;
            Label inputLabel = new Label();
            inputLabel.Text = promptEntry.PromptLabel;

            dynamicInputTableLayoutPanel.Controls.Add(inputLabel, column, currentRow);

            string selectedValue = promptEntry.Value;
            ComboBox inputComboBox = new ComboBox();
            for (int i = 1; i <= promptEntry.ValueOptions.Count; i++)
            {
                inputComboBox.Items.Add(promptEntry.ValueOptions[i]);
            }
            if (inputComboBox.Items.Contains(selectedValue))
            {
                inputComboBox.SelectedIndex =
                    inputComboBox.Items.IndexOf(selectedValue);
            }
            else
            {
                inputComboBox.Items.Add(selectedValue);
            }

            setPromptAttributes(promptEntry, inputLabel, inputComboBox);
            dynamicInputTableLayoutPanel.Controls.Add(inputComboBox, ++column, currentRow);

            dynamicInputTableLayoutPanel.RowStyles[currentRow].SizeType = SizeType.Absolute;
            dynamicInputTableLayoutPanel.RowStyles[currentRow].Height = inputLabel.Height;

            // If this represents a group, register a special event handler to detect changes
            inputComboBox.SelectedIndexChanged += new EventHandler(inputComboBox_SelectedIndexChanged);

            currentRow++;

            return inputComboBox;
        }

        void inputComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            connectPromptInfo["group_list"].Value = ((ComboBox)sender).Text;           
            connectPromptInfo.TunnelGroup = ((ComboBox)sender).Text;
            
            CreateDynamicInputs(connectPromptInfo);
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            for (int i = 1; i <= connectPromptInfo.CountPromptEntry; i++)
            {
                IPromptEntry promptEntry = (IPromptEntry)connectPromptInfo.PromptEntries[i];
                if (inputControls.ContainsKey(promptEntry.PromptName))
                {
                    promptEntry.Value = inputControls[promptEntry.PromptName].Text;
                }
            }

            try
            {
                Close();
                //vpnApi.UserSubmit();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            clearDynamicInputs();
            Close();
        }
    }
}