using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace MyScreenCap.Ctrl {
    /// <summary>
    /// 数値のみ入力可能なテキストボックス
    /// </summary>
    class NumberTextBox : TextBox {
        private uint _MaxValue = 100;
        private uint _MinValue = 0;

        /// <summary>
        /// 最大値
        /// </summary>
        [DefaultValue((uint)100)]
        public uint MaxValue {
            get {
                return _MaxValue;
            }
            set {
                _MaxValue = value;
                if (MinValue > value) {
                    MinValue = value;
                }
                MaxLength = value.ToString().Length;
            }
        }

        /// <summary>
        /// 最小値
        /// </summary>
        [DefaultValue((uint)0)]
        public uint MinValue {
            get {
                return _MinValue;
            }
            set {
                _MinValue = value;
                if (MaxValue < value) {
                    MaxValue = value;
                }
                this.Text = value.ToString();
            }
        }

        [DefaultValue((uint)0)]
        public uint Value {
            get {
                return uint.Parse(this.Text);
            }
            set {
                this.Text = value.ToString();
                CheckValue();
            }
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public NumberTextBox() {
            MaxValue = MaxValue;
            this.Text = MaxValue.ToString();
            this.TextAlign = HorizontalAlignment.Right;
            this.Leave += new EventHandler(NumberTextBox_Leave);

            // 右クリックメニュー表示不可
            this.ContextMenu = new ContextMenu();
        }

        /// <summary>
        /// NumberTextBox Leave
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NumberTextBox_Leave(object sender, EventArgs e) {
            CheckValue();
        }

        /// <summary>
        /// キー入力制御
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
            // 数値と矢印以外はキャンセル
            if ((keyData >= Keys.D0 && keyData <= Keys.D9)
                || (keyData >= Keys.NumPad0 && keyData <= Keys.NumPad9)
                || keyData == Keys.Left
                || keyData == Keys.Right
                || keyData == Keys.Up
                || keyData == Keys.Down
                || keyData == Keys.Delete
                || keyData == Keys.Back) {
                return base.ProcessCmdKey(ref msg, keyData);
            } else {
                return true;
            }
        }

        /// <summary>
        /// 数値のチェック
        /// </summary>
        private void CheckValue() {
            uint val;
            if (uint.TryParse(this.Text, out val)) {
                // 最大値・最小値チェック
                if (val > MaxValue) {
                    val = MaxValue;
                } else if (val < MinValue) {
                    val = MinValue;
                }

                this.Text = val.ToString();
            } else {
                this.Text = MinValue.ToString();
            }
        }
    }
}
