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

    [DefaultEvent("ValueChanged"), DefaultProperty("Value"), ToolboxBitmap(typeof(Knob))]
    public class Knob : ValuePresenter
    {
        private Color activeLedColor = Color.LightGreen;
        private Color dialColor = Color.White;
        private int dialRadius = 30;
        private Color inactiveLedColor = Color.Green;
        private int largeTickFrequency = 10;
        private bool showNumbers = true;
        private bool showTicks = true;
        private bool showValue = false;
        private int smallTickFrequency = 2;
        private int totalAngle = 270;

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

        protected override void Draw(Graphics g, Rectangle r)
        {
            base.Draw(g, r);
            Pen pen = new Pen(this.ForeColor);
            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.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;
            GraphicsPath path = new GraphicsPath();
            path.AddEllipse(num - num3, num2 - num3, num3 * 2f, num3 * 2f);
            PathGradientBrush brush = new PathGradientBrush(path);
            brush.CenterColor =this.dialColor;
            Color[] colorArray = new Color[] { GraphicsUtils.ScaleColor(this.dialColor, 0.4f) };
            brush.SurroundColors =colorArray;
            GraphicsContainer container = g.BeginContainer();
            g.SmoothingMode = (SmoothingMode)4;
            g.FillEllipse(brush, rect);
            this.DrawPointer(g, p, angle);
            if (this.showValue)
            {
                StringFormat format = new StringFormat();
                format.Alignment = StringAlignment.Center;
                format.LineAlignment = StringAlignment.Center;
                g.DrawString(base.FormatValue(base.Value), this.Font, new SolidBrush(this.ForeColor), rect, format);
            }
            g.EndContainer(container);
        }

        private void DrawPointer(Graphics g, Point p, float angle)
        {
            Brush brush;
            float num = (((float) this.totalAngle) / 2f) - angle;
            int num2 = this.dialRadius - 6;
            double num3 = p.X - (Math.Sin((num / 180f) * 3.1415926535897931) * num2);
            double num4 = p.Y - (Math.Cos((num / 180f) * 3.1415926535897931) * num2);
            Rectangle rect = new Rectangle(((int) num3) - 2, ((int) num4) - 2, 5, 5);
            if (base.Capture)
            {
                brush = new SolidBrush(this.activeLedColor);
            }
            else
            {
                brush = new SolidBrush(this.inactiveLedColor);
            }
            g.FillEllipse(brush, rect);
        }

        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)));
        }

        [Category("Appearance"), Description("Active led color"), DefaultValue(typeof(Color), "LightGreen")]
        public Color ActiveLedColor
        {
            get
            {
                return this.activeLedColor;
            }
            set
            {
                if (value != this.activeLedColor)
                {
                    this.activeLedColor = value;
                    base.Invalidate();
                }
            }
        }

        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);
            }
        }

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

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

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

        [DefaultValue(typeof(Color), "Green"), Description("Inactive led color"), Category("Appearance")]
        public Color InactiveLedColor
        {
            get
            {
                return this.inactiveLedColor;
            }
            set
            {
                if (value != this.inactiveLedColor)
                {
                    this.inactiveLedColor = value;
                    base.Invalidate();
                }
            }
        }

        [Description("Define frequency of large ticks"), Category("Appearance"), DefaultValue(10)]
        public int LargeTickFrequency
        {
            get
            {
                return this.largeTickFrequency;
            }
            set
            {
                if (this.largeTickFrequency != value)
                {
                    this.largeTickFrequency = 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), Category("Appearance"), Description("Indicate if the control paints dial ticks")]
        public bool ShowTicks
        {
            get
            {
                return this.showTicks;
            }
            set
            {
                if (this.showTicks != value)
                {
                    this.showTicks = value;
                    base.Invalidate();
                }
            }
        }

        [DefaultValue(false), Category("Appearance"), Description("Indicate if the control paints current value")]
        public bool ShowValue
        {
            get
            {
                return this.showValue;
            }
            set
            {
                if (this.showValue != value)
                {
                    this.showValue = value;
                    base.Invalidate();
                }
            }
        }

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

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