using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using DevComponents.DotNetBar.SuperGrid.Style;
namespace DevComponents.DotNetBar.SuperGrid
{
    ///
    /// GridButtonXEditControl
    ///
    [ToolboxItem(false)]
    public class GridButtonXEditControl : ButtonX, IGridCellEditControl
    {
        #region Private variables
        private GridCell _Cell;
        private EditorPanel _EditorPanel;
        private Bitmap _EditorCellBitmap;
        private bool _ValueChanged;
        private bool _SuspendUpdate;
        private bool _UseCellValueAsButtonText = true;
        private StretchBehavior _StretchBehavior = StretchBehavior.Both;
        #endregion
        ///
        /// GridButtXEditControl
        ///
        public GridButtonXEditControl()
        {
            AutoCheckOnClick = false;
            AutoExpandOnClick = false;
            AutoSizeMode = AutoSizeMode.GrowAndShrink;
            ColorTable = eButtonColor.OrangeWithBackground;
            Style = eDotNetBarStyle.StyleManagerControlled;
            Click += ButtonXClick;
            ButtonItem.ExpandChange += ButtonXExpandChanged;
        }
        #region Hidden properties
        ///
        /// AutoCheckOnClick
        ///
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new bool AutoCheckOnClick
        {
            get { return (base.AutoCheckOnClick); }
            set { base.AutoCheckOnClick = value; }
        }
        #endregion
        #region Public properties
        #region FocusCuesEnabled
        /// 
        /// FocusCuesEnabled
        /// 
        public override bool FocusCuesEnabled
        {
            get { return (false); }
            set { base.FocusCuesEnabled = value; }
        }
        #endregion
        #region UseCellValueAsButtonText
        ///
        /// UseCellValueAsButtonText
        ///
        public bool UseCellValueAsButtonText
        {
            get { return (_UseCellValueAsButtonText); }
            set { _UseCellValueAsButtonText = value; }
        }
        #endregion
        #endregion
        #region ButtonXExpandChanged
        private void ButtonXExpandChanged(object sender, EventArgs e)
        {
            if (Expanded == false)
            {
                _Cell.SuperGrid.PostInternalMouseMove();
                _Cell.SuperGrid.Focus();
            }
        }
        #endregion
        #region ButtonXClick
        private void ButtonXClick(object sender, EventArgs e)
        {
            EditorValueChanged = true;
        }
        #endregion
        #region OnInvalidated
        /// 
        /// OnInvalidated
        /// 
        /// 
        protected override void OnInvalidated(InvalidateEventArgs e)
        {
            base.OnInvalidated(e);
            if (_Cell != null && _SuspendUpdate == false)
                _Cell.InvalidateRender();
        }
        #endregion
        #region GetValue
        ///
        /// GetValue
        ///
        ///
        ///
        public virtual string GetValue(object value)
        {
            if (_UseCellValueAsButtonText == false)
                return (Text);
            GridPanel panel = _Cell.GridPanel;
            if (value == null ||
                (panel.NullValue == NullValue.DBNull && value == DBNull.Value))
            {
                return (_Cell.NullString);
            }
            if (_Cell.IsValueExpression == true)
                value = _Cell.GetExpValue((string)value);
            return (value.ToString());
        }
        #endregion
        #region IGridCellEditControl Members
        #region Public properties
        #region CanInterrupt
        /// 
        /// CanInterrupt
        /// 
        public bool CanInterrupt
        {
            get { return (Expanded == false && IsMouseDown == false); }
        }
        #endregion
        #region CellEditMode
        /// 
        /// CellEditMode
        /// 
        public CellEditMode CellEditMode
        {
            get { return (CellEditMode.NonModal); }
        }
        #endregion
        #region EditorCell
        /// 
        /// EditorCell
        /// 
        public GridCell EditorCell
        {
            get { return (_Cell); }
            set { _Cell = value; }
        }
        #endregion
        #region EditorCellBitmap
        ///
        /// EditorCellBitmap
        ///
        public Bitmap EditorCellBitmap
        {
            get { return (_EditorCellBitmap); }
            set
            {
                if (_EditorCellBitmap != null)
                    _EditorCellBitmap.Dispose();
                _EditorCellBitmap = value;
            }
        }
        #endregion
        #region EditorFormattedValue
        ///
        /// EditorFormattedValue
        ///
        public virtual string EditorFormattedValue
        {
            get { return (Text); }
        }
        #endregion
        #region EditorPanel
        /// 
        /// EditorPanel
        /// 
        public EditorPanel EditorPanel
        {
            get { return (_EditorPanel); }
            set { _EditorPanel = value; }
        }
        #endregion
        #region EditorValue
        /// 
        /// EditorValue
        /// 
        public virtual object EditorValue
        {
            get { return (Text); }
            set { Text = GetValue(value); }
        }
        #endregion
        #region EditorValueChanged
        /// 
        /// EditorValueChanged
        /// 
        public virtual bool EditorValueChanged
        {
            get { return (_ValueChanged); }
            set
            {
                if (_ValueChanged != value)
                {
                    _ValueChanged = value;
                    if (value == true)
                        _Cell.SetEditorDirty(this);
                }
            }
        }
        #endregion
        #region EditorValueType
        ///
        /// EditorValueType
        ///
        public virtual Type EditorValueType
        {
            get { return (typeof(string)); }
        }
        #endregion
        #region StretchBehavior
        /// 
        /// StretchBehavior
        /// 
        public virtual StretchBehavior StretchBehavior
        {
            get { return (_StretchBehavior); }
            set { _StretchBehavior = value; }
        }
        #endregion
        #region SuspendUpdate
        /// 
        /// SuspendUpdate
        /// 
        public virtual bool SuspendUpdate
        {
            get { return (_SuspendUpdate); }
            set { _SuspendUpdate = value; }
        }
        #endregion
        #region ValueChangeBehavior
        /// 
        /// ValueChangeBehavior
        /// 
        public virtual ValueChangeBehavior ValueChangeBehavior
        {
            get { return (ValueChangeBehavior.InvalidateRender); }
        }
        #endregion
        #endregion
        #region InitializeContext
        ///
        /// InitializeContext
        ///
        ///
        ///
        public virtual void InitializeContext(GridCell cell, CellVisualStyle style)
        {
            _Cell = cell;
            if (style != null)
            {
                Enabled = (_Cell.IsReadOnly == false);
                Font = style.Font;
                ForeColor = style.TextColor;
            }
            Text = GetValue(_Cell.Value);
            _ValueChanged = false;
        }
        #endregion
        #region GetProposedSize
        ///
        /// GetProposedSize
        ///
        ///
        ///
        ///
        ///
        ///
        public virtual Size GetProposedSize(Graphics g,
            GridCell cell, CellVisualStyle style, Size constraintSize)
        {
            // Perform a little kludge work here, since getting the base.PreferredSize
            // on a button with empty text seems to add height to the size of the 
            // button each time it is called.
            string oldText = Text;
            if (string.IsNullOrEmpty(Text))
                Text = " ";
            Size size = GetPreferredSize(constraintSize);
            if (constraintSize.Width > 0)
            {
                ButtonItem.RecalcSize();
                if (String.IsNullOrEmpty(ButtonItem.Text) == false)
                {
                    size = ButtonItem.TextDrawRect.Size;
                    size.Height += Dpi.Height8;
                }
            }
            else
            {
                size.Width += Dpi.Width1;
            }
            if (string.IsNullOrEmpty(oldText))
                Text = oldText;
            return (size);
        }
        #endregion
        #region Edit support
        #region BeginEdit
        /// 
        /// BeginEdit
        /// 
        /// 
        /// 
        public virtual bool BeginEdit(bool selectAll)
        {
            return (false);
        }
        #endregion
        #region EndEdit
        /// 
        /// EndEdit
        /// 
        /// 
        public virtual bool EndEdit()
        {
            Expanded = false;
            return (false);
        }
        #endregion
        #region CancelEdit
        /// 
        /// CancelEdit
        /// 
        /// 
        public virtual bool CancelEdit()
        {
            Expanded = false;
            return (false);
        }
        #endregion
        #endregion
        #region CellRender
        /// 
        /// CellRender
        /// 
        /// 
        public virtual void CellRender(Graphics g)
        {
            _Cell.CellRender(this, g);
        }
        #endregion
        #region Keyboard support
        #region CellKeyDown
        ///
        /// CellKeyDown
        ///
        public virtual void CellKeyDown(KeyEventArgs e)
        {
            OnKeyDown(e);
            OnKeyUp(e);
            Checked = false;
        }
        #endregion
        #region WantsInputKey
        /// 
        /// WantsInputKey
        /// 
        /// 
        /// 
        /// 
        public virtual bool WantsInputKey(Keys key, bool gridWantsKey)
        {
            switch (key & Keys.KeyCode)
            {
                case Keys.Space:
                    return (true);
                default:
                    return (gridWantsKey == false);
            }
        }
        #endregion
        #endregion
        #region Mouse support
        #region OnCellMouseMove
        ///
        /// OnCellMouseMove
        ///
        ///
        public virtual void OnCellMouseMove(MouseEventArgs e)
        {
            OnMouseMove(e);
        }
        #endregion
        #region OnCellMouseEnter
        ///
        /// OnCellMouseEnter
        ///
        ///
        public virtual void OnCellMouseEnter(EventArgs e)
        {
            Point pt = _Cell.SuperGrid.PointToClient(MousePosition);
            if (_Cell.Bounds.Contains(pt) == false)
                StopFade();
            OnMouseEnter(e);
        }
        #endregion
        #region OnCellMouseLeave
        ///
        /// OnCellMouseLeave
        ///
        ///
        public virtual void OnCellMouseLeave(EventArgs e)
        {
            if (_Cell != null)
            {
                Point pt = _Cell.SuperGrid.PointToClient(MousePosition);
                if (_Cell.Bounds.Contains(pt) == false)
                    StopFade();
                OnMouseLeave(e);
                _Cell.GridRow.EditorDirty = false;
                Refresh();
            }
        }
        #endregion
        #region OnCellMouseUp
        ///
        /// OnCellMouseUp
        ///
        ///
        public virtual void OnCellMouseUp(MouseEventArgs e)
        {
            OnMouseUp(e);
        }
        #endregion
        #region OnCellMouseDown
        ///
        /// OnCellMouseDown
        ///
        ///
        public virtual void OnCellMouseDown(MouseEventArgs e)
        {
            OnMouseDown(e);
        }
        #endregion
        #endregion
        #endregion  
        #region Dispose
        /// 
        /// Dispose
        /// 
        /// 
        protected override void Dispose(bool disposing)
        {
            Click -= ButtonXClick;
            ButtonItem.ExpandChange -= ButtonXExpandChanged;
            base.Dispose(disposing);
        }
        #endregion
    }
}