//  
//   Rebex Sample Code License
// 
//   Copyright 2025, REBEX CR s.r.o.
//   All rights reserved.
//   https://www.rebex.net/
// 
//   Permission to use, copy, modify, and/or distribute this software for any
//   purpose with or without fee is hereby granted.
// 
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
//   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
//   OTHER DEALINGS IN THE SOFTWARE.
// 

using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using Rebex.TerminalEmulation;

namespace Rebex.Samples
{
    /// <summary>
    /// The Options class provides user interface for setting the terminal options.
    /// </summary>
    public class Options : Form
    {
        /// <summary>
        /// Helper class for working with Encoding combo box.
        /// </summary>
        private class EncodingElement
        {
            public int CodePage
            {
                get { return _encoding.CodePage; }
            }

            public Encoding Encoding
            {
                get { return _encoding; }
            }

            private Encoding _encoding;

            public EncodingElement(string encodingName)
            {
                _encoding = EncodingTools.GetEncoding(encodingName);
            }

            public override string ToString()
            {
                return string.Format("{0} {1}", _encoding.HeaderName, _encoding.EncodingName);
            }
        }

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        private System.Windows.Forms.ComboBox cbEncoding;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Button btnOk;
        private System.Windows.Forms.TextBox txtTerminalName;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.CheckBox cbForceNonDestructiveBackspace;
        private System.Windows.Forms.CheckBox cbIgnoreSubstituteCharacter;
        private System.Windows.Forms.CheckBox cbImplicitCarriageReturnInLinefeed;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.ComboBox cbAutoWrapMode;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.ComboBox cbBackspaceWrapMode;

        /// <summary>
        /// The TerminalOptions object.
        /// </summary>
        private TerminalOptions _options;
        private System.Windows.Forms.Button btnCancel;

        /// <summary>
        /// Encoding names shown in combo box.
        /// </summary>
        string[] _encodingNames = EncodingTools.GetEncodingNames();

        /// <summary>
        /// Initializes this class.
        /// </summary>
        /// <param name="options">Terminal options to be configured.</param>
        public Options(TerminalOptions options)
        {
            _options = options;

            InitializeComponent();

            FillComboBoxes();

            SetFormValues(options);
        }

        /// <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))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.cbEncoding = new System.Windows.Forms.ComboBox();
            this.label2 = new System.Windows.Forms.Label();
            this.btnOk = new System.Windows.Forms.Button();
            this.txtTerminalName = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.cbForceNonDestructiveBackspace = new System.Windows.Forms.CheckBox();
            this.cbIgnoreSubstituteCharacter = new System.Windows.Forms.CheckBox();
            this.cbImplicitCarriageReturnInLinefeed = new System.Windows.Forms.CheckBox();
            this.label3 = new System.Windows.Forms.Label();
            this.cbAutoWrapMode = new System.Windows.Forms.ComboBox();
            this.label4 = new System.Windows.Forms.Label();
            this.cbBackspaceWrapMode = new System.Windows.Forms.ComboBox();
            this.btnCancel = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // cbEncoding
            // 
            this.cbEncoding.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cbEncoding.Location = new System.Drawing.Point(120, 32);
            this.cbEncoding.Name = "cbEncoding";
            this.cbEncoding.Size = new System.Drawing.Size(248, 21);
            this.cbEncoding.TabIndex = 1;
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(5, 35);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(55, 16);
            this.label2.TabIndex = 23;
            this.label2.Text = "Encoding:";
            // 
            // btnOk
            // 
            this.btnOk.Location = new System.Drawing.Point(232, 152);
            this.btnOk.Name = "btnOk";
            this.btnOk.Size = new System.Drawing.Size(63, 23);
            this.btnOk.TabIndex = 7;
            this.btnOk.Text = "OK";
            this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
            // 
            // txtTerminalName
            // 
            this.txtTerminalName.Location = new System.Drawing.Point(120, 6);
            this.txtTerminalName.Name = "txtTerminalName";
            this.txtTerminalName.Size = new System.Drawing.Size(248, 20);
            this.txtTerminalName.TabIndex = 0;
            this.txtTerminalName.Text = "";
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(5, 9);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(83, 16);
            this.label1.TabIndex = 26;
            this.label1.Text = "Terminal name:";
            // 
            // cbForceNonDestructiveBackspace
            // 
            this.cbForceNonDestructiveBackspace.Location = new System.Drawing.Point(10, 115);
            this.cbForceNonDestructiveBackspace.Name = "cbForceNonDestructiveBackspace";
            this.cbForceNonDestructiveBackspace.Size = new System.Drawing.Size(214, 17);
            this.cbForceNonDestructiveBackspace.TabIndex = 4;
            this.cbForceNonDestructiveBackspace.Text = "Force Non-destructive backspace";
            // 
            // cbIgnoreSubstituteCharacter
            // 
            this.cbIgnoreSubstituteCharacter.Location = new System.Drawing.Point(10, 138);
            this.cbIgnoreSubstituteCharacter.Name = "cbIgnoreSubstituteCharacter";
            this.cbIgnoreSubstituteCharacter.Size = new System.Drawing.Size(214, 17);
            this.cbIgnoreSubstituteCharacter.TabIndex = 5;
            this.cbIgnoreSubstituteCharacter.Text = "Ignore Substitute character";
            // 
            // cbImplicitCarriageReturnInLinefeed
            // 
            this.cbImplicitCarriageReturnInLinefeed.Location = new System.Drawing.Point(10, 161);
            this.cbImplicitCarriageReturnInLinefeed.Name = "cbImplicitCarriageReturnInLinefeed";
            this.cbImplicitCarriageReturnInLinefeed.Size = new System.Drawing.Size(214, 17);
            this.cbImplicitCarriageReturnInLinefeed.TabIndex = 6;
            this.cbImplicitCarriageReturnInLinefeed.Text = "Implicit Carriage return in Linefeed";
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(5, 62);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(58, 16);
            this.label3.TabIndex = 33;
            this.label3.Text = "Auto wrap:";
            // 
            // cbAutoWrapMode
            // 
            this.cbAutoWrapMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cbAutoWrapMode.Location = new System.Drawing.Point(120, 59);
            this.cbAutoWrapMode.Name = "cbAutoWrapMode";
            this.cbAutoWrapMode.Size = new System.Drawing.Size(109, 21);
            this.cbAutoWrapMode.TabIndex = 2;
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(5, 89);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(90, 16);
            this.label4.TabIndex = 35;
            this.label4.Text = "Backspace wrap:";
            // 
            // cbBackspaceWrapMode
            // 
            this.cbBackspaceWrapMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cbBackspaceWrapMode.Location = new System.Drawing.Point(120, 86);
            this.cbBackspaceWrapMode.Name = "cbBackspaceWrapMode";
            this.cbBackspaceWrapMode.Size = new System.Drawing.Size(109, 21);
            this.cbBackspaceWrapMode.TabIndex = 3;
            // 
            // btnCancel
            // 
            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.btnCancel.Location = new System.Drawing.Point(304, 152);
            this.btnCancel.Name = "btnCancel";
            this.btnCancel.Size = new System.Drawing.Size(63, 23);
            this.btnCancel.TabIndex = 36;
            this.btnCancel.Text = "Cancel";
            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
            // 
            // Options
            // 
            this.AcceptButton = this.btnOk;
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.CancelButton = this.btnCancel;
            this.ClientSize = new System.Drawing.Size(378, 187);
            this.Controls.Add(this.btnCancel);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.cbBackspaceWrapMode);
            this.Controls.Add(this.cbAutoWrapMode);
            this.Controls.Add(this.cbImplicitCarriageReturnInLinefeed);
            this.Controls.Add(this.cbIgnoreSubstituteCharacter);
            this.Controls.Add(this.cbForceNonDestructiveBackspace);
            this.Controls.Add(this.txtTerminalName);
            this.Controls.Add(this.btnOk);
            this.Controls.Add(this.cbEncoding);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MinimizeBox = false;
            this.MaximizeBox = false;
            this.ShowInTaskbar = false;
            this.KeyPreview = true;
            this.Name = "Options";
            this.Text = "Properties";
            this.ResumeLayout(false);

        }

        #endregion

        /// <summary>
        /// Fills the form's combo boxes.
        /// </summary>
        private void FillComboBoxes()
        {
            // fill the cbEncoding.Items collection
            for(int i = 0; i < _encodingNames.Length; i++)
            {
                EncodingElement encoding =new EncodingElement(_encodingNames[i]);
                cbEncoding.Items.Add(encoding);
            }

            cbAutoWrapMode.DataSource = Enum.GetValues(typeof(AutoWrapMode));
            cbBackspaceWrapMode.DataSource = Enum.GetValues(typeof(AutoWrapMode));
        }

        /// <summary>
        /// Sets the form values according to the specified terminal options.
        /// </summary>
        /// <param name="options">Terminal options.</param>
        private void SetFormValues(TerminalOptions options)
        {
            txtTerminalName.Text = options.TerminalName;
            this.Encoding = options.Encoding;
            cbAutoWrapMode.SelectedItem = options.AutoWrapMode;
            cbBackspaceWrapMode.SelectedItem = options.BackspaceWrapMode;
            cbForceNonDestructiveBackspace.Checked = options.ForceNondestructiveBackspace;
            cbIgnoreSubstituteCharacter.Checked = options.IgnoreSubstituteCharacter;
            cbImplicitCarriageReturnInLinefeed.Checked = options.ImplicitCarriageReturnInLinefeed;
        }

        /// <summary>
        /// Gets or sets the selected Encoding in the combo box.
        /// </summary>
        private Encoding Encoding
        {
            get
            {
                return ((EncodingElement)cbEncoding.SelectedItem).Encoding;
            }
            set
            {
                cbEncoding.SelectedIndex = -1;

                if (value == null)
                    return;

                foreach (EncodingElement encoding in cbEncoding.Items)
                {
                    if (encoding.CodePage == value.CodePage)
                    {
                        cbEncoding.SelectedItem = encoding;
                        return;
                    }
                }
            }
        }

        /// <summary>
        /// Handles the button 'Ok' click event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOk_Click(object sender, EventArgs e)
        {
            // set the values from form to the terminal options
            _options.TerminalName = txtTerminalName.Text;
            _options.Encoding = this.Encoding;
            _options.AutoWrapMode = (AutoWrapMode)cbAutoWrapMode.SelectedValue;
            _options.BackspaceWrapMode = (AutoWrapMode)cbBackspaceWrapMode.SelectedValue;
            _options.ForceNondestructiveBackspace = cbForceNonDestructiveBackspace.Checked;
            _options.IgnoreSubstituteCharacter = cbIgnoreSubstituteCharacter.Checked;
            _options.ImplicitCarriageReturnInLinefeed = cbImplicitCarriageReturnInLinefeed.Checked;

            Close();
        }

        private void btnCancel_Click(object sender, System.EventArgs e)
        {
            Close();
        }
    }
}