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

    [LicenseProvider(typeof(WidgetsLicenseProvider)), DefaultEvent("ValueChanged"), ToolboxBitmap(typeof(Slider)), DefaultProperty("Value")]
    public class Slider : ValuePresenter
    {
        private Color activeLedColor = Color.LightGreen;
        private Color endColor = Color.Red;
        private Color inactiveLedColor = Color.Green;
        private int indent = 10;
        private int largeTickFrequency = 20;
        private bool showNumbers = true;
        private bool showTicks = true;
        private Bitmap sliderImage = null;
        private int smallTickFrequency = 5;
        private Color startColor = Color.Yellow;

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

        protected override void Draw(Graphics g, Rectangle r)
        {
            base.Draw(g, r);
            Rectangle trackRectangle = this.TrackRectangle;
            Rectangle rect = trackRectangle;
            rect.X--;
            rect.Y--;
            rect.Width++;
            rect.Height++;
            g.DrawRectangle(new Pen(this.ForeColor), rect);
            float num = ((float) (base.Value - this.Minimum)) / (this.Maximum - this.Minimum);
            int width = (int) (num * trackRectangle.Width);
            Point p = new Point(trackRectangle.X + width, trackRectangle.Y + (trackRectangle.Height / 2));
            g.FillRectangle(new LinearGradientBrush(trackRectangle, this.startColor, this.endColor, 0), trackRectangle.X, trackRectangle.Y, width, trackRectangle.Height);
            g.FillRectangle(Brushes.get_Black(), trackRectangle.X + width, trackRectangle.Y, trackRectangle.Width - width, trackRectangle.Height);
            this.DrawSlider(g, p);
            if (this.showTicks)
            {
                for (int i = this.Minimum; i <= this.Maximum; i += this.smallTickFrequency)
                {
                    num = ((float) (i - this.Minimum)) / (this.Maximum - this.Minimum);
                    int num4 = trackRectangle.X + ((int) (num * trackRectangle.Width));
                    int num5 = 3;
                    if ((i % this.largeTickFrequency) == 0)
                    {
                        num5 = 7;
                    }
                    if (this.showNumbers && ((i % this.largeTickFrequency) == 0))
                    {
                        float num6 = num4;
                        float num7 = trackRectangle.Top - 30;
                        string text = base.FormatValue(i);
                        SizeF ef = g.MeasureString(text, this.Font);
                        num6 -= ef.Width / 2f;
                        num7 -= ef.Height / 2f;
                        g.DrawString(text, this.Font, new SolidBrush(this.ForeColor), (PointF) new Point((int) num6, (int) num7));
                    }
                    g.DrawLine(new Pen(this.ForeColor), num4, trackRectangle.Top - 10, num4, (trackRectangle.Top - 10) - num5);
                }
            }
        }

        private void DrawSlider(Graphics g, Point p)
        {
            if (this.sliderImage == null)
            {
                Brush brush;
                Rectangle rect = new Rectangle(p.X - 5, p.Y - 10, 10, 20);
                g.FillRectangle(new LinearGradientBrush(rect, Color.White, Color.Gray, 45f), rect);
                GraphicsUtils.DrawBevel(g, rect, BevelStyle.Raised);
                if (base.Capture)
                {
                    brush = new SolidBrush(this.activeLedColor);
                }
                else
                {
                    brush = new SolidBrush(this.inactiveLedColor);
                }
                Rectangle rectangle2 = rect;
                rectangle2.Inflate(-3, -3);
                g.FillRectangle(brush, rectangle2);
            }
            else
            {
                Rectangle rectangle3 = new Rectangle(p.X - (this.sliderImage.Width / 2), p.Y - (this.sliderImage.Height / 2), this.sliderImage.Width, this.sliderImage.Height);
                g.DrawImage(this.sliderImage, rectangle3);
            }
        }

        protected override void OnTextChanged(EventArgs e)
        {
            base.Invalidate();
            base.OnTextChanged(e);
        }

        protected override int PointToValue(Point p)
        {
            Rectangle trackRectangle = this.TrackRectangle;
            if (p.X <= trackRectangle.Left)
            {
                return this.Minimum;
            }
            if (p.X >= trackRectangle.Right)
            {
                return this.Maximum;
            }
            float num = ((float) (p.X - trackRectangle.X)) / ((float) trackRectangle.Width);
            return (((int) (num * (this.Maximum - this.Minimum))) + this.Minimum);
        }

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

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

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

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

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

        [DefaultValue(10), Description("Left and Right Indent"), Category("Appearance")]
        public int Indent
        {
            get
            {
                return this.indent;
            }
            set
            {
                if (this.indent != value)
                {
                    this.indent = value;
                    base.Invalidate();
                }
            }
        }

        [Category("Appearance"), DefaultValue(20), Description("Define frequency of large ticks")]
        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();
                }
            }
        }

        [Description("Indicate if the control paints dial ticks"), Category("Appearance"), DefaultValue(true)]
        public bool ShowTicks
        {
            get
            {
                return this.showTicks;
            }
            set
            {
                if (this.showTicks != value)
                {
                    this.showTicks = value;
                    base.Invalidate();
                }
            }
        }

        [Category("Appearance"), DefaultValue((string) null), Description("Shape of the slider")]
        public Bitmap SliderImage
        {
            get
            {
                return this.sliderImage;
            }
            set
            {
                if (this.sliderImage != value)
                {
                    this.sliderImage = value;
                    if (this.sliderImage != null)
                    {
                        this.sliderImage.MakeTransparent(this.sliderImage.GetPixel(this.sliderImage.Width - 1, this.sliderImage.Height - 1));
                    }
                    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();
                }
            }
        }

        [DefaultValue(typeof(Color), "Yellow"), Description("Start gradient color"), Category("Appearance")]
        public Color StartColor
        {
            get
            {
                return this.startColor;
            }
            set
            {
                if (this.startColor != value)
                {
                    this.startColor = value;
                    base.Invalidate();
                }
            }
        }

        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                base.Text = value;
            }
        }

        private Rectangle TrackRectangle
        {
            get
            {
                Rectangle workRectangle = this.WorkRectangle;
                return new Rectangle(workRectangle.X + this.Indent, workRectangle.Bottom - 15, workRectangle.Width - (this.Indent * 2), 5);
            }
        }
    }
}
