using System;

namespace SharpQuake
{
	internal class KeysMenu : MenuBase
	{
		public override void Show()
		{
			base.Show();
		}

		public override void KeyEvent(int key)
		{
			if (this._BindGrab)
			{
				snd.LocalSound("misc/menu1.wav");
				if (key == 27)
				{
					this._BindGrab = false;
				}
				else if (key != 96)
				{
					Cbuf.InsertText(string.Format("bind \"{0}\" \"{1}\"\n", Key.KeynumToString(key), SharpQuake.KeysMenu._BindNames[this._Cursor][0]));
				}
				this._BindGrab = false;
				return;
			}
			if (key > 27)
			{
				switch (key)
				{
				case 127:
					break;
				case 128:
				case 130:
					snd.LocalSound("misc/menu1.wav");
					this._Cursor--;
					if (this._Cursor < 0)
					{
						this._Cursor = SharpQuake.KeysMenu._BindNames.Length - 1;
						return;
					}
					return;
				case 129:
				case 131:
					snd.LocalSound("misc/menu1.wav");
					this._Cursor++;
					if (this._Cursor >= SharpQuake.KeysMenu._BindNames.Length)
					{
						this._Cursor = 0;
						return;
					}
					return;
				default:
					if (key != 148)
					{
						return;
					}
					break;
				}
				snd.LocalSound("misc/menu2.wav");
				this.UnbindCommand(SharpQuake.KeysMenu._BindNames[this._Cursor][0]);
				return;
			}
			if (key == 13)
			{
				int[] array = new int[2];
				this.FindKeysForCommand(SharpQuake.KeysMenu._BindNames[this._Cursor][0], array);
				snd.LocalSound("misc/menu2.wav");
				if (array[1] != -1)
				{
					this.UnbindCommand(SharpQuake.KeysMenu._BindNames[this._Cursor][0]);
				}
				this._BindGrab = true;
				return;
			}
			if (key != 27)
			{
				return;
			}
			MenuBase.OptionsMenu.Show();
		}

		public override void Draw()
		{
			glpic_t glpic_t = Drawer.CachePic("gfx/ttl_cstm.lmp");
			menu.DrawPic((320 - glpic_t.width) / 2, 4, glpic_t);
			if (this._BindGrab)
			{
				menu.Print(12, 32, "Press a key or button for this action");
			}
			else
			{
				menu.Print(18, 32, "Enter to change, backspace to clear");
			}
			int[] array = new int[2];
			for (int i = 0; i < SharpQuake.KeysMenu._BindNames.Length; i++)
			{
				int cy = 48 + 8 * i;
				menu.Print(16, cy, SharpQuake.KeysMenu._BindNames[i][1]);
				this.FindKeysForCommand(SharpQuake.KeysMenu._BindNames[i][0], array);
				if (array[0] == -1)
				{
					menu.Print(140, cy, "???");
				}
				else
				{
					string text = Key.KeynumToString(array[0]);
					menu.Print(140, cy, text);
					int num = text.Length * 8;
					if (array[1] != -1)
					{
						menu.Print(140 + num + 8, cy, "or");
						menu.Print(140 + num + 32, cy, Key.KeynumToString(array[1]));
					}
				}
			}
			if (this._BindGrab)
			{
				menu.DrawCharacter(130, 48 + this._Cursor * 8, 61);
				return;
			}
			menu.DrawCharacter(130, 48 + this._Cursor * 8, 12 + ((int)(host.RealTime * 4.0) & 1));
		}

		private void FindKeysForCommand(string command, int[] twokeys)
		{
			twokeys[0] = (twokeys[1] = -1);
			int length = command.Length;
			int num = 0;
			for (int i = 0; i < 256; i++)
			{
				string text = Key.Bindings[i];
				if (!string.IsNullOrEmpty(text) && string.Compare(text, 0, command, 0, length) == 0)
				{
					twokeys[num] = i;
					num++;
					if (num == 2)
					{
						break;
					}
				}
			}
		}

		private void UnbindCommand(string command)
		{
			int length = command.Length;
			for (int i = 0; i < 256; i++)
			{
				string text = Key.Bindings[i];
				if (!string.IsNullOrEmpty(text) && string.Compare(text, 0, command, 0, length) == 0)
				{
					Key.SetBinding(i, string.Empty);
				}
			}
		}

		private static readonly string[][] _BindNames = new string[][]
		{
			new string[]
			{
				"+attack",
				"attack"
			},
			new string[]
			{
				"impulse 10",
				"change weapon"
			},
			new string[]
			{
				"+jump",
				"jump / swim up"
			},
			new string[]
			{
				"+forward",
				"walk forward"
			},
			new string[]
			{
				"+back",
				"backpedal"
			},
			new string[]
			{
				"+left",
				"turn left"
			},
			new string[]
			{
				"+right",
				"turn right"
			},
			new string[]
			{
				"+speed",
				"run"
			},
			new string[]
			{
				"+moveleft",
				"step left"
			},
			new string[]
			{
				"+moveright",
				"step right"
			},
			new string[]
			{
				"+strafe",
				"sidestep"
			},
			new string[]
			{
				"+lookup",
				"look up"
			},
			new string[]
			{
				"+lookdown",
				"look down"
			},
			new string[]
			{
				"centerview",
				"center view"
			},
			new string[]
			{
				"+mlook",
				"mouse look"
			},
			new string[]
			{
				"+klook",
				"keyboard look"
			},
			new string[]
			{
				"+moveup",
				"swim up"
			},
			new string[]
			{
				"+movedown",
				"swim down"
			}
		};

		private bool _BindGrab;
	}
}
