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

    [ToolboxBitmap(typeof(RotarySlider))]
    public class RotarySlider : ValuePresenter
    {
        private int mainInterval = 10;
        private const int pix = 20;
        private Color pointerColor = Color.Red;
        private bool showGradient = false;
        private int startVal;
        private int startY;
        private int subDivisions = 10;

        public RotarySlider()
        {
            base.SetStyle((ControlStyles)0x200, true);
        }

        protected override void Draw(Graphics g, Rectangle r)
        {
            base.Draw(g, r);
            this.DrawGauge(g);
        }

        private void DrawGauge(Graphics g)
        {
            Rectangle workRectangle = this.WorkRectangle;
            GraphicsContainer container = g.BeginContainer();
            g.IntersectClip(workRectangle);
            Color color = GraphicsUtils.ScaleColor(this.BackColor, 0.5f);
            Rectangle rect = new Rectangle(workRectangle.X, workRectangle.Y, workRectangle.Width, workRectangle.Height / 2);
            Brush brush = new LinearGradientBrush(rect, color, this.BackColor, 1);
            g.FillRectangle(brush, rect);
            brush.Dispose();
            rect = new Rectangle(workRectangle.X, workRectangle.Y + (workRectangle.Height / 2), workRectangle.Width, workRectangle.Height / 2);
            brush = new LinearGradientBrush(rect, this.BackColor, color, 1);
            g.FillRectangle(brush, rect);
            brush.Dispose();
            int y = workRectangle.Y + (workRectangle.Height / 2);
            int num2 = 20;
            int num3 = (workRectangle.Height / num2) + 1;
            if ((num3 % 2) != 0)
            {
                num3++;
            }
            int num4 = base.Value / this.mainInterval;
            int num5 = num4 * this.mainInterval;
            int num6 = num5 - (this.mainInterval * (num3 / 2));
            int num7 = num6 + (this.mainInterval * num3);
            Pen pen = new Pen(Color.DarkGray);
            Brush brush2 = new SolidBrush(this.ForeColor);
            for (int i = num6; i <= num7; i += this.mainInterval)
            {
                int num9 = y + ((int) ((((double) (base.Value - i)) / ((double) this.mainInterval)) * num2));
                g.DrawLine(pen, workRectangle.Left + 9, num9, workRectangle.Left + 12, num9);
                g.DrawLine(pen, workRectangle.Right - 9, num9, workRectangle.Right - 12, num9);
                for (int j = 1; j < this.subDivisions; j++)
                {
                    int num11 = num9 - ((int) ((((float) num2) / ((float) this.subDivisions)) * j));
                    g.DrawLine(pen, workRectangle.Left + 11, num11, workRectangle.Left + 12, num11);
                    g.DrawLine(pen, workRectangle.Right - 11, num11, workRectangle.Right - 12, num11);
                }
                int num12 = num9 - 1;
                Pen pen2 = SystemPens.ControlLightLight;
                Pen pen3 = SystemPens.ControlDark;
                g.DrawLine(pen2, workRectangle.X + 1, num12, workRectangle.X + 5, num12);
                g.DrawLine(pen3, workRectangle.X + 1, num12 + 1, workRectangle.X + 5, num12 + 1);
                g.DrawLine(pen2, (workRectangle.X + workRectangle.Width) - 1, num12, (workRectangle.X + workRectangle.Width) - 5, num12);
                g.DrawLine(pen3, (workRectangle.X + workRectangle.Width) - 1, num12 + 1, (workRectangle.X + workRectangle.Width) - 5, num12 + 1);
                num12 = (num9 + (num2 / 2)) - 1;
                g.DrawLine(pen2, workRectangle.X + 1, num12, workRectangle.X + 5, num12);
                g.DrawLine(pen3, workRectangle.X + 1, num12 + 1, workRectangle.X + 5, num12 + 1);
                g.DrawLine(pen2, (workRectangle.X + workRectangle.Width) - 1, num12, (workRectangle.X + workRectangle.Width) - 5, num12);
                g.DrawLine(pen3, (workRectangle.X + workRectangle.Width) - 1, num12 + 1, (workRectangle.X + workRectangle.Width) - 5, num12 + 1);
                float num13 = workRectangle.X + (workRectangle.Width / 2);
                float num14 = num9;
                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, brush2, (PointF) new Point((int) num13, (int) num14));
            }
            Brush brush3 = new SolidBrush(this.pointerColor);
            Point[] points = new Point[] { new Point(workRectangle.X + 5, y), new Point(workRectangle.X, y - 3), new Point(workRectangle.X, y + 3) };
            g.FillPolygon(brush3, points);
            points = new Point[] { new Point((workRectangle.X + workRectangle.Width) - 5, y), new Point(workRectangle.X + workRectangle.Width, y - 3), new Point(workRectangle.X + workRectangle.Width, y + 3) };
            g.FillPolygon(brush3, points);
            g.EndContainer(container);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.startY = e.Y;
                this.startVal = base.Value;
            }
            base.OnMouseDown(e);
        }

        protected override int PointToValue(Point p)
        {
            int num = this.startVal + ((int) ((((double) (-this.startY + p.Y)) / 20.0) * this.mainInterval));
            if (num <= this.Minimum)
            {
                return this.Minimum;
            }
            if (num >= this.Maximum)
            {
                return this.Maximum;
            }
            return num;
        }

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

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

        [Category("Appearance"), Description("Gets or sets whether control should use gradient background"), DefaultValue(false)]
        public bool ShowGradient
        {
            get
            {
                return this.showGradient;
            }
            set
            {
                if (this.showGradient != value)
                {
                    this.showGradient = value;
                    base.Invalidate();
                }
            }
        }
    }
}
