namespace PerpetuumSoft.Widgets
{
    using PerpetuumSoft.Widgets.Licensing;
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;

    [ToolboxBitmap(typeof(Meter)), LicenseProvider(typeof(WidgetsLicenseProvider))]
    public class Meter : ValuePresenter
    {
        private Color dangerColor = Color.Red;
        private int dangerValue = 70;
        private int largeTickFrequency = 20;
        private int numberFrequency = 0x19;
        private Color pointerColor = Color.Red;
        private bool showGradient = false;
        private bool showNumbers = true;
        private int smallTickFrequency = 5;
        private int totalAngle = 130;

        protected override void Draw(Graphics g, Rectangle r)
        {
            base.Draw(g, r);
            Rectangle workRectangle = this.WorkRectangle;
            Pen pen = new Pen(this.ForeColor);
            Pen pen2 = new Pen(this.dangerColor);
            if (this.ShowGradient)
            {
                Brush brush = new LinearGradientBrush(workRectangle, GraphicsUtils.ScaleColor(this.BackColor, 0.5f), this.BackColor, 1);
                g.FillRectangle(brush, workRectangle);
            }
            Brush brush2 = new SolidBrush(this.ForeColor);
            Point center = this.Center;
            int num = (int) (this.Radius * 0.8f);
            float num2 = ((float) (base.Value - this.Minimum)) / (this.Maximum - this.Minimum);
            float angle = num2 * this.totalAngle;
            if (this.Text != "")
            {
                g.DrawString(this.Text, this.Font, brush2, (PointF) new Point(center.X - ((int) (g.MeasureString(this.Text, this.Font).Width / 2f)), (center.Y - 15) - (this.Font.get_Height() / 2)));
            }
            this.DrawPointer(g, center, angle, num * 0.8f);
            int num4 = (int) (num * 0.7f);
            int num5 = num4 + 3;
            int num6 = num5 + 6;
            for (int i = this.Minimum; i <= this.Maximum; i += this.smallTickFrequency)
            {
                num2 = ((float) (i - this.Minimum)) / (this.Maximum - this.Minimum);
                float num8 = num2 * this.totalAngle;
                float num9 = (((float) this.totalAngle) / 2f) - num8;
                double num10 = center.X - (Math.Sin((num9 / 180f) * 3.1415926535897931) * num4);
                double num11 = center.Y - (Math.Cos((num9 / 180f) * 3.1415926535897931) * num4);
                double num12 = num5;
                if ((i % this.largeTickFrequency) == 0)
                {
                    num12 = num6;
                }
                if (this.showNumbers && ((i % this.numberFrequency) == 0))
                {
                    int num13 = num6 + this.Font.get_Height();
                    double num14 = center.X - (Math.Sin((num9 / 180f) * 3.1415926535897931) * num13);
                    double num15 = center.Y - (Math.Cos((num9 / 180f) * 3.1415926535897931) * num13);
                    string text = base.FormatValue(i);
                    SizeF ef = g.MeasureString(text, this.Font);
                    num14 -= ef.Width / 2f;
                    num15 -= ef.Height / 2f;
                    g.DrawString(text, this.Font, brush2, (PointF) new Point((int) num14, (int) num15));
                }
                double num16 = center.X - (Math.Sin((num9 / 180f) * 3.1415926535897931) * num12);
                double num17 = center.Y - (Math.Cos((num9 / 180f) * 3.1415926535897931) * num12);
                PointF tf = new PointF((float) num10, (float) num11);
                PointF tf2 = new PointF((float) num16, (float) num17);
                if (i < this.dangerValue)
                {
                    g.DrawLine(pen, tf, tf2);
                }
                else
                {
                    g.DrawLine(pen2, tf, tf2);
                }
                g.DrawString(this.Text, this.Font, brush2, (PointF) new Point(center.X - ((int) (g.MeasureString(this.Text, this.Font).Width / 2f)), (center.Y + num6) + (this.Font.get_Height() / 2)));
            }
            g.Flush();
        }

        private void DrawPointer(Graphics g, Point p, float angle, float rad)
        {
            float num = (((float) this.totalAngle) / 2f) - angle;
            double num2 = p.X - (Math.Sin((num / 180f) * 3.1415926535897931) * rad);
            double num3 = p.Y - (Math.Cos((num / 180f) * 3.1415926535897931) * rad);
            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);
        }

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

        [DefaultValue(typeof(Color), "Red"), Category("Appearance"), Description("Danger color.")]
        public Color DangerColor
        {
            get
            {
                return this.dangerColor;
            }
            set
            {
                if (this.dangerColor != value)
                {
                    this.dangerColor = value;
                    base.Invalidate();
                }
            }
        }

        [Description("Danger Value"), Category("Behavior"), DefaultValue(70)]
        public int DangerValue
        {
            get
            {
                return this.dangerValue;
            }
            set
            {
                if (this.dangerValue != value)
                {
                    this.dangerValue = value;
                    base.Invalidate();
                }
            }
        }

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

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

        [DefaultValue(0x19), Category("Appearance"), Description("Define frequency of numbers")]
        public int NumberFrequency
        {
            get
            {
                return this.numberFrequency;
            }
            set
            {
                if (this.numberFrequency != value)
                {
                    this.numberFrequency = value;
                    base.Invalidate();
                }
            }
        }

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

        private int Radius
        {
            get
            {
                Rectangle workRectangle = this.WorkRectangle;
                if (workRectangle.Height >= (workRectangle.Width / 2))
                {
                    return (workRectangle.Width / 2);
                }
                return workRectangle.Height;
            }
        }

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

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

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

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