﻿// Decompiled with JetBrains decompiler
// Type: InvokedServer.Controls.HexEditor.StringViewHandler
// 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.Drawing;
using System.Windows.Forms;


namespace InvokedServer.Controls.HexEditor
{
	public class StringViewHandler
	{
		private Rectangle _recStringView;
		private StringFormat _stringFormat;
		private InvokedServer.Controls.HexEditor.HexEditor _editor;

		public int MaxWidth => this._recStringView.X + this._recStringView.Width;

		public StringViewHandler(InvokedServer.Controls.HexEditor.HexEditor editor)
		{
			this._editor = editor;
			this._stringFormat = new StringFormat(StringFormat.GenericTypographic);
			this._stringFormat.Alignment = StringAlignment.Center;
			this._stringFormat.LineAlignment = StringAlignment.Center;
		}

		public void OnKeyPress(KeyPressEventArgs e)
		{
			if (char.IsControl(e.KeyChar))
				return;
			this.HandleUserInput(e.KeyChar);
		}

		public void OnKeyDown(KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back)
			{
				if (this._editor.SelectionLength > 0)
				{
					this.HandleUserRemove();
					int caretIndex = this._editor.CaretIndex;
					Point caretLocation = this.GetCaretLocation(caretIndex);
					this._editor.SetCaretStart(caretIndex, caretLocation);
				}
				else if (this._editor.CaretIndex < this._editor.LastVisibleByte && e.KeyCode == Keys.Delete)
				{
					this._editor.RemoveByteAt(this._editor.CaretIndex);
					this._editor.SetCaretStart(this._editor.CaretIndex, this.GetCaretLocation(this._editor.CaretIndex));
				}
				else
				{
					if (this._editor.CaretIndex <= 0 || e.KeyCode != Keys.Back)
						return;
					int index = this._editor.CaretIndex - 1;
					this._editor.RemoveByteAt(index);
					Point caretLocation = this.GetCaretLocation(index);
					this._editor.SetCaretStart(index, caretLocation);
				}
			}
			else if (e.KeyCode == Keys.Up && this._editor.CaretIndex - this._editor.BytesPerLine >= 0)
			{
				int index = this._editor.CaretIndex - this._editor.BytesPerLine;
				if (index % this._editor.BytesPerLine == 0 && this._editor.CaretPosX >= this._recStringView.X + this._recStringView.Width)
				{
					Point location = new Point(this._editor.CaretPosX, this._editor.CaretPosY - this._recStringView.Height);
					if (index == 0)
					{
						location = new Point(this._editor.CaretPosX, this._editor.CaretPosY);
						index = this._editor.BytesPerLine;
					}
					if (e.Shift)
						this._editor.SetCaretEnd(index, location);
					else
						this._editor.SetCaretStart(index, location);
				}
				else
					this.HandleArrowKeys(index, e.Shift);
			}
			else if (e.KeyCode == Keys.Down && (this._editor.CaretIndex - 1) / this._editor.BytesPerLine < this._editor.HexTableLength / this._editor.BytesPerLine)
			{
				int index = this._editor.CaretIndex + this._editor.BytesPerLine;
				if (index > this._editor.HexTableLength)
				{
					this.HandleArrowKeys(this._editor.HexTableLength, e.Shift);
				}
				else
				{
					Point location = new Point(this._editor.CaretPosX, this._editor.CaretPosY + this._recStringView.Height);
					if (e.Shift)
						this._editor.SetCaretEnd(index, location);
					else
						this._editor.SetCaretStart(index, location);
				}
			}
			else if (e.KeyCode == Keys.Left && this._editor.CaretIndex - 1 >= 0)
			{
				this.HandleArrowKeys(this._editor.CaretIndex - 1, e.Shift);
			}
			else
			{
				if (e.KeyCode != Keys.Right || this._editor.CaretIndex + 1 > this._editor.LastVisibleByte)
					return;
				this.HandleArrowKeys(this._editor.CaretIndex + 1, e.Shift);
			}
		}

		public void HandleArrowKeys(int index, bool isShiftDown)
		{
			Point caretLocation = this.GetCaretLocation(index);
			if (isShiftDown)
				this._editor.SetCaretEnd(index, caretLocation);
			else
				this._editor.SetCaretStart(index, caretLocation);
		}

		public void OnMouseDown(int x, int y)
		{
			int num1 = (x - this._recStringView.X) / (int)this._editor.CharSize.Width;
			int num2 = (y - this._recStringView.Y) / this._recStringView.Height;
			int num3 = num1 > this._editor.BytesPerLine ? this._editor.BytesPerLine : num1;
			int num4 = num3 < 0 ? 0 : num3;
			int num5 = num2 > this._editor.MaxBytesV ? this._editor.MaxBytesV : num2;
			int num6 = num5 < 0 ? 0 : num5;
			if ((this._editor.LastVisibleByte - this._editor.FirstVisibleByte) / this._editor.BytesPerLine <= num6)
			{
				if ((this._editor.LastVisibleByte - this._editor.FirstVisibleByte) % this._editor.BytesPerLine <= num4)
					num4 = (this._editor.LastVisibleByte - this._editor.FirstVisibleByte) % this._editor.BytesPerLine;
				num6 = (this._editor.LastVisibleByte - this._editor.FirstVisibleByte) / this._editor.BytesPerLine;
			}
			this._editor.SetCaretStart(Math.Min(this._editor.LastVisibleByte, this._editor.FirstVisibleByte + num4 + num6 * this._editor.BytesPerLine), new Point(num4 * (int)this._editor.CharSize.Width + this._recStringView.X, num6 * this._recStringView.Height + this._recStringView.Y));
		}

		public void OnMouseDragged(int x, int y)
		{
			int num1 = (x - this._recStringView.X) / (int)this._editor.CharSize.Width;
			int num2 = (y - this._recStringView.Y) / this._recStringView.Height;
			int num3 = num1 > this._editor.BytesPerLine ? this._editor.BytesPerLine : num1;
			int num4 = num3 < 0 ? 0 : num3;
			int num5 = num2 > this._editor.MaxBytesV ? this._editor.MaxBytesV : num2;
			int num6 = this._editor.FirstVisibleByte <= 0 ? (num5 < 0 ? 0 : num5) : (num5 < 0 ? -1 : num5);
			if ((this._editor.LastVisibleByte - this._editor.FirstVisibleByte) / this._editor.BytesPerLine <= num6)
			{
				if ((this._editor.LastVisibleByte - this._editor.FirstVisibleByte) % this._editor.BytesPerLine <= num4)
					num4 = (this._editor.LastVisibleByte - this._editor.FirstVisibleByte) % this._editor.BytesPerLine;
				num6 = (this._editor.LastVisibleByte - this._editor.FirstVisibleByte) / this._editor.BytesPerLine;
			}
			this._editor.SetCaretEnd(Math.Min(this._editor.LastVisibleByte, this._editor.FirstVisibleByte + num4 + num6 * this._editor.BytesPerLine), new Point(num4 * (int)this._editor.CharSize.Width + this._recStringView.X, num6 * this._recStringView.Height + this._recStringView.Y));
		}

		public void OnMouseDoubleClick()
		{
			if (this._editor.CaretIndex >= this._editor.LastVisibleByte)
				return;
			int index = this._editor.CaretIndex + 1;
			Point caretLocation = this.GetCaretLocation(index);
			this._editor.SetCaretEnd(index, caretLocation);
		}

		public void Focus()
		{
			int caretIndex = this._editor.CaretIndex;
			Point caretLocation = this.GetCaretLocation(caretIndex);
			this._editor.SetCaretStart(caretIndex, caretLocation);
		}

		public void Update(int startPositionX, Rectangle area)
		{
			int x = startPositionX;
			int y = area.Y;
			SizeF charSize = this._editor.CharSize;
			int width = (int)((double)charSize.Width * (double)this._editor.BytesPerLine);
			charSize = this._editor.CharSize;
			int height = (int)charSize.Height - 2;
			this._recStringView = new Rectangle(x, y, width, height);
			this._recStringView.X += this._editor.EntityMargin;
		}

		public void Paint(Graphics g, int index, int startIndex)
		{
			Point byteColumnAndRow = this.GetByteColumnAndRow(index);
			if (this._editor.IsSelected(index + startIndex))
				this.PaintByteAsSelected(g, byteColumnAndRow, index + startIndex);
			else
				this.PaintByte(g, byteColumnAndRow, index + startIndex);
		}

		private void PaintByteAsSelected(Graphics g, Point point, int index)
		{
			SolidBrush solidBrush1 = new SolidBrush(this._editor.SelectionBackColor);
			SolidBrush solidBrush2 = new SolidBrush(this._editor.SelectionForeColor);
			RectangleF bound = this.GetBound(point);
			char byteAsChar = this._editor.GetByteAsChar(index);
			string s = char.IsControl(byteAsChar) ? "." : byteAsChar.ToString();
			g.FillRectangle((Brush)solidBrush1, bound);
			g.DrawString(s, this._editor.Font, (Brush)solidBrush2, bound, this._stringFormat);
		}

		private void PaintByte(Graphics g, Point point, int index)
		{
			SolidBrush solidBrush = new SolidBrush(this._editor.ForeColor);
			RectangleF bound = this.GetBound(point);
			char byteAsChar = this._editor.GetByteAsChar(index);
			string s = char.IsControl(byteAsChar) ? "." : byteAsChar.ToString();
			g.DrawString(s, this._editor.Font, (Brush)solidBrush, bound, this._stringFormat);
		}

		private Point GetCaretLocation(int index)
		{
			return new Point(this._recStringView.X + (int)this._editor.CharSize.Width * (index % this._editor.BytesPerLine), this._recStringView.Y + this._recStringView.Height * ((index - (this._editor.FirstVisibleByte + index % this._editor.BytesPerLine)) / this._editor.BytesPerLine));
		}

		private void HandleUserRemove()
		{
			int selectionStart = this._editor.SelectionStart;
			Point caretLocation = this.GetCaretLocation(selectionStart);
			this._editor.RemoveSelectedBytes();
			this._editor.SetCaretStart(selectionStart, caretLocation);
		}

		private void HandleUserInput(char key)
		{
			if (!this._editor.CaretFocused)
				return;
			this.HandleUserRemove();
			byte num = Convert.ToByte(key);
			if (this._editor.HexTableLength <= 0)
				this._editor.AppendByte(num);
			else
				this._editor.InsertByte(this._editor.CaretIndex, num);
			int index = this._editor.CaretIndex + 1;
			Point caretLocation = this.GetCaretLocation(index);
			this._editor.SetCaretStart(index, caretLocation);
		}

		private Point GetByteColumnAndRow(int index)
		{
			return new Point(index % this._editor.BytesPerLine, index / this._editor.BytesPerLine);
		}

		private RectangleF GetBound(Point point)
		{
			return new RectangleF((float)(this._recStringView.X + point.X * (int)this._editor.CharSize.Width), (float)(this._recStringView.Y + point.Y * this._recStringView.Height), this._editor.CharSize.Width, (float)this._recStringView.Height);
		}
	}
}