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

    [DefaultProperty("Value"), DefaultEvent("ValueChanged"), ToolboxBitmap(typeof(Dial))]
    public class Dial : ValuePresenter
    {
        private Color dialColor = Color.White;
        private int dialRadius = 30;
        private int largeTickFrequency = 10;
        private Color pointerColor = Color.Red;
        private int pointerRadius = 20;
        private bool showNumbers = true;
        private bool showTicks = true;
        private int smallTickFrequency = 2;
        private int totalAngle = 270;

        public Dial()
        {
            base.SetStyle((System.Windows.Forms.ControlStyles)0x200, true);
        }

        protected override void Draw(Graphics g, Rectangle r)
        {
            base.Draw(g, r);
            using (Pen pen = new Pen(this.ForeColor))
            {
                using (Brush brush = new SolidBrush(this.ForeColor))
                {
                    Point center = this.Center;
                    float num = ((float) (base.Value - this.Minimum)) / (this.Maximum - this.Minimum);
                    float angle = num * this.totalAngle;
                    this.DrawDial(g, center, angle);
                    int num3 = this.dialRadius + 2;
                    int num4 = num3 + 3;
                    int num5 = num4 + 5;
                    if (this.showTicks)
                    {
                        for (int i = this.Minimum; i <= this.Maximum; i += this.smallTickFrequency)
                        {
                            num = ((float) (i - this.Minimum)) / (this.Maximum - this.Minimum);
                            float num7 = num * this.totalAngle;
                            float num8 = (((float) this.totalAngle) / 2f) - num7;
                            double num9 = center.X - (Math.Sin((num8 / 180f) * 3.1415926535897931) * num3);
                            double num10 = center.Y - (Math.Cos((num8 / 180f) * 3.1415926535897931) * num3);
                            double num11 = num4;
                            if ((i % this.largeTickFrequency) == 0)
                            {
                                num11 = num5;
                                if (this.showNumbers)
                                {
                                    int num12 = num5 + this.Font.Height;
                                    double num13 = center.X - (Math.Sin((num8 / 180f) * 3.1415926535897931) * num12);
                                    double num14 = center.Y - (Math.Cos((num8 / 180f) * 3.1415926535897931) * num12);
                                    string text = base.FormatValue(i);
                                    SizeF ef = g.MeasureString(text, this.Font);
                                    num13 -= ef.Width / 2f;
                                    num14 -= ef.Height / 2f;
                                    g.DrawString(text, this.Font, brush, (PointF) new Point((int) num13, (int) num14));
                                }
                            }
                            double num15 = center.X - (Math.Sin((num8 / 180f) * 3.1415926535897931) * num11);
                            double num16 = center.Y - (Math.Cos((num8 / 180f) * 3.1415926535897931) * num11);
                            g.DrawLine(pen, (int) num9, (int) num10, (int) num15, (int) num16);
                        }
                    }
                    g.DrawString(this.Text, this.Font, brush, (PointF) new Point(center.X - ((int) (g.MeasureString(this.Text, this.Font).Width / 2f)), (center.Y + num5) + (this.Font.Height / 2)));
                }
            }
        }

        private void DrawDial(Graphics g, Point p, float angle)
        {
            Rectangle rect = new Rectangle(p.X - this.pointerRadius, p.Y - this.pointerRadius, this.pointerRadius * 2, this.pointerRadius * 2);
            Rectangle rectangle2 = new Rectangle(p.X - this.dialRadius, p.Y - this.dialRadius, this.dialRadius * 2, this.dialRadius * 2);
            float num = p.X - (this.dialRadius * 0.6f);
            float num2 = p.Y - (this.dialRadius * 0.6f);
            float num3 = this.dialRadius * 1.85f;
            using (GraphicsPath path = new GraphicsPath())
            {
                path.AddEllipse(num - num3, num2 - num3, num3 * 2f, num3 * 2f);
                using (PathGradientBrush brush = new PathGradientBrush(path))
                {
                    brush.CenterColor =this.dialColor;
                    Color[] colorArray2 = new Color[] { GraphicsUtils.ScaleColor(this.dialColor, 0.25f) };
                    Color[] colorArray = colorArray2;
                    brush.SurroundColors = colorArray;
                    num = p.X + (this.pointerRadius * 0.6f);
                    num2 = p.Y + (this.pointerRadius * 0.6f);
                    num3 = this.pointerRadius * 1.85f;
                    using (GraphicsPath path2 = new GraphicsPath())
                    {
                        path2.AddEllipse(num - num3, num2 - num3, num3 * 2f, num3 * 2f);
                        using (PathGradientBrush brush2 = new PathGradientBrush(path2))
                        {
                            brush2.CenterColor =this.dialColor;
                            colorArray2 = new Color[] { GraphicsUtils.ScaleColor(this.DialColor, 0.5f) };
                            colorArray = colorArray2;
                            brush2.SurroundColors =colorArray;
                            GraphicsContainer container = g.BeginContainer();
                            g.SmoothingMode=(SmoothingMode)4;
                            g.FillEllipse(brush, rectangle2);
                            g.FillEllipse(brush2, rect);
                            float num4 = (((float) this.totalAngle) / 2f) - angle;
                            double num5 = p.X - (Math.Sin((num4 / 180f) * 3.1415926535897931) * this.pointerRadius);
                            double num6 = p.Y - (Math.Cos((num4 / 180f) * 3.1415926535897931) * this.pointerRadius);
                            PointF tf = new PointF((float) num5, (float) num6);
                            using (Pen pen = new Pen(this.pointerColor, 2f))
                            {
                                g.DrawLine(pen, (PointF) p, tf);
                            }
                            int num7 = 9;
                            for (int i = 0; i < num7; i++)
                            {
                                float num9 = ((360f / ((float) num7)) * i) + num4;
                                num5 = p.X - (Math.Sin((num9 / 180f) * 3.1415926535897931) * this.pointerRadius);
                                num6 = p.Y - (Math.Cos((num9 / 180f) * 3.1415926535897931) * this.pointerRadius);
                                PointF tf2 = new PointF((float) num5, (float) num6);
                                num5 = p.X - (Math.Sin((num9 / 180f) * 3.1415926535897931) * this.dialRadius);
                                num6 = p.Y - (Math.Cos((num9 / 180f) * 3.1415926535897931) * this.dialRadius);
                                PointF tf3 = new PointF((float) num5, (float) num6);
                                g.DrawLine(Pens.Gray, tf2, tf3);
                            }
                            g.EndContainer(container);
                        }
                    }
                }
            }
        }

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

        protected override int PointToValue(Point p)
        {
            double num3;
            Point center = this.Center;
            float num = center.X - p.X;
            float num2 = center.Y - p.Y;
            if (num2 == 0f)
            {
                num3 = (num > 0f) ? ((double) 90) : ((double) (-90));
            }
            else
            {
                double num4 = (Math.Atan((double) (num / num2)) * 180.0) / 3.1415926535897931;
                if (num2 > 0f)
                {
                    num3 = num4;
                }
                else
                {
                    num3 = (num > 0f) ? (num4 + 180.0) : (num4 - 180.0);
                }
            }
            double num5 = (this.totalAngle / 2) - num3;
            double num6 = num5 / ((double) this.totalAngle);
            if (num6 <= 0.0)
            {
                return this.Minimum;
            }
            if (num6 >= 1.0)
            {
                return this.Maximum;
            }
            return (this.Minimum + ((int) ((this.Maximum - this.Minimum) * num6)));
        }

        private Point Center
        {
            get
            {
                Rectangle workRectangle = this.WorkRectangle;
                return new Point((workRectangle.Left + workRectangle.Right) / 2, (workRectangle.Top + workRectangle.Bottom) / 2);
            }
        }

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

        [Description("Color of the dial"), DefaultValue(typeof(Color), "White"), Category("Appearance")]
        public Color DialColor
        {
            get
            {
                return this.dialColor;
            }
            set
            {
                if (this.dialColor != value)
                {
                    this.dialColor = value;
                    base.Invalidate();
                }
            }
        }

        [Category("Appearance"), DefaultValue(30), Description("Radius of dal")]
        public int DialRadius
        {
            get
            {
                return this.dialRadius;
            }
            set
            {
                if (this.dialRadius != value)
                {
                    this.dialRadius = value;
                    base.Invalidate();
                }
            }
        }

        protected override bool Editable
        {
            get
            {
                return true;
            }
        }

        [Description("Define frequency of large ticks"), DefaultValue(10), Category("Appearance")]
        public int LargeTickFrequency
        {
            get
            {
                return this.largeTickFrequency;
            }
            set
            {
                if (this.largeTickFrequency != value)
                {
                    this.largeTickFrequency = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(typeof(Color), "Red"), Category("Appearance"), Description("Color of the pointer")]
        public Color PointerColor
        {
            get
            {
                return this.pointerColor;
            }
            set
            {
                if (this.pointerColor != value)
                {
                    this.pointerColor = value;
                    base.Invalidate();
                }
            }
        }

        [Category("Appearance"), DefaultValue(20), Description("Radius of slider")]
        public int PointerRadius
        {
            get
            {
                return this.pointerRadius;
            }
            set
            {
                if (this.pointerRadius != value)
                {
                    this.pointerRadius = value;
                    base.Invalidate();
                }
            }
        }

        [Category("Appearance"), Description("Indicate if the control paints dial numbers"), DefaultValue(true)]
        public bool ShowNumbers
        {
            get
            {
                return this.showNumbers;
            }
            set
            {
                if (this.showNumbers != value)
                {
                    this.showNumbers = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(true), Description("Indicate if the control paints dial ticks"), Category("Appearance")]
        public bool ShowTicks
        {
            get
            {
                return this.showTicks;
            }
            set
            {
                if (this.showTicks != value)
                {
                    this.showTicks = value;
                    base.Invalidate();
                }
            }
        }

        [Description("Define frequency of small ticks"), DefaultValue(2), Category("Appearance")]
        public int SmallTickFrequency
        {
            get
            {
                return this.smallTickFrequency;
            }
            set
            {
                if (this.smallTickFrequency != value)
                {
                    this.smallTickFrequency = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(270), Category("Appearance"), Description("Angle behind minimum and maximum positions")]
        public int TotalAngle
        {
            get
            {
                return this.totalAngle;
            }
            set
            {
                if (this.totalAngle != value)
                {
                    this.totalAngle = value;
                    base.Invalidate();
                }
            }
        }
    }
}
