using System;
using System.Windows.Forms;
using System.Drawing;
using FastReport.Utils;
using System.ComponentModel;
using FastReport.Data;

namespace FastReport.Controls
{
    /// <summary>
    /// Represents the combobox used to select a data column.
    /// </summary>
    [ToolboxItem(false)]
    public class DataColumnComboBox : UserControl
    {
        private TextBox textBox;
        private Button button;
        private Button comboButton;
        private Report report;
        private DataColumnDropDown dropDown;
        private Timer timer;
        private int closedTicks;
        private int dpi;

        /// <summary>
        /// Occurs when the text portion of the combobox is changed.
        /// </summary>
        public new event EventHandler TextChanged;

        /// <inheritdoc/>
        public override string Text
        {
            get { return textBox.Text; }
            set { textBox.Text = value; }
        }

        /// <summary>
        /// Gets or sets the data source.
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public DataSourceBase DataSource
        {
            get { return dropDown.DataSource; }
            set
            {
                // to recreate datasource list
                Report = Report;
                dropDown.DataSource = value;
            }
        }

        /// <summary>
        /// Gets or sets the Report.
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Report Report
        {
            get { return report; }
            set
            {
                report = value;
                dropDown.CreateNodes(value);
            }
        }

        private void FTextBox_TextChanged(object sender, EventArgs e)
        {
            if (TextChanged != null)
                TextChanged(this, EventArgs.Empty);
        }

        private void FDropDown_ColumnSelected(object sender, EventArgs e)
        {
            Text = String.IsNullOrEmpty(dropDown.Column) ? "" : "[" + dropDown.Column + "]";
            timer.Start();
        }

        private void FDropDown_Closed(object sender, ToolStripDropDownClosedEventArgs e)
        {
            closedTicks = Environment.TickCount;
        }

        private void FComboButton_Click(object sender, EventArgs e)
        {
            if (Math.Abs(Environment.TickCount - closedTicks) < 100)
                return;

            string column = Text.Replace("[", "");
            column = column.Replace("]", "");
            dropDown.Column = column;
            dropDown.SetSize(Width, 250);
            dropDown.RightToLeft = RightToLeft;
            dropDown.Owner = this;
            dropDown.Show(this, new Point(RightToLeft == RightToLeft.Yes ? Width : 0, Height));
        }

        private void FButton_Click(object sender, EventArgs e)
        {
            Text = Editors.EditExpression(Report, Text);
            timer.Start();
        }

        private void FTimer_Tick(object sender, EventArgs e)
        {
            FindForm().BringToFront();
            textBox.Focus();
            textBox.Select(Text.Length, 0);
            timer.Stop();
        }

        private void LayoutControls()
        {
            int btnWidth = Height - 2;
            if (button != null)
                button.SetBounds(RightToLeft == RightToLeft.Yes ? 1 : Width - btnWidth - 1, 1, btnWidth, btnWidth);
            if (comboButton != null)
                comboButton.SetBounds(RightToLeft == RightToLeft.Yes ? btnWidth + 1 : Width - btnWidth * 2 - 1, 1, btnWidth, btnWidth);
            if (textBox != null)
                textBox.SetBounds(RightToLeft == RightToLeft.Yes ? btnWidth * 2 + 1 : 3, (Height - textBox.PreferredHeight) / 2 - 1, Width - btnWidth * 2 - 3, textBox.PreferredHeight);
        }

        private void UpdateImages()
        {
            button.Image = this.GetImage(52);
            comboButton.Image = this.GetImage(182);
        }

        /// <inheritdoc/>
        protected override void OnPaint(PaintEventArgs e)
        {
            if (dpi != this.Dpi())
            {
                UpdateImages();
                dpi = this.Dpi();
            }

            Graphics g = e.Graphics;
            g.FillRectangle(Enabled ? SystemBrushes.Window : SystemBrushes.Control, DisplayRectangle);
            if (Enabled)
                ControlPaint.DrawVisualStyleBorder(g, new Rectangle(0, 0, Width - 1, Height - 1));
            else
                g.DrawRectangle(SystemPens.InactiveBorder, new Rectangle(0, 0, Width - 1, Height - 1));
        }

        /// <inheritdoc/>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (timer != null)
                    timer.Dispose();
                timer = null;
            }
            base.Dispose(disposing);
        }

        /// <inheritdoc/>
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            LayoutControls();
        }

        /// <inheritdoc/>
        protected override void OnLayout(LayoutEventArgs e)
        {
            base.OnLayout(e);
            LayoutControls();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DataColumnComboBox"/> class.
        /// </summary>
        public DataColumnComboBox()
        {
            button = new Button();
            button.FlatStyle = FlatStyle.Flat;
            button.FlatAppearance.BorderSize = 0;
            button.Click += new EventHandler(FButton_Click);
            Controls.Add(button);

            comboButton = new Button();
            comboButton.FlatStyle = FlatStyle.Flat;
            comboButton.FlatAppearance.BorderSize = 0;
            comboButton.Click += new EventHandler(FComboButton_Click);
            Controls.Add(comboButton);

            textBox = new TextBox();
            textBox.BorderStyle = BorderStyle.None;
            textBox.TextChanged += new EventHandler(FTextBox_TextChanged);
            Controls.Add(textBox);

            dropDown = new DataColumnDropDown();
            dropDown.ColumnSelected += new EventHandler(FDropDown_ColumnSelected);
            dropDown.Closed += new ToolStripDropDownClosedEventHandler(FDropDown_Closed);

            timer = new Timer();
            timer.Interval = 50;
            timer.Tick += new EventHandler(FTimer_Tick);

            // prevent autoscale of child controls
            AutoScaleMode = AutoScaleMode.None;
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
        }
    }
}
