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

    [TypeConverter(typeof(DigitsDisplayConverter))]
    public class DigitsDisplay
    {
        private Color activeColor = Color.Lime;
        private bool antiAlias = false;
        private static Hashtable CharSegments = new Hashtable();
        private int digitHeight = 0x18;
        private int digitSpace = 3;
        private int digitWidth = 12;
        private Color inactiveColor = Color.DarkGreen;
        private GraphicsPath[] segmentPaths;
        private int segmentSpace = 1;
        private int segmentThickness = 2;

        static DigitsDisplay()
        {
            CharSegments.Add('0', 0x3f);
            CharSegments.Add('1', Segments.RightBottom | Segments.RightTop);
            CharSegments.Add('2', 0x5b);
            CharSegments.Add('3', 0x6b);
            CharSegments.Add('4', 0x6c);
            CharSegments.Add('5', 0x67);
            CharSegments.Add('6', 0x77);
            CharSegments.Add('7', Segments.RightBottom | Segments.RightTop | Segments.Top);
            CharSegments.Add('8', Segments.All);
            CharSegments.Add('9', 0x6f);
            CharSegments.Add(' ', Segments.None);
            CharSegments.Add('-', Segments.Middle);
        }

        private void AddSegmentRegion(int num, PointF[] path)
        {
            GraphicsPath path2 = new GraphicsPath();
            path2.StartFigure();
            path2.AddLines(path);
            path2.CloseFigure();
            this.segmentPaths[num] = path2;
        }

        private void CalculateRegions()
        {
            if (this.segmentPaths == null)
            {
                this.segmentPaths = new GraphicsPath[8];
                float num = this.digitHeight / 2;
                float num2 = this.segmentThickness / 2;
                PointF[] path = new PointF[] { new PointF((float) this.segmentSpace, 0f), new PointF((float) (this.digitWidth - this.segmentSpace), 0f), new PointF((float) ((this.digitWidth - this.segmentSpace) - this.segmentThickness), (float) this.segmentThickness), new PointF((float) (this.segmentSpace + this.segmentThickness), (float) this.segmentThickness) };
                this.AddSegmentRegion(0, path);
                path = new PointF[] { new PointF((float) this.segmentSpace, (float) this.digitHeight), new PointF((float) (this.digitWidth - this.segmentSpace), (float) this.digitHeight), new PointF((float) ((this.digitWidth - this.segmentSpace) - this.segmentThickness), (float) (this.digitHeight - this.segmentThickness)), new PointF((float) (this.segmentSpace + this.segmentThickness), (float) (this.digitHeight - this.segmentThickness)) };
                this.AddSegmentRegion(1, path);
                path = new PointF[] { new PointF(0f, (float) this.segmentSpace), new PointF(0f, num - this.segmentSpace), new PointF((float) this.segmentThickness, (num - this.segmentSpace) - this.segmentThickness), new PointF((float) this.segmentThickness, (float) (this.segmentSpace + this.segmentThickness)) };
                this.AddSegmentRegion(2, path);
                path = new PointF[] { new PointF((float) this.digitWidth, (float) this.segmentSpace), new PointF((float) this.digitWidth, num - this.segmentSpace), new PointF((float) (this.digitWidth - this.segmentThickness), (num - this.segmentSpace) - this.segmentThickness), new PointF((float) (this.digitWidth - this.segmentThickness), (float) (this.segmentSpace + this.segmentThickness)) };
                this.AddSegmentRegion(3, path);
                path = new PointF[] { new PointF(0f, (float) (this.digitHeight - this.segmentSpace)), new PointF(0f, (this.digitHeight - num) + this.segmentSpace), new PointF((float) this.segmentThickness, ((this.digitHeight - num) + this.segmentSpace) + this.segmentThickness), new PointF((float) this.segmentThickness, (float) ((this.digitHeight - this.segmentSpace) - this.segmentThickness)) };
                this.AddSegmentRegion(4, path);
                path = new PointF[] { new PointF((float) this.digitWidth, (float) (this.digitHeight - this.segmentSpace)), new PointF((float) this.digitWidth, (this.digitHeight - num) + this.segmentSpace), new PointF((float) (this.digitWidth - this.segmentThickness), ((this.digitHeight - num) + this.segmentSpace) + this.segmentThickness), new PointF((float) (this.digitWidth - this.segmentThickness), (float) ((this.digitHeight - this.segmentSpace) - this.segmentThickness)) };
                this.AddSegmentRegion(5, path);
                path = new PointF[] { new PointF((float) this.segmentSpace, num), new PointF(this.segmentSpace + num2, num - num2), new PointF((this.digitWidth - this.segmentSpace) - num2, num - num2), new PointF((float) (this.digitWidth - this.segmentSpace), num), new PointF((this.digitWidth - this.segmentSpace) - num2, num + num2), new PointF(this.segmentSpace + num2, num + num2) };
                this.AddSegmentRegion(6, path);
            }
        }

        private void ClearRegions()
        {
            this.segmentPaths = null;
        }

        private void PaintDigit(Graphics g, PointF pos, Segments digit)
        {
            using (Brush brush = new SolidBrush(this.activeColor))
            {
                using (Brush brush2 = new SolidBrush(this.inactiveColor))
                {
                    int num = (int) digit;
                    for (int i = 0; i < 7; i++)
                    {
                        if (this.segmentPaths[i] != null)
                        {
                            Brush brush3;
                            if ((num & 1) == 1)
                            {
                                brush3 = brush;
                            }
                            else
                            {
                                brush3 = brush2;
                            }
                            g.FillPath(brush3, this.segmentPaths[i]);
                            num = num >> 1;
                        }
                    }
                }
            }
        }

        public void PaintString(Graphics g, PointF pos, string text)
        {
            this.CalculateRegions();
            using (Brush brush = new SolidBrush(this.activeColor))
            {
                using (new SolidBrush(this.inactiveColor))
                {
                    GraphicsContainer container = g.BeginContainer();
                    g.TranslateTransform(pos.X, pos.Y);
                    if (this.antiAlias)
                    {
											g.SmoothingMode = (System.Drawing.Drawing2D.SmoothingMode)(2);
                    }
                    foreach (char ch in text)
                    {
                        if (CharSegments.ContainsKey(ch))
                        {
                            this.PaintDigit(g, pos, (Segments) CharSegments[ch]);
                            g.TranslateTransform((float) (this.digitSpace + this.digitWidth), 0f);
                        }
                        else if (ch == ':')
                        {
                            g.FillRectangle(brush, 0f, this.digitHeight * 0.3f, (float) this.segmentThickness, (float) this.segmentThickness);
                            g.FillRectangle(brush, 0f, this.digitHeight * 0.7f, (float) this.segmentThickness, (float) this.segmentThickness);
                            g.TranslateTransform((float) (this.digitSpace + this.SegmentThickness), 0f);
                        }
                        else if ((ch == '.') || (ch == ','))
                        {
                            g.FillRectangle(brush, 0, this.digitHeight, this.segmentThickness, this.segmentThickness);
                            g.TranslateTransform((float) (this.digitSpace + this.SegmentThickness), 0f);
                        }
                    }
                    g.EndContainer(container);
                }
            }
        }

        [Description("Active led color"), DefaultValue(typeof(Color), "Lime"), Category("Appearance")]
        public Color ActiveColor
        {
            get
            {
                return this.activeColor;
            }
            set
            {
                if (this.activeColor != value)
                {
                    this.activeColor = value;
                }
            }
        }

        [DefaultValue(false), Category("Appearance"), Description("Switch antialiasing mode for drawing digits")]
        public bool AntiAlias
        {
            get
            {
                return this.antiAlias;
            }
            set
            {
                if (this.antiAlias != value)
                {
                    this.antiAlias = value;
                }
            }
        }

        [DefaultValue(0x18), Description("Height of partial digit"), Category("Appearance")]
        public int DigitHeight
        {
            get
            {
                return this.digitHeight;
            }
            set
            {
                if (this.digitHeight != value)
                {
                    this.digitHeight = value;
                    this.ClearRegions();
                }
            }
        }

        [Description("Space behind neightbours digits"), Category("Appearance"), DefaultValue(3)]
        public int DigitSpace
        {
            get
            {
                return this.digitSpace;
            }
            set
            {
                if (this.digitSpace != value)
                {
                    this.digitSpace = value;
                }
            }
        }

        [Description("Width of partial digit"), Category("Appearance"), DefaultValue(12)]
        public int DigitWidth
        {
            get
            {
                return this.digitWidth;
            }
            set
            {
                if (this.digitWidth != value)
                {
                    this.digitWidth = value;
                    this.ClearRegions();
                }
            }
        }

        [DefaultValue(typeof(Color), "DarkGreen"), Description("Ininactive led color"), Category("Appearance")]
        public Color InactiveColor
        {
            get
            {
                return this.inactiveColor;
            }
            set
            {
                if (this.inactiveColor != value)
                {
                    this.inactiveColor = value;
                }
            }
        }

        [Description("Space behind led segments"), DefaultValue(1), Category("Appearance")]
        public int SegmentSpace
        {
            get
            {
                return this.segmentSpace;
            }
            set
            {
                if (this.segmentSpace != value)
                {
                    this.segmentSpace = value;
                    this.ClearRegions();
                }
            }
        }

        [Category("Appearance"), Description("Led segment thickness"), DefaultValue(2)]
        public int SegmentThickness
        {
            get
            {
                return this.segmentThickness;
            }
            set
            {
                if (this.segmentThickness != value)
                {
                    this.segmentThickness = value;
                    this.ClearRegions();
                }
            }
        }

        [Flags]
        private enum Segments
        {
            All = 0x7f,
            Bottom = 2,
            LeftBottom = 0x10,
            LeftTop = 4,
            Middle = 0x40,
            None = 0,
            RightBottom = 0x20,
            RightTop = 8,
            Top = 1
        }
    }
}
