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

    [LicenseProvider(typeof(WidgetsLicenseProvider)), ToolboxBitmap(typeof(Compas))]
    public class Compas : ValuePresenter
    {
        private Color dialColor = Color.White;
        private Color pointerColor1 = Color.Red;
        private Color pointerColor2 = Color.Blue;
        private bool showGradient = false;

        protected override void Draw(Graphics g, Rectangle r)
        {
            Brush brush;
            base.Draw(g, r);
            Rectangle workRectangle = this.WorkRectangle;
            if (this.ShowGradient)
            {
                brush = new LinearGradientBrush(workRectangle, GraphicsUtils.ScaleColor(this.dialColor, 0.5f), this.dialColor, 1);
            }
            else
            {
                brush = new SolidBrush(this.dialColor);
            }
            g.FillEllipse(brush, workRectangle);
            Point center = this.Center;
            int radius = this.Radius;
            float num = ((float) (base.Value - this.Minimum)) / (this.Maximum - this.Minimum);
            float angle = num * 360f;
            using (Brush brush2 = new SolidBrush(this.ForeColor))
            {
                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)));
                }
                string[] strArray = new string[] { "N", "NW", "W", "SW", "S", "SE", "E", "NE" };
                int num3 = (int) (this.Radius * 0.7f);
                for (int i = 0; i < 8; i++)
                {
                    double a = 0.78539816339744828 * i;
                    double num6 = center.X - (Math.Sin(a) * num3);
                    double num7 = center.Y - (Math.Cos(a) * num3);
                    string text = strArray[i];
                    SizeF ef = g.MeasureString(text, this.Font);
                    num6 -= ef.Width / 2f;
                    num7 -= ef.Height / 2f;
                    g.DrawString(text, this.Font, brush2, (PointF) new Point((int) num6, (int) num7));
                }
                this.DrawPointer(g, center, angle, this.Radius * 0.8f);
                g.Flush();
            }
            brush.Dispose();
        }

        private void DrawPointer(Graphics g, Point p, float angle, float rad)
        {
            Point[] pointArray;
            float num = 180f - angle;
            double num2 = 8.0;
            double num3 = p.X - (Math.Sin((num / 180f) * 3.1415926535897931) * rad);
            double num4 = p.Y - (Math.Cos((num / 180f) * 3.1415926535897931) * rad);
            double num5 = p.X - (Math.Sin(((num / 180f) + 1f) * 3.1415926535897931) * rad);
            double num6 = p.Y - (Math.Cos(((num / 180f) + 1f) * 3.1415926535897931) * rad);
            double num7 = p.X - (Math.Sin(((num / 180f) + 0.5) * 3.1415926535897931) * num2);
            double num8 = p.Y - (Math.Cos(((num / 180f) + 0.5) * 3.1415926535897931) * num2);
            double num9 = p.X - (Math.Sin(((num / 180f) - 0.5) * 3.1415926535897931) * num2);
            double num10 = p.Y - (Math.Cos(((num / 180f) - 0.5) * 3.1415926535897931) * num2);
            g.set_SmoothingMode(4);
            using (Brush brush = new SolidBrush(this.pointerColor2))
            {
                pointArray = new Point[] { new Point((int) num3, (int) num4), new Point((int) num7, (int) num8), new Point((int) num9, (int) num10) };
                g.FillPolygon(brush, pointArray);
            }
            using (Brush brush2 = new SolidBrush(this.pointerColor1))
            {
                pointArray = new Point[] { new Point((int) num5, (int) num6), new Point((int) num7, (int) num8), new Point((int) num9, (int) num10) };
                g.FillPolygon(brush2, pointArray);
            }
            g.set_SmoothingMode(0);
        }

        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 + workRectangle.Top) / 2);
            }
        }

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

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

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

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

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

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