using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Mesnac.Controls.Default
{
    [ToolboxBitmap(typeof(Curve), "ICONS.Curve.bmp")]
    public partial class Curve : Control
    {
        #region 初始化
        public Curve()
        {
            InitializeComponent();
            SetStyle(ControlStyles.UserPaint |
                    ControlStyles.DoubleBuffer |
                    ControlStyles.ResizeRedraw |
                    ControlStyles.AllPaintingInWmPaint |
                    ControlStyles.SupportsTransparentBackColor,
                    true);
            this.Size = new Size(200, 180);
        }
        private int _xPointCount = 200;
        List<pvalue> m_pvalues = new List<pvalue>();		// value array
        private string strTitle = "曲线图"; //标题
        private Color clrAxisTextColor = Color.Black; //轴说明文字颜色
        private Color clrSliceTextColor = Color.Black; //刻度文字颜色
        private int _MaXValue = 200;
        private class pvalue
        {
            public pvalue()
            {
                time = DateTime.Now;
            }
            public float value { get; set; }
            public DateTime time { get; set; }
        }
        #endregion
        #region 公共属性
        #region mFont
        private Font _font = null;
        [Description("文本字体"), Category("Appearance")]
        public Font mFont
        {
            get { return _font; }
            set { _font = value; this.Invalidate(); }
        }
        #endregion
        #region MaxValue
        [Description("Y轴最大值"), Category("Data")]
        public int MaxValue
        {
            set { _MaXValue = value; this.Invalidate(); }
            get { return _MaXValue; }
        }
        #endregion
        #region xPointCount
        [Description("X轴最大值"), Category("Data")]
        public int xPointCount
        {
            set { _xPointCount = value; this.Invalidate(); }
            get { return _xPointCount; }
        }
        #endregion
        #region CurrentValue
        private float _CurrentValue = 0f;
        public float CurrentValue
        {
            set { _CurrentValue = value; }
            get { return _CurrentValue; }
        }
        #endregion
        #region sName
        private string _sName = "CurveName";
        [Description("曲线名称"), Category("Appearance")]
        public string sName
        {
            set { _sName = value; this.Invalidate(); }
            get { return _sName; }
        }
        #endregion
        #region Title
        /// <summary>
        /// 标题
        /// </summary>
        /// 
        [Description("图表标题"), Category("Appearance")]
        public string Title
        {
            set { strTitle = value; this.Invalidate(); }
            get { return strTitle; }
        }
        #endregion
        #region TextColor
        /// <summary>
        /// 文字颜色
        /// </summary>
        /// 
        private Color clrTextColor = Color.Green;
        [Description("数字和文本的颜色"), Category("Appearance")]
        public Color TextColor
        {
            set { clrTextColor = value; this.Invalidate(); }
            get { return clrTextColor; }
        }
        #endregion
        #region AxisColor
        /// <summary>
        /// 轴线颜色
        /// </summary>
        /// 
        private Color clrAxisColor = Color.Black;
        [Description("坐标系的颜色"), Category("Appearance")]
        public Color AxisColor
        {
            set { clrAxisColor = value; this.Invalidate(); }
            get { return clrAxisColor; }
        }
        #endregion
        #region CurveColor
        /// <summary>
        /// 曲线颜色
        /// </summary>
        /// 
        private Color clrsCurveColors = Color.Red;
        [Description("曲线颜色"), Category("Appearance")]
        public Color CurveColor
        {
            set { clrsCurveColors = value; this.Invalidate(); }
            get { return clrsCurveColors; }
        }
        #endregion
        #region DashStyle
        private DashStyle _dashStyle = DashStyle.Solid;
        [Description("边框风格"), Category("Behavior")]
        public DashStyle DashStyle
        {
            get { return _dashStyle; }
            set { _dashStyle = value; this.Invalidate(); }
        }
        #endregion
        #region LineStyle
        private DashStyle _LineStyle = DashStyle.Solid;
        [Description("曲线风格"), Category("Behavior")]
        public DashStyle LineStyle
        {
            get { return _LineStyle; }
            set { _LineStyle = value; this.Invalidate(); }
        }
        #endregion
        #region FontSize
        /// <summary>
        /// 字体大小号数
        /// </summary>
        /// 
        private int intFontSize = 9;
        [Description("数字和文本的字号"), Category("Appearance")]
        public int FontSize
        {
            get { return intFontSize; }
            set { intFontSize = value; this.Invalidate(); }
        }
        #endregion
        #region CurveSize
        /// <summary>
        /// 曲线线条大小
        /// </summary>
        /// 
        private int intCurveSize = 1;
        [Description("曲线线宽"), Category("Appearance")]
        public int CurveSize
        {
            get { return intCurveSize; }
            set { intCurveSize = value; this.Invalidate(); }
        }
        #endregion
        #region LineColor
        //
        //line style
        private Color _LineColor = Color.Black;
        [Description("边框颜色"), Category("Appearance")]
        public Color LineColor
        {
            get { return _LineColor; }
            set { _LineColor = value; this.Invalidate(); }
        }
        #endregion
        #region LineWidth
        private int _LineWidth = 2;
        [Description("边框线宽"), Category("Appearance")]
        public int LineWidth
        {
            get { return _LineWidth; }
            set { _LineWidth = value; this.Invalidate(); }
        }
        #endregion
        #region LineAlpha
        private int _LineAlpha = 255;
        [Description("边框线色透明值0~255"), Category("Appearance")]
        public int LineAlpha
        {
            get { return _LineAlpha; }
            set { _LineAlpha = value; this.Invalidate(); }
        }
        #endregion
        #region bHaveAction
        //action setup
        private bool _bHaveAction = false;
        public bool bHaveAction
        {
            get
            {
                return _bHaveAction;
            }
            set
            {
                _bHaveAction = value;
            }
        }
        #endregion
        #region ScaleName
        private string _scalename = null;
        public string ScaleName
        {
            get
            {
                return _scalename;
            }
            set
            {
                _scalename = value;
            }
        }
        #endregion
        #endregion
        #region PointValue
        private void AddPoint(float y)
        {
            CurrentValue = y;
            pvalue p = new pvalue();
            p.value = y;

            m_pvalues.Add(p);
            if (m_pvalues.Count > _xPointCount)
            {
                m_pvalues.RemoveAt(0);
            }
            this.Refresh();
        }

        private string _PointName = null;
        public string PointName
        {
            get
            {
                return _PointName;
            }
            set
            {
                _PointName = value;
            }
        }
        public float PointValue
        {
            set
            {
                AddPoint(value);
            }
            get
            {
                return CurrentValue;
            }
        }
        #endregion
        protected override void OnPaint(PaintEventArgs pe)
        {
            // TODO: 在此处添加自定义绘制代码
            #region 初始化基础表格
            Graphics g = pe.Graphics;
            GraphicsPath path = new GraphicsPath();
            Rectangle rect = new Rectangle(new Point(0, 0), new Size(this.ClientSize.Width, this.ClientSize.Height));
            path.AddRectangle(rect);
            Pen pen = null;
            pen = new Pen(Color.FromArgb(LineAlpha, LineColor));
            pen.Width = LineWidth;
            pen.DashStyle = DashStyle;
            g.DrawPath(pen, path);
            if (pen != null)
            {
                pen.Dispose();
            }
            path.Dispose();
            //draw cordniate
            if (_font == null)
            {
                _font = new Font("宋体", FontSize, FontStyle.Regular);
            }
            SolidBrush b1 = new SolidBrush(clrAxisColor);
            Pen b2 = new Pen(AxisColor, 1);
            for (int j = -2; j < 3; j++)//-2 3
            {
                int i;
                double slice = ((double)j * MaxValue / 2);
                g.DrawString(slice.ToString(), _font, b1, rect.Left, rect.Top + rect.Height / 2 - j * rect.Height / 6);
                for (i = 0; i < 60; i += 2)
                {
                    float fltX1 = rect.Left + 9 * rect.Width * i / 600;
                    float fltY1 = rect.Top + rect.Height / 2 - j * rect.Height / 6;
                    float fltX2 = rect.Left + 9 * rect.Width * (i + 1) / 600;
                    float fltY2 = rect.Top + rect.Height / 2 - j * rect.Height / 6;
                    g.DrawLine(b2, fltX1, fltY1, fltX2, fltY2);
                }
            }
            SolidBrush sb = new SolidBrush(clrTextColor);
            //Font ft = new Font("宋体", FontSize);
            g.DrawString(strTitle, _font, sb, rect.Width / 2 - strTitle.Length, rect.Top + 15);
            g.DrawString("当前值: " + CurrentValue.ToString(), _font, sb, rect.Left + 5, rect.Top + 15);
            g.DrawString("曲线名称: " + sName, _font, sb, rect.Left + 5, rect.Bottom - 15);
            #endregion
            #region 曲线值
            //draw curve
            float maxheight = MaxValue;
            float widthsegment = (float)(rect.Width * 0.9) / _xPointCount;
            Pen b3 = new Pen(clrsCurveColors, intCurveSize);
            b3.DashStyle = LineStyle;
            if (true)
            {
                float fltX1 = rect.Left;
                float fltY1 = rect.Top + rect.Height / 2;
                for (int i = 0; i < m_pvalues.Count; i++)
                {
                    float fltX2 = rect.Left + i * widthsegment;
                    float fltY2 = rect.Top + rect.Height / 2 - ((m_pvalues[i].value * rect.Height) / (2 * maxheight)) * 2 / 3;
                    g.DrawLine(b3, fltX1, fltY1, fltX2, fltY2);
                    fltX1 = fltX2;
                    fltY1 = fltY2;
                    if ((i + 1) % 30 == 0 && i > 0)
                    {
                        g.DrawLine(b2, fltX2, rect.Top + 1 * rect.Height / 6, fltX2, rect.Top + 5 * rect.Height / 6);
                        g.DrawString(m_pvalues[i].time.ToString("mm:ss"), _font, sb, fltX2 - 16, rect.Top + 5 * rect.Height / 6);
                    }
                }
            }
            b1.Dispose();
            b2.Dispose();
            b3.Dispose();
            sb.Dispose();
            #endregion
            // 调用基类 OnPaint
            base.OnPaint(pe);
        }
    }
}