using System;
using System.ComponentModel;
using System.Drawing;
using System.Media;
using System.Windows.Forms;
using DevComponents.DotNetBar;
using System.Globalization;
namespace DevComponents.Editors
{
    /// 
    /// Standalone Calculator control.
    /// 
    [ToolboxBitmap(typeof(DotNetBarManager), "Calculator.ico"), DefaultEvent("ValueChanged"), DefaultProperty("Value"), ToolboxItem(true), Designer("DevComponents.DotNetBar.Design.CalculatorDesigner, DevComponents.DotNetBar.Design, Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf")]
    public partial class Calculator : Control
    {
        #region Events
        #region ButtonClick
        /// 
        /// Occurs when a calc button has been clicked
        /// 
        [Description("Occurs when a calc button has been clicked.")]
        public event EventHandler ButtonClick;
        #endregion
        #region ValueChanged
        /// 
        /// Occurs when the calculator value has changed
        /// 
        [Description("Occurs when the calculator value has changed.")]
        public event EventHandler ValueChanged;
        #endregion
        public event EventHandler CalculatorDisplayChanged;
        /// 
        /// Raises CalculatorDisplayChanged event.
        /// 
        /// Provides event arguments.
        protected virtual void OnCalculatorDisplayChanged(EventArgs e)
        {
            EventHandler handler = CalculatorDisplayChanged;
            if (handler != null)
                handler(this, e);
        }
        #endregion
        #region Private variables
        private string _StringValue = null;
        private double _Value;
        private double _LValue;
        private double _MemValue;
        private Operators _Operator;
        private Operators _LastOp;
        private bool _IsIntValue;
        private bool _ShowMemKeys;
        private DecimalKeyVisibility _DecimalKeyVisibility;
        private Timer _KeyTimer;
        private string _NumberDecimalSeparator;
        #endregion
        public Calculator()
        {
            InitializeComponent();
            _ShowMemKeys = true;
            _DecimalKeyVisibility = DecimalKeyVisibility.Auto;
            this.SetStyle(DisplayHelp.DoubleBufferFlag | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
            labelValue.BackColor = Color.White;
            pnlCalc.BackColor = Color.White;
            pnlPad.BackColor = Color.White;
            _NumberDecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
            BtnDecimal.Text = _NumberDecimalSeparator;
        }
        #region Public properties
        #region DisplayValue
        [Browsable(false)]
        public double DisplayValue
        {
            get
            {
                if (string.IsNullOrEmpty(_StringValue) == true)
                    return (_Value);
                return (double.Parse(_StringValue));
            }
        }
        #endregion
        #region UpdateDisplay
        private void UpdateDisplay()
        {
            labelValue.Text = DisplaySValue;
        }
        #endregion
        #region DisplaySValue
        [Browsable(false)]
        public string DisplaySValue
        {
            get
            {
                if (string.IsNullOrEmpty(_StringValue) == false)
                    return (_StringValue);
                return (_Value.ToString());
            }
        }
        #endregion
        #region IsIntValue
        /// 
        /// Indicates whether calculator displays only Integer values.
        /// 
        [DefaultValue(false), Category("Behavior"), Description("Indicates whether calculator displays only Integer values.")]
        public bool IsIntValue
        {
            get { return (_IsIntValue); }
            set
            {
                if (_IsIntValue != value)
                {
                    _IsIntValue = value;
                    UpdateLayout();
                }
            }
        }
        #endregion
        #region ShowMemKeys
        /// 
        /// Gets or sets whether memory keys are visible. Default value is true.
        /// 
        [DefaultValue(true), Category("Appearance"), Description("Indicates whether memory keys are visible.")]
        public bool ShowMemKeys
        {
            get { return (_ShowMemKeys); }
            set
            {
                if (_ShowMemKeys != value)
                {
                    _ShowMemKeys = value;
                    if (_ShowMemKeys == true)
                    {
                        pnlCalc.Height += (pnlMem.Height - 1);
                        pnlPad.Location = new Point(1, pnlMem.Bottom);
                    }
                    else
                    {
                        pnlCalc.Height -= (pnlMem.Height - 1);
                        if(_DisplayVisible)
                            pnlPad.Location = new Point(1, labelValue.Bottom);
                        else
                            pnlPad.Location = new Point(1, labelValue.Top);
                    }
                    InvalidateAutoSize();
                    //Size = pnlCalc.Size;
                }
            }
        }
        #endregion
        #region DecimalKeyVisibility
        /// 
        /// Gets or sets visibility of the decimal calculator key.
        /// 
        [DefaultValue(DecimalKeyVisibility.Auto), Category("Appearance"), Description("Indicates visibility of the decimal calculator key.")]
        public DecimalKeyVisibility DecimalKeyVisibility
        {
            get { return (_DecimalKeyVisibility); }
            set
            {
                if (_DecimalKeyVisibility != value)
                {
                    _DecimalKeyVisibility = value;
                    UpdateLayout();
                }
            }
        }
        #endregion
        #region SValue
        [DefaultValue(null), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public string StringValue
        {
            get { return (_StringValue); }
            set
            {
                _StringValue = value;
                OnValueChanged();
            }
        }
        #endregion
        #region Value
        [DefaultValue(0d), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public double Value
        {
            get { return (_Value); }
            set
            {
                _Value = value;
                OnValueChanged();
            }
        }
        #endregion
        #endregion
        #region Keyboard Support
        internal void ProcessKeyPress(KeyPressEventArgs e)
        {
            ButtonX btn = null;
            switch (e.KeyChar)
            {
                case '0': btn = OnDigitSelect(BtnDigit0); break;
                case '1': btn = OnDigitSelect(BtnDigit1); break;
                case '2': btn = OnDigitSelect(BtnDigit2); break;
                case '3': btn = OnDigitSelect(BtnDigit3); break;
                case '4': btn = OnDigitSelect(BtnDigit4); break;
                case '5': btn = OnDigitSelect(BtnDigit5); break;
                case '6': btn = OnDigitSelect(BtnDigit6); break;
                case '7': btn = OnDigitSelect(BtnDigit7); break;
                case '8': btn = OnDigitSelect(BtnDigit8); break;
                case '9': btn = OnDigitSelect(BtnDigit9); break;
                case '+': btn = OnOperatorSelect(BtnAdd, Operators.Add); break;
                case '-': btn = OnOperatorSelect(BtnSubtract, Operators.Subtract); break;
                case '*': btn = OnOperatorSelect(BtnMultiply, Operators.Multiply); break;
                case '/': btn = OnOperatorSelect(BtnDivide, Operators.Divide); break;
                case '%': btn = OnPercentSelect(); break;
                case 'r': btn = OnReciprocalSelect(); break;
                case '@': btn = OnSqrtSelect(); break;
                case 'n': btn = OnNegateSelect(); break;
                case 'c': btn = OnClearSelect(); break;
                case 'e': btn = OnClearEntrySelect(); break;
                case '=': btn = OnEqualsSelect(); break;
                case '\b': btn = OnBackSelect(); break;
                case '\r':
                    btn = ((ModifierKeys & Keys.Control) == Keys.Control)
                        ? OnMemStoreSelect() : OnEqualsSelect();
                    break;
                case (char)18: btn = OnMemRestoreSelect(); break;
                case (char)16: btn = OnMemAddSelect(); break;
                case (char)17: btn = OnMemSubtractSelect(); break;
                case (char)12: btn = OnMemClearSelect(); break;
            }
            if (btn == null && e.KeyChar.ToString() == _NumberDecimalSeparator)
                btn = OnDecimalSelect();
            if (btn != null)
            {
                FlashKey(btn);
                e.Handled = true;
            }
        }
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);
            if (e.Handled == false)
            {
                ProcessKeyPress(e);
            }
        }
        #endregion
        #region Button Support
        #region BtnDigitClick
        private void BtnDigitClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnDigitSelect((ButtonX)sender);
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnDigitSelect(ButtonX btn)
        {
            AddDigit(btn);
            OnValueChanged();
            return (btn);
        }
        #region AddDigit
        private void AddDigit(object sender)
        {
            ButtonX btn = sender as ButtonX;
            if (btn != null)
            {
                char c = btn.Name[8];
                if (_StringValue == null || _LastOp == Operators.Set)
                {
                    _StringValue = "";
                    if (_LastOp == Operators.Calc || _LastOp == Operators.Set)
                        SetOperator(Operators.None);
                }
                _StringValue += c;
                UpdateDisplay();
                OnCalculatorDisplayChanged(EventArgs.Empty);
            }
        }
        #endregion
        #endregion
        #region BtnDecimalClick
        private void BtnDecimalClick(object sender, EventArgs e)
        {
            if (OnButtonClick(BtnDecimal) == false)
                OnDecimalSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnDecimalSelect()
        {
            if (_IsIntValue == false)
            {
                if (_StringValue == null || _LastOp == Operators.Set)
                {
                    _StringValue = "0" + _NumberDecimalSeparator;
                    if (_LastOp == Operators.Calc || _LastOp == Operators.Set)
                        SetOperator(Operators.None);
                }
                else if (_StringValue.Contains(_NumberDecimalSeparator) == false)
                {
                    _StringValue += _NumberDecimalSeparator;
                }
            }
            OnValueChanged();
            return (BtnDecimal);
        }
        #endregion
        #region BtnBackClick
        private void BtnBackClick(object sender, EventArgs e)
        {
            if (OnButtonClick(BtnBack) == false)
                OnBackSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnBackSelect()
        {
            if (string.IsNullOrEmpty(_StringValue) == false)
            {
                _StringValue = _StringValue.Substring(0, _StringValue.Length - 1);
                if (_StringValue.Length == 0 ||
                    (_StringValue.Length == 1 && _StringValue[0] == '-'))
                {
                    _StringValue = "0";
                }
            }
            else
            {
                SystemSounds.Beep.Play();
            }
            OnValueChanged();
            return (BtnBack);
        }
        #endregion
        #region BtnAddClick
        private void BtnAddClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnOperatorSelect(BtnAdd, Operators.Add);
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        #endregion
        #region BtnSubtractClick
        private void BtnSubtractClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnOperatorSelect(BtnSubtract, Operators.Subtract);
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        #endregion
        #region BtnMultiplyClick
        private void BtnMultiplyClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnOperatorSelect(BtnMultiply, Operators.Multiply);
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        #endregion
        #region BtnDivideClick
        private void BtnDivideClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnOperatorSelect(BtnDivide, Operators.Divide);
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        #endregion
        #region BtnNegateClick
        private void BtnNegateClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnNegateSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnNegateSelect()
        {
            if (string.IsNullOrEmpty(_StringValue) == false)
            {
                _StringValue = '-' + _StringValue;
                _StringValue = _StringValue.Replace("--", "");
            }
            else
            {
                _Value = -_Value;
            }
            OnValueChanged();
            return (BtnNegate);
        }
        #endregion
        #region BtnSqrtClick
        private void BtnSqrtClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnSqrtSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnSqrtSelect()
        {
            if (string.IsNullOrEmpty(_StringValue) == false)
            {
                double d = double.Parse(_StringValue);
                if (d > 0)
                {
                    d = Math.Sqrt(d);
                    if (IsIntValue == true)
                        d = Math.Round(d);
                    _StringValue = d.ToString();
                }
                else
                    SystemSounds.Beep.Play();
            }
            else
            {
                if (_Value > 0)
                    _Value = Math.Sqrt(_Value);
                else
                    SystemSounds.Beep.Play();
            }
            _LastOp = Operators.Set;
            OnValueChanged();
            return (BtnSqrt);
        }
        #endregion
        #region BtnReciprocalClick
        private void BtnReciprocalClick(object sender, EventArgs e)
        {
            if (OnButtonClick(BtnReciprocal) == false)
                OnReciprocalSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnReciprocalSelect()
        {
            if (string.IsNullOrEmpty(_StringValue) == false)
            {
                double d = double.Parse(_StringValue);
                if (d != 0)
                {
                    d = 1 / d;
                    if (IsIntValue == true)
                        d = Math.Round(d);
                    _StringValue = d.ToString();
                }
                else
                {
                    SystemSounds.Beep.Play();
                }
            }
            else
            {
                if (_Value != 0)
                    _Value = 1 / _Value;
                else
                    SystemSounds.Beep.Play();
            }
            _LastOp = Operators.Set;
            OnValueChanged();
            return (BtnReciprocal);
        }
        #endregion
        #region BtnPercentClick
        private void BtnPercentClick(object sender, EventArgs e)
        {
            if (OnButtonClick(BtnPercent) == false)
                OnPercentSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnPercentSelect()
        {
            if (string.IsNullOrEmpty(_StringValue) == false)
            {
                double d = double.Parse(_StringValue);
                d = (_Value * d) / 100;
                if (IsIntValue == true)
                    d = Math.Round(d);
                _StringValue = d.ToString();
            }
            else
            {
                _Value = 0;
            }
            OnValueChanged();
            return (BtnPercent);
        }
        #endregion
        #region BtnEqualsClick
        private void BtnEqualsClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnEqualsSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnEqualsSelect()
        {
            UpdateTotal();
            _LastOp = Operators.Calc;
            lbxOperator.Text = "";
            OnValueChanged();
            return (BtnEquals);
        }
        #endregion
        #region BtnClearEntryClick
        private void BtnClearEntryClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnClearEntrySelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnClearEntrySelect()
        {
            if (string.IsNullOrEmpty(_StringValue) == false)
                _StringValue = "0";
            else
                _Value = 0;
            OnValueChanged();
            return (BtnClearEntry);
        }
        #endregion
        #region BtnClearClick
        private void BtnClearClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnClearSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnClearSelect()
        {
            _Value = 0;
            _LValue = 0;
            _StringValue = null;
            SetOperator(Operators.None);
            OnValueChanged();
            return (BtnClear);
        }
        #endregion
        #region BtnMemStoreClick
        private void BtnMemStoreClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnMemStoreSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnMemStoreSelect()
        {
            StoreToMem(DisplayValue);
            return (BtnMemStore);
        }
        #endregion
        #region BtnMemRestoreClick
        private void BtnMemRestoreClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnMemRestoreSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnMemRestoreSelect()
        {
            _StringValue = _MemValue.ToString();
            OnValueChanged();
            return (BtnMemRestore);
        }
        #endregion
        #region BtnMemClearClick
        private void BtnMemClearClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnMemClearSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnMemClearSelect()
        {
            StoreToMem(0);
            return (BtnMemClear);
        }
        #endregion
        #region BtnMemAddClick
        private void BtnMemAddClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnMemAddSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnMemAddSelect()
        {
            StoreToMem(_MemValue + DisplayValue);
            return (BtnMemAdd);
        }
        #endregion
        #region BtnMemSubtractClick
        private void BtnMemSubtractClick(object sender, EventArgs e)
        {
            if (OnButtonClick(sender) == false)
                OnMemSubtractSelect();
            if (_FocusButtonsOnMouseDown)
                Focus();
        }
        private ButtonX OnMemSubtractSelect()
        {
            StoreToMem(_MemValue - DisplayValue);
            return (BtnMemSubtract);
        }
        #endregion
        #region StoreToMem
        private void StoreToMem(double value)
        {
            _MemValue = value;
            lbxMemory.Text = (value == 0) ? "" : "M";
        }
        #endregion
        #endregion
        #region SetOperator
        private void SetOperator(Operators op)
        {
            _Operator = op;
            _LastOp = op;
            lbxOperator.Text = ((char)op).ToString();
        }
        #endregion
        #region OnOperatorSelect
        private ButtonX OnOperatorSelect(ButtonX btn, Operators op)
        {
            if (string.IsNullOrEmpty(_StringValue) == false)
                UpdateTotal();
            SetOperator(op);
            OnValueChanged();
            return (btn);
        }
        #endregion
        #region UpdateTotal
        private void UpdateTotal()
        {
            if (string.IsNullOrEmpty(_StringValue) == false)
                _LValue = double.Parse(_StringValue);
            switch (_Operator)
            {
                case Operators.None:
                    _Value = _LValue;
                    break;
                case Operators.Add:
                    _Value += _LValue;
                    break;
                case Operators.Subtract:
                    _Value -= _LValue;
                    break;
                case Operators.Multiply:
                    _Value *= _LValue;
                    break;
                case Operators.Divide:
                    if (_LValue > 0)
                        _Value /= _LValue;
                    else
                        SystemSounds.Beep.Play();
                    break;
            }
            _StringValue = null;
            OnValueChanged();
        }
        #endregion
        #region UpdateLayout
        private void UpdateLayout()
        {
            bool showDecimal;
            switch (_DecimalKeyVisibility)
            {
                case DecimalKeyVisibility.Always:
                    showDecimal = true;
                    break;
                case DecimalKeyVisibility.Auto:
                    showDecimal = (IsIntValue == false);
                    break;
                default:
                    showDecimal = false;
                    break;
            }
            if (showDecimal == true)
            {
                BtnDecimal.Visible = true;
                BtnDigit0.Width = BtnDigit2.Bounds.Right - BtnDigit0.Bounds.X;
            }
            else
            {
                BtnDecimal.Visible = false;
                BtnDigit0.Width = BtnDecimal.Bounds.Right - BtnDigit0.Bounds.X;
            }
            InvalidateAutoSize();
        }
        #endregion
        #region OnButtonClick
        private bool OnButtonClick(object button)
        {
            if (ButtonClick != null)
            {
                ButtonClickEventArgs e =
                    new ButtonClickEventArgs(button);
                ButtonClick(this, e);
                return (e.Cancel);
            }
            return (false);
        }
        #endregion
        #region OnValueChanged
        public void OnValueChanged()
        {
            if (ValueChanged != null)
            {
                ValueChanged(this,
                    new ValueChangedEventArgs(DisplaySValue, DisplayValue));
            }
            UpdateDisplay();
            OnCalculatorDisplayChanged(EventArgs.Empty);
        }
        #endregion
        #region OnVisibleChanged
        protected override void OnVisibleChanged(EventArgs e)
        {
            if (Visible == true)
            {
                _StringValue = null;
                _LValue = 0;
                StoreToMem(0);
                SetOperator(Operators.Set);
                OnValueChanged();
            }
            base.OnVisibleChanged(e);
        }
        #endregion
        #region FlashKey
        public void FlashKey(ButtonX keyButton)
        {
            if (_KeyTimer == null)
            {
                _KeyTimer = new Timer();
                _KeyTimer.Interval = 125;
                _KeyTimer.Tick += KeyTimerTick;
            }
            ButtonX btn = _KeyTimer.Tag as ButtonX;
            if (btn != null)
            {
                _KeyTimer.Stop();
                DoKeyTimerUp(btn);
            }
            DoKeyTimerDown(keyButton);
            _KeyTimer.Tag = keyButton;
            _KeyTimer.Start();
        }
        #region DoKeyTimerDown
        private void DoKeyTimerDown(ButtonX btn)
        {
            MouseEventArgs args = new MouseEventArgs(
                MouseButtons.Left, 1, btn.Location.X, btn.Location.Y, 0);
            btn.InternalItem.InternalMouseDown(args);
        }
        #endregion
        #region DoKeyTimerUp
        private void DoKeyTimerUp(ButtonX btn)
        {
            MouseEventArgs args = new MouseEventArgs(
                MouseButtons.Left, 1, btn.Location.X, btn.Location.Y, 0);
            btn.InternalItem.InternalMouseUp(args);
        }
        #endregion
        #region KeyTimerTick
        void KeyTimerTick(object sender, EventArgs e)
        {
            ButtonX btn = _KeyTimer.Tag as ButtonX;
            if (btn != null)
                DoKeyTimerUp(btn);
            _KeyTimer.Stop();
        }
        #endregion
        #endregion
        #region Auto-Sizing
        protected override void OnPaint(PaintEventArgs e)
        {
            using(SolidBrush brush=new SolidBrush(this.BackColor))
                e.Graphics.FillRectangle(brush, this.ClientRectangle);
            base.OnPaint(e);
        }
        private Size _PreferredSize = Size.Empty;
        /// 
        /// Invalidates control auto-size and resizes the control if AutoSize is set to true.
        /// 
        public void InvalidateAutoSize()
        {
            _PreferredSize = Size.Empty;
            AdjustSize();
        }
        /// 
        /// Gets or sets a value indicating whether the control is automatically resized to display its entire contents. You can set MaximumSize.Width property to set the maximum width used by the control.
        /// 
        [Browsable(true), DefaultValue(false), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public override bool AutoSize
        {
            get
            {
                return base.AutoSize;
            }
            set
            {
                if (this.AutoSize != value)
                {
                    base.AutoSize = value;
                    AdjustSize();
                }
            }
        }
        private void AdjustSize()
        {
            if (this.AutoSize)
            {
                this.Size = base.PreferredSize;
            }
        }
        private bool _FocusButtonsOnMouseDown = true;
        internal bool FocusButtonsOnMouseDown
        {
            get { return _FocusButtonsOnMouseDown; }
            set
            {
                if (value != _FocusButtonsOnMouseDown)
                {
                    bool oldValue = _FocusButtonsOnMouseDown;
                    _FocusButtonsOnMouseDown = value;
                    OnFocusButtonsOnMouseDownChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when FocusButtonsOnMouseDown property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnFocusButtonsOnMouseDownChanged(bool oldValue, bool newValue)
        {
            this.BtnBack.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDigit8.FocusOnLeftMouseButtonDown = newValue;
            this.BtnReciprocal.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDigit5.FocusOnLeftMouseButtonDown = newValue;
            this.BtnSqrt.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDivide.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDigit9.FocusOnLeftMouseButtonDown = newValue;
            this.BtnClearEntry.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDecimal.FocusOnLeftMouseButtonDown = newValue;
            this.BtnAdd.FocusOnLeftMouseButtonDown = newValue;
            this.BtnEquals.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDigit4.FocusOnLeftMouseButtonDown = newValue;
            this.BtnSubtract.FocusOnLeftMouseButtonDown = newValue;
            this.BtnMultiply.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDigit6.FocusOnLeftMouseButtonDown = newValue;
            this.BtnClear.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDigit1.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDigit2.FocusOnLeftMouseButtonDown = newValue;
            this.BtnNegate.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDigit0.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDigit3.FocusOnLeftMouseButtonDown = newValue;
            this.BtnPercent.FocusOnLeftMouseButtonDown = newValue;
            this.BtnDigit7.FocusOnLeftMouseButtonDown = newValue;
            this.BtnMemStore.FocusOnLeftMouseButtonDown = newValue;
            this.BtnMemRestore.FocusOnLeftMouseButtonDown = newValue;
            this.BtnMemAdd.FocusOnLeftMouseButtonDown = newValue;
            this.BtnMemClear.FocusOnLeftMouseButtonDown = newValue;
            this.BtnMemSubtract.FocusOnLeftMouseButtonDown = newValue;
        }
        protected override void OnFontChanged(EventArgs e)
        {
            InvalidateAutoSize();
            BtnMemAdd.Font = new Font(this.Font.FontFamily, BtnMemAdd.Font.SizeInPoints);
            BtnMemClear.Font = new Font(this.Font.FontFamily, BtnMemClear.Font.SizeInPoints);
            BtnMemRestore.Font = new Font(this.Font.FontFamily, BtnMemRestore.Font.SizeInPoints);
            BtnMemStore.Font = new Font(this.Font.FontFamily, BtnMemStore.Font.SizeInPoints);
            BtnMemSubtract.Font = new Font(this.Font.FontFamily, BtnMemSubtract.Font.SizeInPoints);
            BtnDigit0.Font = new Font(this.Font.FontFamily, BtnDigit0.Font.SizeInPoints);
            BtnDigit1.Font = new Font(this.Font.FontFamily, BtnDigit1.Font.SizeInPoints);
            BtnDigit2.Font = new Font(this.Font.FontFamily, BtnDigit2.Font.SizeInPoints);
            BtnDigit3.Font = new Font(this.Font.FontFamily, BtnDigit3.Font.SizeInPoints);
            BtnDigit4.Font = new Font(this.Font.FontFamily, BtnDigit4.Font.SizeInPoints);
            BtnDigit5.Font = new Font(this.Font.FontFamily, BtnDigit5.Font.SizeInPoints);
            BtnDigit6.Font = new Font(this.Font.FontFamily, BtnDigit6.Font.SizeInPoints);
            BtnDigit7.Font = new Font(this.Font.FontFamily, BtnDigit7.Font.SizeInPoints);
            BtnDigit8.Font = new Font(this.Font.FontFamily, BtnDigit8.Font.SizeInPoints);
            BtnDigit9.Font = new Font(this.Font.FontFamily, BtnDigit9.Font.SizeInPoints);
            labelValue.Font = new Font(this.Font.FontFamily, labelValue.Font.SizeInPoints);
            base.OnFontChanged(e);
        }
        public override Size GetPreferredSize(Size proposedSize)
        {
            if (!_PreferredSize.IsEmpty) return _PreferredSize;
            if (!BarFunctions.IsHandleValid(this))
                return base.GetPreferredSize(proposedSize);
            _PreferredSize = pnlCalc.Size;
            return _PreferredSize;
        }
        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
        {
            if (this.AutoSize)
            {
                Size preferredSize = base.PreferredSize;
                width = preferredSize.Width;
                height = preferredSize.Height;
            }
            base.SetBoundsCore(x, y, width, height, specified);
        }
        protected override void OnHandleCreated(EventArgs e)
        {
            if (this.AutoSize)
                this.AdjustSize();
            base.OnHandleCreated(e);
        }
        #endregion
        #region DisplayVisible
        private bool _DisplayVisible = true;
        /// 
        /// Gets or sets whether calculator display is visible. Default value is true.
        /// 
        [DefaultValue(true), Category("Appearance"), Description("Indicates whether calculator display is visible.")]
        public bool DisplayVisible
        {
            get { return _DisplayVisible; }
            set
            {
                if (value != _DisplayVisible)
                {
                    bool oldValue = _DisplayVisible;
                    _DisplayVisible = value;
                    OnDisplayVisibleChanged(oldValue, value);
                }
            }
        }
        /// 
        /// Called when DisplayVisible property has changed.
        /// 
        /// Old property value
        /// New property value
        protected virtual void OnDisplayVisibleChanged(bool oldValue, bool newValue)
        {
            labelValue.Visible = newValue;
            if (newValue)
            {
                pnlPad.Top += labelValue.Height;
                pnlMem.Top += labelValue.Height;
                pnlCalc.Height += labelValue.Height;
            }
            else
            {
                pnlPad.Top -= labelValue.Height;
                pnlMem.Top -= labelValue.Height;
                pnlCalc.Height -= labelValue.Height;
            }
            _PreferredSize = Size.Empty;
            AdjustSize();
        }        
        #endregion
    }
    #region Enums
    public enum Operators
    {
        None = ' ',
        Calc = '=',
        Set = '\t',
        Add = '+',
        Subtract = '-',
        Multiply = '*',
        Divide = '/',
    }
    public enum DecimalKeyVisibility
    {
        Auto,
        Always,
        Never
    }
    #endregion
    #region ButtonClickEventArgs
    /// 
    /// ButtonClickEventArgs
    /// 
    public class ButtonClickEventArgs : CancelEventArgs
    {
        #region Private variables
        private object _Button;
        #endregion
        ///
        /// ButtonClickEventArgs
        ///
        public ButtonClickEventArgs(object button)
        {
            _Button = button;
        }
        #region Public properties
        /// 
        /// Gets the calc button that was clicked
        /// 
        public object Button
        {
            get { return (_Button); }
        }
        #endregion
    }
    #endregion
    #region ValueChangedEventArgs
    /// 
    /// ValueChangedEventArgs
    /// 
    public class ValueChangedEventArgs : EventArgs
    {
        #region Private variables
        private double _Value;
        private string _SValue;
        #endregion
        ///
        /// ValueChangedEventArgs
        ///
        ///
        ///
        public ValueChangedEventArgs(string svalue, double value)
        {
            _Value = value;
            _SValue = svalue;
        }
        #region Public properties
        /// 
        /// Gets the input string value
        /// 
        public string SValue
        {
            get { return (_SValue); }
        }
        /// 
        /// Gets or sets calculator value
        /// 
        public double Value
        {
            get { return (_Value); }
            set { _Value = value; }
        }
        #endregion
    }
    #endregion
}