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

    [DefaultProperty("Value"),DefaultEvent("ValueChanged"), ToolboxBitmap(typeof(MultiPositionSwitch))]
    public class MultiPositionSwitch : ValuePresenter
    {
        private string[] cases = new string[0];
        private Color dialColor = Color.White;
        private int dialRadius = 30;
        private Color pointerColor = Color.Black;
        private int pointerRadius = 20;
        private int totalAngle = 270;

        public MultiPositionSwitch()
        {
            base.SetStyle((System.Windows.Forms.ControlStyles)0x200, true);
            this.Maximum = 5;
            this.Increment = 1;
        }

        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 + 6;
            int num5 = 7;
            for (int i = this.Minimum; i <= this.Maximum; i++)
            {
                double num13;
                double num14;
                string str;
                Point point2;
                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 = center.X - (Math.Sin((num8 / 180f) * 3.1415926535897931) * num4);
                double num12 = center.Y - (Math.Cos((num8 / 180f) * 3.1415926535897931) * num4);
                g.DrawLine(pen, (int) num9, (int) num10, (int) num11, (int) num12);
                int index = i - this.Minimum;
                if (this.cases.Length > index)
                {
                    str = this.cases[index];
                }
                else
                {
                    str = "case " + i.ToString();
                }
                SizeF ef = g.MeasureString(str, this.Font);
                if ((i - this.Minimum) < ((this.Maximum - this.Minimum) / 2))
                {
                    num13 = num11 - num5;
                    num14 = num12;
                    point2 = new Point((((int) num13) - ((int) ef.Width)) - 2, ((int) num14) - ((int) ef.Height));
                }
                else if ((i - this.Minimum) > ((this.Maximum - this.Minimum) / 2))
                {
                    num13 = num11 + num5;
                    num14 = num12;
                    point2 = new Point(((int) num13) + 2, ((int) num14) - ((int) ef.Height));
                }
                else
                {
                    num13 = num11;
                    num14 = num12;
                    point2 = new Point(((int) num13) - ((int) (ef.Width / 2f)), (((int) num14) - ((int) ef.Height)) - 3);
                }
                g.DrawLine(pen, (int) num13, (int) num14, (int) num11, (int) num12);
                Font font = this.Font;
                g.DrawString(str, font, brush, (PointF) point2);
            }
            g.DrawString(this.Text, this.Font, brush, (PointF) new Point(center.X - ((int) (g.MeasureString(this.Text, this.Font).Width / 2f)), (center.Y + num4) + (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;
            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.25f) };
            brush.SurroundColors =colorArray;
            SolidBrush brush2 = new SolidBrush(GraphicsUtils.ScaleColor(this.dialColor, 0.75f));
            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);
            new PointF((float) num5, (float) num6);
            double num7 = p.X - (Math.Sin(((90f + num4) / 180f) * 3.1415926535897931) * 3.0);
            double num8 = p.Y - (Math.Cos(((90f + num4) / 180f) * 3.1415926535897931) * 3.0);
            double num9 = p.X - (Math.Sin(((-90f + num4) / 180f) * 3.1415926535897931) * 3.0);
            double num10 = p.Y - (Math.Cos(((-90f + num4) / 180f) * 3.1415926535897931) * 3.0);
            PointF[] tfArray = new PointF[] { new PointF((float) num5, (float) num6), new PointF((float) num7, (float) num8), new PointF((float) num9, (float) num10) };
            g.FillPolygon(new SolidBrush(this.pointerColor), tfArray);
            int num11 = 9;
            for (int i = 0; i < num11; i++)
            {
                float num13 = ((360f / ((float) num11)) * i) + num4;
                num5 = p.X - (Math.Sin((num13 / 180f) * 3.1415926535897931) * this.pointerRadius);
                num6 = p.Y - (Math.Cos((num13 / 180f) * 3.1415926535897931) * this.pointerRadius);
                PointF tf = new PointF((float) num5, (float) num6);
                num5 = p.X - (Math.Sin((num13 / 180f) * 3.1415926535897931) * this.dialRadius);
                num6 = p.Y - (Math.Cos((num13 / 180f) * 3.1415926535897931) * this.dialRadius);
                PointF tf2 = new PointF((float) num5, (float) num6);
                g.DrawLine(Pens.Gray, tf, tf2);
            }
            g.EndContainer(container);
        }

        private void DrawPointer(Graphics g, Point p, float angle)
        {
            float num = (((float) this.totalAngle) / 2f) - angle;
            double num2 = p.X - (Math.Sin((num / 180f) * 3.1415926535897931) * this.pointerRadius);
            double num3 = p.Y - (Math.Cos((num / 180f) * 3.1415926535897931) * this.pointerRadius);
            Point point = new Point((int) num2, (int) num3);
            g.DrawLine(new Pen(this.pointerColor), p, point);
        }

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

        [Description("Cases text"), Category("Appearance")]
        public string[] Cases
        {
            get
            {
                return this.cases;
            }
            set
            {
                this.cases = 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(180, 170);
            }
        }

        [Category("Appearance"), DefaultValue(typeof(Color), "White"), Description("Color of the dial")]
        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(1)]
        public override int Increment
        {
            get
            {
                return base.Increment;
            }
            set
            {
                base.Increment = value;
            }
        }

        [DefaultValue(5)]
        public override int Maximum
        {
            get
            {
                return base.Maximum;
            }
            set
            {
                base.Maximum = value;
            }
        }

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

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

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