using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;

namespace NotepadEnhanced.GUI.Controls
{
    class CustomTabControl : TabControl
    {
        private bool _trackCaret;
        private const int _TRACKER_THICKNESS = 10;
        private LinearGradientBrush _upperLgb, _leftLgb;

        public CustomTabControl()
        {
            // For tracker painting
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetupGradients();
        }

        private void SetupGradients()
        {
            _upperLgb = new LinearGradientBrush(Point.Empty, new Point(0, _TRACKER_THICKNESS / 2),
                Color.White, Color.YellowGreen);

            _leftLgb = new LinearGradientBrush(Point.Empty, new Point(_TRACKER_THICKNESS / 2, 0),
                Color.White, Color.YellowGreen);

            _leftLgb.WrapMode = _upperLgb.WrapMode = WrapMode.TileFlipX;
        }

        protected override void OnControlAdded(ControlEventArgs e)
        {
            base.OnControlAdded(e);
            e.Control.BackColor = Color.White;
            e.Control.Paint += TabPage_Paint;

            if (_trackCaret)
            {
                e.Control.Padding = new Padding(_TRACKER_THICKNESS, _TRACKER_THICKNESS, 0, 0);
            }
        }

        private void TabPage_Paint(object sender, PaintEventArgs e)
        {
            if (_trackCaret)
            { 
                PlainTextBox plainTextBox = (PlainTextBox)this.SelectedTab.Controls[0];
                e.Graphics.Clear(this.SelectedTab.BackColor);

                // Track on left side
                float yPos = plainTextBox.GetPositionFromCharIndex(plainTextBox.SelectionStart).Y + _TRACKER_THICKNESS;
                e.Graphics.FillRectangle(_leftLgb, 0, yPos, _TRACKER_THICKNESS, plainTextBox.SelectionHeight);

                // Track on top side
                int width = plainTextBox.SelectionWidth;

                // Track topside even when no text is selected
                if (width < _TRACKER_THICKNESS)
                    width = _TRACKER_THICKNESS;

                int xPos = plainTextBox.GetPositionFromCharIndex(plainTextBox.SelectionStart).X;
                xPos += plainTextBox.Location.X + 2; // Add 2 to compensate for the form border
                e.Graphics.FillRectangle(_upperLgb, xPos, 0, width, _TRACKER_THICKNESS);
            }
        }

        /// <summary>
        /// Allow the user to navigate through the tabs with ctrl + number
        /// </summary>
        protected override void OnKeyDown(KeyEventArgs ke)
        {
            base.OnKeyDown(ke);

            bool isNum1To9 = (ke.KeyValue >= (int)Keys.D1 && ke.KeyValue <= (int)Keys.D9);

            if (ke.Control && isNum1To9)
            {
                int tabIndex = ke.KeyValue - ((int)Keys.D1);

                if (tabIndex < this.TabCount)
                    this.SelectedIndex = tabIndex;
            }
        }

        public void UpdateCaretTraker()
        {
            // Invalidate selected tabpage
            this.SelectedTab.Invalidate(false);
        }

        private void SetTrackerPadding()
        {
            for (int i = 0; i < this.TabPages.Count; i++)
            {
                if (_trackCaret)
                {
                    this.TabPages[i].Padding = new Padding(_TRACKER_THICKNESS, _TRACKER_THICKNESS, 0, 0);
                }
                else
                {
                    this.TabPages[i].Padding = new Padding(0);
                }
            }
        }

        [DefaultValue(false)]
        public bool TrackCaret
        {
            get { return _trackCaret; }
            set 
            { 
                _trackCaret = value;
                SetTrackerPadding();
            }
        }
    }
}
