﻿// Decompiled with JetBrains decompiler
// Type: InvokedServer.Controls.HexEditor.HexEditor
// Assembly: HQ, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: C53BC0E5-A85B-41E9-8105-FC74ED122A9A
// Assembly location: C:\Users\ian\Downloads\Telegram Desktop\fein\HQ.exe

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;


namespace InvokedServer.Controls.HexEditor
{
	public class HexEditor : Control
	{
		private object _caretLock = new object();
		private object _hexTableLock = new object();
		private IKeyMouseEventHandler _handler;
		private EditView _editView;
		private ByteCollection _hexTable;
		private string _lineCountCaps = "X";
		private int _nrCharsLineCount = 4;
		private Caret _caret;
		private Rectangle _recContent;
		private Rectangle _recLineCount;
		private StringFormat _stringFormat;
		private int _firstByte;
		private int _lastByte;
		private int _maxBytesH;
		private int _maxBytesV;
		private int _maxBytes;
		private int _maxVisibleBytesV;
		private VScrollBar _vScrollBar;
		private int _vScrollBarWidth = 20;
		private int _vScrollPos;
		private int _vScrollMax;
		private int _vScrollMin;
		private int _vScrollSmall;
		private int _vScrollLarge;
		private SizeF _charSize;
		private bool _isVScrollHidden = true;
		private int _bytesPerLine = 8;
		private int _entityMargin = 10;
		private BorderStyle _borderStyle = BorderStyle.Fixed3D;
		private Color _borderColor = Color.Empty;
		private Color _selectionBackColor = Color.Blue;
		private Color _selectionForeColor = Color.White;
		private InvokedServer.Controls.HexEditor.HexEditor.CaseStyle _lineCountCaseStyle = InvokedServer.Controls.HexEditor.HexEditor.CaseStyle.UpperCase;
		private InvokedServer.Controls.HexEditor.HexEditor.CaseStyle _hexViewCaseStyle = InvokedServer.Controls.HexEditor.HexEditor.CaseStyle.UpperCase;
		private bool _isVScrollVisible;
		private bool _dragging;

		public override Font Font
		{
			set
			{
				base.Font = value;
				this.UpdateRectanglePositioning();
				this.Invalidate();
			}
		}

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

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public byte[] HexTable
		{
			get
			{
				lock (this._hexTableLock)
					return this._hexTable.ToArray();
			}
			set
			{
				lock (this._hexTableLock)
				{
					if (value == this._hexTable.ToArray())
						return;
					this._hexTable = new ByteCollection(value);
				}
				this.UpdateRectanglePositioning();
				this.Invalidate();
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public SizeF CharSize
		{
			get => this._charSize;
			private set
			{
				if (this._charSize == value)
					return;
				this._charSize = value;
				if (this.CharSizeChanged == null)
					return;
				this.CharSizeChanged((object)this, EventArgs.Empty);
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int MaxBytesV => this._maxBytesV;

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int FirstVisibleByte => this._firstByte;

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int LastVisibleByte => this._lastByte;

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public bool VScrollBarHidden
		{
			get => this._isVScrollHidden;
			set
			{
				if (this._isVScrollHidden == value)
					return;
				this._isVScrollHidden = value;
				if (!this._isVScrollHidden)
					this.Controls.Add((Control)this._vScrollBar);
				else
					this.Controls.Remove((Control)this._vScrollBar);
				this.UpdateRectanglePositioning();
				this.Invalidate();
			}
		}

		[DefaultValue(8)]
		[Category("Hex")]
		[Description("Property that specifies the number of bytes to display per line.")]
		public int BytesPerLine
		{
			get => this._bytesPerLine;
			set
			{
				if (this._bytesPerLine == value)
					return;
				this._bytesPerLine = value;
				this.UpdateRectanglePositioning();
				this.Invalidate();
			}
		}

		[DefaultValue(10)]
		[Category("Hex")]
		[Description("Property that specifies the margin between each of the entitys in the control.")]
		public int EntityMargin
		{
			get => this._entityMargin;
			set
			{
				if (this._entityMargin == value)
					return;
				this._entityMargin = value;
				this.UpdateRectanglePositioning();
				this.Invalidate();
			}
		}

		[DefaultValue(BorderStyle.Fixed3D)]
		[Category("Appearance")]
		[Description("Indicates where the control should have a border.")]
		public BorderStyle BorderStyle
		{
			get => this._borderStyle;
			set
			{
				if (this._borderStyle == value)
					return;
				if (value != BorderStyle.FixedSingle)
					this._borderColor = Color.Empty;
				this._borderStyle = value;
				this.UpdateRectanglePositioning();
				this.Invalidate();
			}
		}

		[DefaultValue(typeof(Color), "Empty")]
		[Category("Appearance")]
		[Description("Indicates the color to be used when displaying a FixedSingle border.")]
		public Color BorderColor
		{
			get => this._borderColor;
			set
			{
				if (this.BorderStyle != BorderStyle.FixedSingle || this._borderColor == value)
					return;
				this._borderColor = value;
				this.Invalidate();
			}
		}

		[DefaultValue(typeof(Color), "Blue")]
		[Category("Hex")]
		[Description("Property for the background color of the selected text areas.")]
		public Color SelectionBackColor
		{
			get => this._selectionBackColor;
			set
			{
				if (this._selectionBackColor == value)
					return;
				this._selectionBackColor = value;
			}
		}

		[DefaultValue(typeof(Color), "White")]
		[Category("Hex")]
		[Description("Property for the foreground color of the selected text areas.")]
		public Color SelectionForeColor
		{
			get => this._selectionForeColor;
			set
			{
				if (this._selectionForeColor == value)
					return;
				this._selectionForeColor = value;
			}
		}

		[DefaultValue(InvokedServer.Controls.HexEditor.HexEditor.CaseStyle.UpperCase)]
		[Category("Hex")]
		[Description("Property for the case type to use on the line counter.")]
		public InvokedServer.Controls.HexEditor.HexEditor.CaseStyle LineCountCaseStyle
		{
			get => this._lineCountCaseStyle;
			set
			{
				if (this._lineCountCaseStyle == value)
					return;
				this._lineCountCaseStyle = value;
				this._lineCountCaps = this._lineCountCaseStyle != InvokedServer.Controls.HexEditor.HexEditor.CaseStyle.LowerCase ? "X" : "x";
				this.Invalidate();
			}
		}

		[DefaultValue(InvokedServer.Controls.HexEditor.HexEditor.CaseStyle.UpperCase)]
		[Category("Hex")]
		[Description("Property for the case type to use for the hexadecimal values view.")]
		public InvokedServer.Controls.HexEditor.HexEditor.CaseStyle HexViewCaseStyle
		{
			get => this._hexViewCaseStyle;
			set
			{
				if (this._hexViewCaseStyle == value)
					return;
				this._hexViewCaseStyle = value;
				if (this._hexViewCaseStyle == InvokedServer.Controls.HexEditor.HexEditor.CaseStyle.LowerCase)
					this._editView.SetLowerCase();
				else
					this._editView.SetUpperCase();
				this.Invalidate();
			}
		}

		[DefaultValue(false)]
		[Category("Hex")]
		[Description("Property for the visibility of the vertical scrollbar.")]
		public bool VScrollBarVisisble
		{
			get => this._isVScrollVisible;
			set
			{
				if (this._isVScrollVisible == value)
					return;
				this._isVScrollVisible = value;
				this.UpdateRectanglePositioning();
				this.Invalidate();
			}
		}

		[Description("Event that is triggered whenever the hextable has been changed.")]
		public event EventHandler HexTableChanged;

		[Description("Event that is triggered whenever the SelectionStart value is changed.")]
		public event EventHandler SelectionStartChanged;

		[Description("Event that is triggered whenever the SelectionLength value is changed.")]
		public event EventHandler SelectionLengthChanged;

		[Description("Event that is triggered whenever the size of the char is changed.")]
		public event EventHandler CharSizeChanged;

		protected void OnVScrollBarScroll(object sender, ScrollEventArgs e)
		{
			switch (e.Type)
			{
				case ScrollEventType.SmallDecrement:
					this.ScrollLineUp(1);
					break;
				case ScrollEventType.SmallIncrement:
					this.ScrollLineDown(1);
					break;
				case ScrollEventType.LargeDecrement:
					this.ScrollLineUp(this._vScrollLarge);
					break;
				case ScrollEventType.LargeIncrement:
					this.ScrollLineDown(this._vScrollLarge);
					break;
				case ScrollEventType.ThumbTrack:
					this.ScrollThumbTrack(e.NewValue - e.OldValue);
					break;
			}
			this.Invalidate();
		}

		protected void CaretSelectionStartChanged(object sender, EventArgs e)
		{
			if (this.SelectionStartChanged == null)
				return;
			this.SelectionStartChanged((object)this, e);
		}

		protected void CaretSelectionLengthChanged(object sender, EventArgs e)
		{
			if (this.SelectionLengthChanged == null)
				return;
			this.SelectionLengthChanged((object)this, e);
		}

		protected override void OnMarginChanged(EventArgs e)
		{
			base.OnMarginChanged(e);
			this.UpdateRectanglePositioning();
			this.Invalidate();
		}

		protected override void OnGotFocus(EventArgs e)
		{
			if (this._handler != null)
				this._handler.OnGotFocus(e);
			this.UpdateRectanglePositioning();
			this.Invalidate();
			base.OnGotFocus(e);
		}

		protected override void OnLostFocus(EventArgs e)
		{
			this._dragging = false;
			this.DestroyCaret();
			base.OnLostFocus(e);
		}

		protected override bool IsInputKey(Keys keyData)
		{
			switch (keyData)
			{
				case Keys.Left:
				case Keys.Up:
				case Keys.Right:
				case Keys.Down:
				case Keys.Left | Keys.Shift:
				case Keys.Up | Keys.Shift:
				case Keys.Right | Keys.Shift:
				case Keys.Down | Keys.Shift:
					return true;
				default:
					return base.IsInputKey(keyData);
			}
		}

		protected override void OnKeyPress(KeyPressEventArgs e)
		{
			if (this._handler != null)
				this._handler.OnKeyPress(e);
			base.OnKeyPress(e);
		}

		protected override void OnKeyDown(KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Next)
			{
				if (!this._isVScrollHidden)
				{
					this.ScrollLineDown(this._vScrollLarge);
					this.Invalidate();
				}
			}
			else if (e.KeyCode == Keys.Prior)
			{
				if (!this._isVScrollHidden)
				{
					this.ScrollLineUp(this._vScrollLarge);
					this.Invalidate();
				}
			}
			else if (this._handler != null)
				this._handler.OnKeyDown(e);
			base.OnKeyDown(e);
		}

		protected override void OnKeyUp(KeyEventArgs e)
		{
			if (this._handler != null)
				this._handler.OnKeyUp(e);
			base.OnKeyUp(e);
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			if (this.Focused)
			{
				if (this._handler != null)
					this._handler.OnMouseDown(e);
				if (e.Button == MouseButtons.Left)
				{
					this._dragging = true;
					this.Invalidate();
				}
			}
			else
				this.Focus();
			base.OnMouseDown(e);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			if (this.Focused && this._dragging)
			{
				if (this._handler != null)
					this._handler.OnMouseDragged(e);
				this.Invalidate();
			}
			base.OnMouseMove(e);
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			this._dragging = false;
			if (this.Focused && this._handler != null)
				this._handler.OnMouseUp(e);
			base.OnMouseUp(e);
		}

		protected override void OnMouseDoubleClick(MouseEventArgs e)
		{
			if (this.Focused && this._handler != null)
				this._handler.OnMouseDoubleClick(e);
			base.OnMouseDoubleClick(e);
		}

		public int CaretPosX
		{
			get
			{
				lock (this._caretLock)
					return this._caret.Location.X;
			}
		}

		public int CaretPosY
		{
			get
			{
				lock (this._caretLock)
					return this._caret.Location.Y;
			}
		}

		public int SelectionStart
		{
			get
			{
				lock (this._caretLock)
					return this._caret.SelectionStart;
			}
		}

		public int SelectionLength
		{
			get
			{
				lock (this._caretLock)
					return this._caret.SelectionLength;
			}
		}

		public int CaretIndex
		{
			get
			{
				lock (this._caretLock)
					return this._caret.CurrentIndex;
			}
		}

		public bool CaretFocused
		{
			get
			{
				lock (this._caretLock)
					return this._caret.Focused;
			}
		}

		public void SetCaretStart(int index, Point location)
		{
			location = this.ScrollToCaret(index, location);
			lock (this._caretLock)
			{
				this._caret.SetStartIndex(index);
				this._caret.SetCaretLocation(location);
			}
			this.Invalidate();
		}

		public void SetCaretEnd(int index, Point location)
		{
			location = this.ScrollToCaret(index, location);
			lock (this._caretLock)
			{
				this._caret.SetEndIndex(index);
				this._caret.SetCaretLocation(location);
			}
			this.Invalidate();
		}

		public bool IsSelected(int byteIndex)
		{
			lock (this._caretLock)
				return this._caret.IsSelected(byteIndex);
		}

		public void DestroyCaret()
		{
			lock (this._caretLock)
				this._caret.Destroy();
		}

		public int HexTableLength
		{
			get
			{
				lock (this._hexTableLock)
					return this._hexTable.Length;
			}
		}

		public void RemoveSelectedBytes()
		{
			int selectionStart = this.SelectionStart;
			int selectionLength = this.SelectionLength;
			if (selectionLength <= 0)
				return;
			lock (this._hexTableLock)
				this._hexTable.RemoveRange(selectionStart, selectionLength);
			this.UpdateRectanglePositioning();
			this.Invalidate();
			if (this.HexTableChanged == null)
				return;
			this.HexTableChanged((object)this, EventArgs.Empty);
		}

		public void RemoveByteAt(int index)
		{
			lock (this._hexTableLock)
				this._hexTable.RemoveAt(index);
			this.UpdateRectanglePositioning();
			this.Invalidate();
			if (this.HexTableChanged == null)
				return;
			this.HexTableChanged((object)this, EventArgs.Empty);
		}

		public void AppendByte(byte item)
		{
			lock (this._hexTableLock)
				this._hexTable.Add(item);
			this.UpdateRectanglePositioning();
			this.Invalidate();
			if (this.HexTableChanged == null)
				return;
			this.HexTableChanged((object)this, EventArgs.Empty);
		}

		public void InsertByte(int index, byte item)
		{
			lock (this._hexTableLock)
				this._hexTable.Insert(index, item);
			this.UpdateRectanglePositioning();
			this.Invalidate();
			if (this.HexTableChanged == null)
				return;
			this.HexTableChanged((object)this, EventArgs.Empty);
		}

		public char GetByteAsChar(int index)
		{
			lock (this._hexTableLock)
				return this._hexTable.GetCharAt(index);
		}

		public byte GetByte(int index)
		{
			lock (this._hexTableLock)
				return this._hexTable.GetAt(index);
		}

		public void SetByte(int index, byte item)
		{
			lock (this._hexTableLock)
				this._hexTable.SetAt(index, item);
			this.Invalidate();
			if (this.HexTableChanged == null)
				return;
			this.HexTableChanged((object)this, EventArgs.Empty);
		}

		public void ScrollLineUp(int lines)
		{
			if (this._firstByte <= 0)
				return;
			lines = lines > this._vScrollPos ? this._vScrollPos : lines;
			this._vScrollPos -= this._vScrollSmall * lines;
			this.UpdateVisibleByteIndex();
			this.UpdateScrollValues();
			if (!this.CaretFocused)
				return;
			Point start = new Point(this.CaretPosX, this.CaretPosY);
			start.Y += this._recLineCount.Height * lines;
			lock (this._caretLock)
				this._caret.SetCaretLocation(start);
		}

		public void ScrollLineDown(int lines)
		{
			if (this._vScrollPos > this._vScrollMax - this._vScrollLarge)
				return;
			lines = lines + this._vScrollPos > this._vScrollMax - this._vScrollLarge ? this._vScrollMax - this._vScrollLarge - this._vScrollPos + 1 : lines;
			this._vScrollPos += this._vScrollSmall * lines;
			this.UpdateVisibleByteIndex();
			this.UpdateScrollValues();
			if (!this.CaretFocused)
				return;
			Point start = new Point(this.CaretPosX, this.CaretPosY);
			start.Y -= this._recLineCount.Height * lines;
			lock (this._caretLock)
			{
				this._caret.SetCaretLocation(start);
				if (start.Y >= this._recContent.Y)
					return;
				this._caret.Hide(this.Handle);
			}
		}

		public void ScrollThumbTrack(int lines)
		{
			if (lines == 0)
				return;
			if (lines < 0)
				this.ScrollLineUp(-1 * lines);
			else
				this.ScrollLineDown(lines);
		}

		public Point ScrollToCaret(int caretIndex, Point position)
		{
			if (position.Y < 0)
			{
				this._vScrollPos -= Math.Abs((position.Y - this._recContent.Y) / this._recLineCount.Height) * this._vScrollSmall;
				this.UpdateVisibleByteIndex();
				this.UpdateScrollValues();
				if (this.CaretFocused)
					position.Y = this._recContent.Y;
			}
			else if (position.Y > this._maxVisibleBytesV * this._recLineCount.Height)
			{
				this._vScrollPos += (position.Y / this._recLineCount.Height - (this._maxVisibleBytesV - 1)) * this._vScrollSmall;
				if (this._vScrollPos > this._vScrollMax - (this._vScrollLarge - 1))
					this._vScrollPos = this._vScrollMax - (this._vScrollLarge - 1);
				this.UpdateVisibleByteIndex();
				this.UpdateScrollValues();
				if (this.CaretFocused)
					position.Y = (this._maxVisibleBytesV - 1) * this._recLineCount.Height + this._recContent.Y;
			}
			return position;
		}

		private void UpdateRectanglePositioning()
		{
			if (this.ClientRectangle.Width == 0)
				return;
			SizeF sizeF;
			using (Graphics graphics = this.CreateGraphics())
				sizeF = graphics.MeasureString("D", this.Font, 100, this._stringFormat);
			this.CharSize = new SizeF((float)Math.Ceiling((double)sizeF.Width), (float)Math.Ceiling((double)sizeF.Height));
			this._recContent = this.ClientRectangle;
			ref Rectangle local1 = ref this._recContent;
			int x = local1.X;
			Padding margin = this.Margin;
			int left1 = margin.Left;
			local1.X = x + left1;
			ref Rectangle local2 = ref this._recContent;
			int y1 = local2.Y;
			margin = this.Margin;
			int top1 = margin.Top;
			local2.Y = y1 + top1;
			ref Rectangle local3 = ref this._recContent;
			int width = local3.Width;
			margin = this.Margin;
			int right = margin.Right;
			local3.Width = width - right;
			ref Rectangle local4 = ref this._recContent;
			int height = local4.Height;
			margin = this.Margin;
			int bottom = margin.Bottom;
			local4.Height = height - bottom;
			if (this.BorderStyle == BorderStyle.Fixed3D)
			{
				this._recContent.X += 2;
				this._recContent.Y += 2;
				--this._recContent.Width;
				--this._recContent.Height;
			}
			else if (this.BorderStyle == BorderStyle.FixedSingle)
			{
				++this._recContent.X;
				++this._recContent.Y;
				--this._recContent.Width;
				--this._recContent.Height;
			}
			if (!this.VScrollBarHidden)
			{
				this._recContent.Width -= this._vScrollBarWidth;
				VScrollBar vScrollBar1 = this._vScrollBar;
				int num1 = this._recContent.X + this._recContent.Width;
				margin = this.Margin;
				int left2 = margin.Left;
				int num2 = num1 - left2;
				vScrollBar1.Left = num2;
				VScrollBar vScrollBar2 = this._vScrollBar;
				int y2 = this._recContent.Y;
				margin = this.Margin;
				int top2 = margin.Top;
				int num3 = y2 - top2;
				vScrollBar2.Top = num3;
				this._vScrollBar.Width = this._vScrollBarWidth;
				this._vScrollBar.Height = this._recContent.Height;
			}
			this._recLineCount = new Rectangle(this._recContent.X, this._recContent.Y, (int)((double)this._charSize.Width * 4.0), (int)this._charSize.Height - 2);
			this._editView.Update(this._recLineCount.X + this._recLineCount.Width + this._entityMargin / 2, this._recContent);
			this._maxBytesH = this._bytesPerLine;
			this._maxBytesV = (int)Math.Ceiling((double)this._recContent.Height / (double)this._recLineCount.Height);
			this._maxBytes = this._maxBytesH * this._maxBytesV;
			this._maxVisibleBytesV = (int)Math.Floor((double)this._recContent.Height / (double)this._recLineCount.Height);
			this.UpdateScrollBarSize();
		}

		private void UpdateVisibleByteIndex()
		{
			if (this._hexTable.Length == 0)
			{
				this._firstByte = 0;
				this._lastByte = 0;
			}
			else
			{
				this._firstByte = this._vScrollPos * this._maxBytesH;
				this._lastByte = Math.Min(this.HexTableLength, this._firstByte + this._maxBytes);
			}
		}

		private void UpdateScrollValues()
		{
			if (!this._isVScrollHidden)
			{
				this._vScrollBar.Minimum = this._vScrollMin;
				this._vScrollBar.Maximum = this._vScrollMax;
				this._vScrollBar.Value = this._vScrollPos;
				this._vScrollBar.SmallChange = this._vScrollSmall;
				this._vScrollBar.LargeChange = this._vScrollLarge;
				this._vScrollBar.Visible = true;
			}
			else
				this._vScrollBar.Visible = false;
		}

		private void UpdateScrollBarSize()
		{
			if (this.VScrollBarVisisble && this._maxVisibleBytesV > 0 && this._maxBytesH > 0)
			{
				int maxVisibleBytesV = this._maxVisibleBytesV;
				int num1 = 1;
				int num2 = 0;
				int num3 = this.HexTableLength / this._maxBytesH;
				int num4 = this._firstByte / this._maxBytesH;
				if (maxVisibleBytesV != this._vScrollLarge || num1 != this._vScrollSmall)
				{
					this._vScrollLarge = maxVisibleBytesV;
					this._vScrollSmall = num1;
				}
				if (num3 >= maxVisibleBytesV)
				{
					if (num3 != this._vScrollMax || num4 != this._vScrollPos)
					{
						this._vScrollMin = num2;
						this._vScrollMax = num3;
						this._vScrollPos = num4;
					}
					this.VScrollBarHidden = false;
					this.UpdateScrollValues();
				}
				else
					this.VScrollBarHidden = true;
			}
			else
				this.VScrollBarHidden = true;
		}

		public HexEditor()
		  : this(new ByteCollection())
		{
		}

		public HexEditor(ByteCollection collection)
		{
			this._stringFormat = new StringFormat(StringFormat.GenericTypographic);
			this._stringFormat.Alignment = StringAlignment.Center;
			this._stringFormat.LineAlignment = StringAlignment.Center;
			this._hexTable = collection;
			this._vScrollBar = new VScrollBar();
			this._vScrollBar.Scroll += new ScrollEventHandler(this.OnVScrollBarScroll);
			this.SetStyle(ControlStyles.ResizeRedraw, true);
			this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
			this.SetStyle(ControlStyles.Selectable, true);
			this._caret = new Caret(this);
			this._caret.SelectionStartChanged += new EventHandler(this.CaretSelectionStartChanged);
			this._caret.SelectionLengthChanged += new EventHandler(this.CaretSelectionLengthChanged);
			this._editView = new EditView(this);
			this._handler = (IKeyMouseEventHandler)this._editView;
			this.Cursor = Cursors.IBeam;
		}

		private RectangleF GetLineCountBound(int index)
		{
			return new RectangleF((float)this._recLineCount.X, (float)(this._recLineCount.Y + this._recLineCount.Height * index), (float)this._recLineCount.Width, (float)this._recLineCount.Height);
		}

		protected override void OnPaintBackground(PaintEventArgs pevent)
		{
			if (this.BorderStyle == BorderStyle.Fixed3D)
			{
				SolidBrush solidBrush = new SolidBrush(this.BackColor);
				Rectangle clientRectangle = this.ClientRectangle;
				pevent.Graphics.FillRectangle((Brush)solidBrush, clientRectangle);
				ControlPaint.DrawBorder3D(pevent.Graphics, this.ClientRectangle, Border3DStyle.Sunken);
			}
			else if (this.BorderStyle == BorderStyle.FixedSingle)
			{
				SolidBrush solidBrush = new SolidBrush(this.BackColor);
				Rectangle clientRectangle = this.ClientRectangle;
				pevent.Graphics.FillRectangle((Brush)solidBrush, clientRectangle);
				ControlPaint.DrawBorder(pevent.Graphics, this.ClientRectangle, this.BorderColor, ButtonBorderStyle.Solid);
			}
			else
				base.OnPaintBackground(pevent);
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);
			Region region = new Region(this.ClientRectangle);
			region.Exclude(this._recContent);
			e.Graphics.ExcludeClip(region);
			this.UpdateVisibleByteIndex();
			this.PaintLineCount(e.Graphics, this._firstByte, this._lastByte);
			this._editView.Paint(e.Graphics, this._firstByte, this._lastByte);
		}

		private void PaintLineCount(Graphics g, int startIndex, int lastIndex)
		{
			SolidBrush solidBrush = new SolidBrush(this.ForeColor);
			for (int index = 0; index * this._maxBytesH + startIndex <= lastIndex; ++index)
			{
				RectangleF lineCountBound = this.GetLineCountBound(index);
				string str = (startIndex + index * this._maxBytesH).ToString(this._lineCountCaps);
				int count = this._nrCharsLineCount - str.Length;
				string s = count <= -1 ? new string('~', this._nrCharsLineCount) : new string('0', count) + str;
				g.DrawString(s, this.Font, (Brush)solidBrush, lineCountBound, this._stringFormat);
			}
		}

		protected override void OnResize(EventArgs e)
		{
			base.OnResize(e);
			this.UpdateRectanglePositioning();
			this.Invalidate();
		}

		public enum CaseStyle
		{
			LowerCase,
			UpperCase,
		}
	}
}