namespace InstrumentationControls
{
	using System;
    using System.ComponentModel;
    using System.Drawing;

    [ToolboxBitmap(typeof(Oscilloscope))]
    public class Oscilloscope : InstrumentationControl
    {
        private int depth1 = 0;
        private int depth2 = 0;
        private bool enableSecondRay = false;
        private int gridStepX = 20;
        private int gridStepY = 10;
        private int[] hystory1;
        private int[] hystory2;
        private int maximum = 100;
        private int minimum = 0;
        private Color rayColor1 = Color.LightGreen;
        private Color rayColor2 = Color.Yellow;

        public Oscilloscope()
        {
            this.BackColor = Color.Black;
            this.ForeColor = Color.Green;
        }

        protected override void Draw(Graphics g, Rectangle r)
        {
            base.Draw(g, r);
            Rectangle workRectangle = this.WorkRectangle;
            Pen pen = new Pen(this.ForeColor);
            for (int i = this.gridStepX; i < workRectangle.Width; i += this.gridStepX)
            {
                g.DrawLine(pen, i, workRectangle.Y, i, workRectangle.Y + workRectangle.Height);
            }
            for (int j = this.gridStepY; j <= (this.Maximum - this.Minimum); j += this.gridStepY)
            {
                int num3 = (int) ((((double) j) / ((double) (this.Maximum - this.Minimum))) * workRectangle.Height);
                g.DrawLine(pen, workRectangle.X, num3, workRectangle.X + workRectangle.Width, num3);
            }
            if ((this.hystory1 != null) && (this.depth1 > 1))
            {
                Point[] points = new Point[this.depth1];
                for (int k = 0; k < this.depth1; k++)
                {
                    float num5 = (this.hystory1[k] - this.Minimum) / (this.Maximum - this.Minimum);
                    int x = workRectangle.Right - k;
                    int y = workRectangle.Bottom - ((int) (num5 * workRectangle.Height));
                    points[k] = new Point(x, y);
                }
                Pen pen2 = new Pen(this.rayColor1, 2f);
                g.SmoothingMode = (System.Drawing.Drawing2D.SmoothingMode)4;
                g.DrawLines(pen2, points);
								g.SmoothingMode = (System.Drawing.Drawing2D.SmoothingMode)0;
            }
            if ((this.enableSecondRay && (this.hystory2 != null)) && (this.depth2 > 1))
            {
                Point[] pointArray2 = new Point[this.depth2];
                for (int m = 0; m < this.depth2; m++)
                {
                    float num9 = (this.hystory2[m] - this.Minimum) / (this.Maximum - this.Minimum);
                    int num10 = workRectangle.Right - m;
                    int num11 = workRectangle.Bottom - ((int) (num9 * workRectangle.Height));
                    pointArray2[m] = new Point(num10, num11);
                }
                Pen pen3 = new Pen(this.rayColor2, 2f);
								g.SmoothingMode = (System.Drawing.Drawing2D.SmoothingMode)4;
                g.DrawLines(pen3, pointArray2);
                g.SmoothingMode =(System.Drawing.Drawing2D.SmoothingMode)0;
            }
        }

        private void MoveRay1(int value)
        {
            if (this.hystory1 == null)
            {
                this.hystory1 = new int[this.WorkRectangle.Width];
                this.depth1 = 0;
            }
            if (this.depth1 < (this.hystory1.Length - 2))
            {
                this.depth1++;
            }
            for (int i = this.depth1; i >= 0; i--)
            {
                this.hystory1[i + 1] = this.hystory1[i];
            }
            this.hystory1[0] = value;
        }

        private void MoveRay2(int value)
        {
            if (this.hystory2 == null)
            {
                this.hystory2 = new int[this.WorkRectangle.Width];
                this.depth2 = 0;
            }
            if (this.depth2 < (this.hystory2.Length - 2))
            {
                this.depth2++;
            }
            for (int i = this.depth2; i >= 0; i--)
            {
                this.hystory2[i + 1] = this.hystory2[i];
            }
            this.hystory2[0] = value;
        }

        public void MoveRays(int value1)
        {
            this.MoveRay1(value1);
            base.Invalidate();
        }

        public void MoveRays(int value1, int value2)
        {
            this.MoveRay1(value1);
            this.MoveRay2(value2);
            base.Invalidate();
        }

        protected override void OnResize(EventArgs e)
        {
            this.hystory1 = null;
            this.hystory2 = null;
            base.OnResize(e);
        }

        protected override void OnTextChanged(EventArgs e)
        {
            base.Invalidate();
            base.OnTextChanged(e);
        }

        protected override Size DefaultSize
        {
            get
            {
                return new Size(0xa8, 0x80);
            }
        }

        [DefaultValue(false), Category("Appearance"), Description("Get or set whether second ray should be shown")]
        public bool EnableSecondRay
        {
            get
            {
                return this.enableSecondRay;
            }
            set
            {
                if (this.enableSecondRay != value)
                {
                    this.enableSecondRay = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(20), Description("Get or set step beetween vertical grid lines"), Category("Appearance")]
        public int GridStepX
        {
            get
            {
                return this.gridStepX;
            }
            set
            {
                if (this.gridStepX != value)
                {
                    this.gridStepX = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(10), Description("Get or set step beetween horizontal grid lines"), Category("Appearance")]
        public int GridStepY
        {
            get
            {
                return this.gridStepY;
            }
            set
            {
                if (this.gridStepY != value)
                {
                    this.gridStepY = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(100), Description("The upper bound of the value property"), Category("Behavior")]
        public int Maximum
        {
            get
            {
                return this.maximum;
            }
            set
            {
                if (this.maximum != value)
                {
                    this.maximum = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(0), Category("Behavior"), Description("The lower bound of the value property")]
        public int Minimum
        {
            get
            {
                return this.minimum;
            }
            set
            {
                if (this.minimum != value)
                {
                    this.minimum = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(Color), "LightGreen"), Category("Appearance"), Description("Color of the first ray")]
        public Color RayColor1
        {
            get
            {
                return this.rayColor1;
            }
            set
            {
                if (this.rayColor1 != value)
                {
                    this.rayColor1 = value;
                    base.Invalidate();
                }
            }
        }

        [Description("Color of the first ray"), DefaultValue(typeof(Color), "Yellow"), Category("Appearance")]
        public Color RayColor2
        {
            get
            {
                return this.rayColor2;
            }
            set
            {
                if (this.rayColor2 != value)
                {
                    this.rayColor2 = value;
                    base.Invalidate();
                }
            }
        }
    }
}
