using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using C1.Chart.Finance;
using C1.Chart;

namespace StockChart
{

    public partial class ucToolbar : UserControl
    {
        public EventHandler<StringEventArgs> OnComparisonChanged;
        public EventHandler<IntgerEventArgs> OnSelectedIndexChanged;
        public EventHandler<BooleanEventArgs> OnShowVolumeChanged;
        public EventHandler<ChartTypeChangedEventArgs> OnChartTypeChanged;
        public EventHandler OnReseted;
        public EventHandler<StringEventArgs> OnSaveImage;
        public EventHandler<BooleanEventArgs> OnMovingAverageVisibilityChanged;
        public EventHandler<MovingAverageTypeChangedEventArgs> OnMovingAverageTypeChanged;
        public EventHandler<IntgerEventArgs> OnMovingAveragePeriodChanged;
        public EventHandler<BooleanEventArgs> OnLineMarkerVisibilityChanged;
        public EventHandler<BooleanEventArgs> OnNewsVisibilityChanged;

        public ucToolbar()
        {
            InitializeComponent();
            if (!this.DesignMode)
            {
                InitializeControls();
            }

            this.Load += (o, e) =>
            {
                this.chkMovingAverage.Checked = false;
                this.chkLineMarker.Checked = false;
            };
        }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public string RangeText
        {
            get { return this.lblDateRange.Text; }
            set { this.BeginInvoke(new Action(()=>
            {
                this.lblDateRange.Text = value;
            })); }
        }


        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int RangeSelectedIndex
        {
            get { return this.ucButtonGroup.SelectedIndex; }
            set
            {
                this.BeginInvoke(new Action(() =>
                {
                    this.ucButtonGroup.SelectedIndex = value;
                }));
            }
        }

        private bool _showChartType = false;

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool ShowChartType
        {
            get { return this._showChartType; }
            set
            {
                _showChartType = value;

                this.BeginInvoke(new Action(() =>
                {
                    cbChartType.SelectedIndex = 0;
                    cbChartType.Visible = panel10.Visible = _showChartType;
                }));
            }
        }
        private bool _enableReset = false;
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool EnableReset
        {
            get { return this._enableReset; }
            set
            {
                _enableReset = value;

                this.BeginInvoke(new Action(() =>
                {
                    btnReset.Enabled = _enableReset;
                }));
            }
        }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public IEnumerable<QuoteInfo> QuotesInfo
        {
            get { return this.txtInfo.QuotesInfo; }
            set
            {
                this.txtInfo.QuotesInfo = value;
            }
        }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public DisplayMode QuotesInfoDisplayMode
        {
            get { return this.txtInfo.DisplayMode; }
            set
            {
                this.txtInfo.DisplayMode = value;
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsShowMovingAverage
        {
            get { return this.chkMovingAverage.Checked; }
        }

        private bool _isShowNews = false;
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsShowNews
        {
            get { return _isShowNews; }
            set
            {
                _isShowNews = value;
                this.BeginInvoke(new Action(() =>
                {
                    this.chkNews.Visible = _isShowNews;
                }));
            }
        }
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsLineMarkerChecked
        {
            get { return this.chkLineMarker.Checked; }
        }
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsNewsChecked
        {
            get { return _isShowNews && this.chkNews.Checked; }
        }

        internal string GetFirstSeriesCOntroller()
        {
            return this.pnlChecks.Controls.Count > 0 ? this.pnlChecks.Controls[0].Text : null;
        }

        internal void AddSeriesController(Symbol s, Action checkedChangedCallback)
        {
            this.BeginInvoke(new Action(() =>
            {
                C1.Win.C1Input.C1CheckBox cb = new C1.Win.C1Input.C1CheckBox();


                cb.BackColor = System.Drawing.Color.Transparent;
                cb.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(71)))), ((int)(((byte)(71)))), ((int)(((byte)(71)))));
                cb.BorderStyle = System.Windows.Forms.BorderStyle.None;
                cb.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
                cb.CheckState = System.Windows.Forms.CheckState.Checked;
                cb.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
                 cb.TabIndex = 0;
                this.c1ThemeController1.SetTheme(cb, "ExpressionDark");
                cb.UseVisualStyleBackColor = true;

                cb.AutoSize = true;
                cb.Font = new System.Drawing.Font("Segoe UI", 10F, FontStyle.Bold);
                cb.Dock = DockStyle.Left;
                cb.ForeColor = s.Color;
                cb.Text = s.Code;
                cb.Checked = true;
                cb.Tag = s;

                cb.CheckedChanged += (o, e) =>
                {
                    s.Visibility = cb.Checked ? SeriesVisibility.Visible : SeriesVisibility.Hidden;
                    checkedChangedCallback();
                };

                this.pnlChecks.Controls.Add(cb);
            }));
        }

        internal void RemoveSeriesController(Symbol s)
        {
            this.BeginInvoke(new Action(() =>
            {
                C1.Win.C1Input.C1CheckBox cb = null;

                foreach (Control item in this.pnlChecks.Controls)
                {
                    if (item is C1.Win.C1Input.C1CheckBox)
                    {
                        if (item.Tag == s)
                        {
                            cb = item as C1.Win.C1Input.C1CheckBox;
                        }
                    }
                }

                if (cb!= null)
                {
                    this.pnlChecks.Controls.Remove(cb);
                    cb.Dispose();
                }
            }));
        }
        internal void RemoveAllSeriesController()
        {
            this.BeginInvoke(new Action(() =>
            {
                this.pnlChecks.Controls.Clear();
            }));
        }

        private void InitializeControls()
        {
            if (!this.DesignMode)
                this.txtSearchBox.DataSource = DataService.Instance.SymbolNames;
            this.txtSearchBox.OnSymbolChanged += (o, e) =>
            {
                if(this.OnComparisonChanged != null)
                this.OnComparisonChanged(this, new StringEventArgs() { Value = e.Value });
            };
            
            this.ucButtonGroup.OnSelectedIndexChanged += (o, e) =>
            {
                if (this.OnSelectedIndexChanged != null)
                {
                    this.OnSelectedIndexChanged(this, e);
                }
            };

            this.btnReset.Click += (o, e) =>
            {
                if (this.OnReseted != null)
                {
                    this.OnReseted(this, new EventArgs());
                }
            };

            this.btnShowVolume.OnCheckedChanged += (o, e) =>
            {
                if (this.OnShowVolumeChanged != null)
                {
                    this.OnShowVolumeChanged(this, new BooleanEventArgs() { Value = this.btnShowVolume.Checked});
                }
            };


            cbChartType.ItemsDisplayMember = "Name";
            cbChartType.ItemsValueMember = "Value";
            var chartTypes = new ChartType[] { ChartType.Line, ChartType.Area, ChartType.Candlestick, ChartType.HighLowOpenClose };

            foreach (var t in chartTypes)
            {
                cbChartType.Items.Add(new ComboBoxItem("Chart Type: " + t.ToString(), t));
            }
            cbChartType.SelectedIndex = 0;
            //this.cbChartType.SelectedIndexChanged += (o, e) =>
            //{
            //    this.cbChartType.FitWidth();
            //    if (this.OnChartTypeChanged != null)
            //    {
            //        ChartType type = (ChartType)(cbChartType.SelectedItem);
            //        this.OnChartTypeChanged(this, new ChartTypeChangedEventArgs() { Type = type });
            //    }
            //};
            this.cbChartType.SelectedItemChanged += (o, e) =>
            {
                this.cbChartType.FitWidth();
                if (this.OnChartTypeChanged != null)
                {
                    ChartType type = (ChartType)(cbChartType.SelectedItem);
                    this.OnChartTypeChanged(this, new ChartTypeChangedEventArgs() { Type = type });
                }
            };

            cbExport.Text = "Export To";
            cbExport.Items.Add(new C1.Win.C1Input.DropDownItem() { Text = "PNG" });
            cbExport.Items.Add(new C1.Win.C1Input.DropDownItem() { Text = "JPG" });
            cbExport.Items.Add(new C1.Win.C1Input.DropDownItem() { Text = "SVG"});
            cbExport.ItemsDisplayMember = "Text";
            cbExport.DropDownClosed += (o, e) =>
            {
                var text = cbExport.SelectedText;

                if (OnSaveImage != null && text != "Export To")
                {
                    OnSaveImage(this, new StringEventArgs() { Value = text });
                }
                cbExport.SelectedIndex = -1;
                cbExport.Text = "Export To";
            };

            chkMovingAverage.CheckedChanged += (o, e) =>
            {
                this.cbMovingAverageType.Visible = 
                this.txtMovingAveragePeriod.Visible =
                this.lblPeriod.Visible = this.chkMovingAverage.Checked;

                if (this.OnMovingAverageVisibilityChanged != null)
                {
                    this.OnMovingAverageVisibilityChanged(this, new BooleanEventArgs() { Value = chkMovingAverage.Checked });
                }
            };

            cbMovingAverageType.ItemsDisplayMember = "Name";
            cbMovingAverageType.ItemsValueMember = "Value";
            foreach (var t in Enum.GetValues(typeof(C1.Chart.MovingAverageType)))
            {
                cbMovingAverageType.Items.Add(new ComboBoxItem("Type: " + t.ToString(), t));
            }
            cbMovingAverageType.SelectedIndex = 0;
            this.cbMovingAverageType.SelectedIndexChanged += (o, e) =>
            {
                this.cbMovingAverageType.FitWidth();
                if (this.OnChartTypeChanged != null)
                {
                    C1.Chart.MovingAverageType type = (C1.Chart.MovingAverageType)cbMovingAverageType.SelectedItem;
                    this.OnMovingAverageTypeChanged(this, new MovingAverageTypeChangedEventArgs() { Type = type });
                }
            };

            this.txtMovingAveragePeriod.TextChanged += (o, e) =>
            {
                int i = 0;
                bool b = int.TryParse(this.txtMovingAveragePeriod.Text, out i);
                if (b)
                {
                if (Convert.ToInt32(this.txtMovingAveragePeriod.Text) <= 2)
                    {
                        txtMovingAveragePeriod.Text = 2.ToString();
                        txtMovingAveragePeriod.Value = 2;
                    }
                    if (this.OnMovingAveragePeriodChanged != null && i >= 2)
                    {
                        this.OnMovingAveragePeriodChanged(this, new IntgerEventArgs() { Value = i });
                    }
                }
            };
            this.chkLineMarker.CheckedChanged += (o, e) =>
            {
                if (this.OnLineMarkerVisibilityChanged != null)
                {
                    this.OnLineMarkerVisibilityChanged(this, new BooleanEventArgs() { Value = chkLineMarker.Checked });
                }
            };

            this.chkNews.CheckedChanged += (o, e) =>
            {
                if (this.OnNewsVisibilityChanged != null)
                {
                    this.OnNewsVisibilityChanged(this, new BooleanEventArgs() { Value = chkNews.Checked });
                }
            };


            ToolTip toolTip1 = new ToolTip();

            toolTip1.AutoPopDelay = 5000;
            toolTip1.InitialDelay = 1000;
            toolTip1.ReshowDelay = 500;
            toolTip1.ShowAlways = true;

            toolTip1.SetToolTip(this.btnShowVolume, "Show Vlolume");
        }
    }

    public static class ComboBoxExtension
    {
        public static void FitWidth(this C1.Win.C1Input.C1ComboBox cmb)
        {
            using (Graphics g = Graphics.FromHwnd(cmb.Handle))
            {
                SizeF fontSize = g.MeasureString(cmb.Text, cmb.Font);
                cmb.Width = (int)(fontSize.Width + 29);
            }
        }
    }


    public class StringEventArgs : EventArgs
    {
        public string Value { get; set; }
    }
    public class IntgerEventArgs : EventArgs
    {
        public int Value { get; set; }
    }
    public class BooleanEventArgs : EventArgs
    {
        public bool Value { get; set; }
    }

    public class ChartTypeChangedEventArgs : EventArgs
    {
        public ChartType Type { get; set; }
    }
    public class MovingAverageTypeChangedEventArgs : EventArgs
    {
        public C1.Chart.MovingAverageType Type { get; set; }
    }

}
