namespace InControl
{
	using UnityEngine;


	public struct KeyInfo
	{
		readonly Key key;
		readonly string name;
		readonly string macName;
		readonly KeyCode[] keyCodes;


		KeyInfo( Key key, string name, params KeyCode[] keyCodes )
		{
			this.key = key;
			this.name = name;
			this.macName = name;
			this.keyCodes = keyCodes;
		}


		KeyInfo( Key key, string name, string macName, params KeyCode[] keyCodes )
		{
			this.key = key;
			this.name = name;
			this.macName = macName;
			this.keyCodes = keyCodes;
		}


		public bool IsPressed
		{
			get
			{
				var keyCodeCount = keyCodes.Length;
				for (var i = 0; i < keyCodeCount; i++)
				{
					if (Input.GetKey( keyCodes[i] ))
					{
						return true;
					}
				}

				return false;
			}
		}


		public string Name
		{
			get
			{
				if (Application.platform == RuntimePlatform.OSXEditor ||
				    Application.platform == RuntimePlatform.OSXPlayer
#if !UNITY_5_4_OR_NEWER
					|| Application.platform == RuntimePlatform.OSXWebPlayer
#endif
				)
				{
					return macName;
				}
				else
				{
					return name;
				}
			}
		}


		public Key Key
		{
			get
			{
				return key;
			}
		}


		public static readonly KeyInfo[] KeyList =
		{
			new KeyInfo( Key.None, "None", KeyCode.None ),

			new KeyInfo( Key.Shift, "Shift", KeyCode.LeftShift, KeyCode.RightShift ),
			new KeyInfo( Key.Alt, "Alt", "Option", KeyCode.LeftAlt, KeyCode.RightAlt ),
			new KeyInfo( Key.Command, "Command", KeyCode.LeftCommand, KeyCode.RightCommand ),
			new KeyInfo( Key.Control, "Control", KeyCode.LeftControl, KeyCode.RightControl ),

			new KeyInfo( Key.LeftShift, "Left Shift", KeyCode.LeftShift ),
			new KeyInfo( Key.LeftAlt, "Left Alt", "Left Option", KeyCode.LeftAlt ),
			new KeyInfo( Key.LeftCommand, "Left Command", KeyCode.LeftCommand ),
			new KeyInfo( Key.LeftControl, "Left Control", KeyCode.LeftControl ),

			new KeyInfo( Key.RightShift, "Right Shift", KeyCode.RightShift ),
			new KeyInfo( Key.RightAlt, "Right Alt", "Right Option", KeyCode.RightAlt ),
			new KeyInfo( Key.RightCommand, "Right Command", KeyCode.RightCommand ),
			new KeyInfo( Key.RightControl, "Right Control", KeyCode.RightControl ),

			new KeyInfo( Key.Escape, "Escape", KeyCode.Escape ),
			new KeyInfo( Key.F1, "F1", KeyCode.F1 ),
			new KeyInfo( Key.F2, "F2", KeyCode.F2 ),
			new KeyInfo( Key.F3, "F3", KeyCode.F3 ),
			new KeyInfo( Key.F4, "F4", KeyCode.F4 ),
			new KeyInfo( Key.F5, "F5", KeyCode.F5 ),
			new KeyInfo( Key.F6, "F6", KeyCode.F6 ),
			new KeyInfo( Key.F7, "F7", KeyCode.F7 ),
			new KeyInfo( Key.F8, "F8", KeyCode.F8 ),
			new KeyInfo( Key.F9, "F9", KeyCode.F9 ),
			new KeyInfo( Key.F10, "F10", KeyCode.F10 ),
			new KeyInfo( Key.F11, "F11", KeyCode.F11 ),
			new KeyInfo( Key.F12, "F12", KeyCode.F12 ),

			new KeyInfo( Key.Key0, "Num 0", KeyCode.Alpha0 ),
			new KeyInfo( Key.Key1, "Num 1", KeyCode.Alpha1 ),
			new KeyInfo( Key.Key2, "Num 2", KeyCode.Alpha2 ),
			new KeyInfo( Key.Key3, "Num 3", KeyCode.Alpha3 ),
			new KeyInfo( Key.Key4, "Num 4", KeyCode.Alpha4 ),
			new KeyInfo( Key.Key5, "Num 5", KeyCode.Alpha5 ),
			new KeyInfo( Key.Key6, "Num 6", KeyCode.Alpha6 ),
			new KeyInfo( Key.Key7, "Num 7", KeyCode.Alpha7 ),
			new KeyInfo( Key.Key8, "Num 8", KeyCode.Alpha8 ),
			new KeyInfo( Key.Key9, "Num 9", KeyCode.Alpha9 ),

			new KeyInfo( Key.A, "A", KeyCode.A ),
			new KeyInfo( Key.B, "B", KeyCode.B ),
			new KeyInfo( Key.C, "C", KeyCode.C ),
			new KeyInfo( Key.D, "D", KeyCode.D ),
			new KeyInfo( Key.E, "E", KeyCode.E ),
			new KeyInfo( Key.F, "F", KeyCode.F ),
			new KeyInfo( Key.G, "G", KeyCode.G ),
			new KeyInfo( Key.H, "H", KeyCode.H ),
			new KeyInfo( Key.I, "I", KeyCode.I ),
			new KeyInfo( Key.J, "J", KeyCode.J ),
			new KeyInfo( Key.K, "K", KeyCode.K ),
			new KeyInfo( Key.L, "L", KeyCode.L ),
			new KeyInfo( Key.M, "M", KeyCode.M ),
			new KeyInfo( Key.N, "N", KeyCode.N ),
			new KeyInfo( Key.O, "O", KeyCode.O ),
			new KeyInfo( Key.P, "P", KeyCode.P ),
			new KeyInfo( Key.Q, "Q", KeyCode.Q ),
			new KeyInfo( Key.R, "R", KeyCode.R ),
			new KeyInfo( Key.S, "S", KeyCode.S ),
			new KeyInfo( Key.T, "T", KeyCode.T ),
			new KeyInfo( Key.U, "U", KeyCode.U ),
			new KeyInfo( Key.V, "V", KeyCode.V ),
			new KeyInfo( Key.W, "W", KeyCode.W ),
			new KeyInfo( Key.X, "X", KeyCode.X ),
			new KeyInfo( Key.Y, "Y", KeyCode.Y ),
			new KeyInfo( Key.Z, "Z", KeyCode.Z ),

			new KeyInfo( Key.Backquote, "Backquote", KeyCode.BackQuote ),
			new KeyInfo( Key.Minus, "Minus", KeyCode.Minus ),
			new KeyInfo( Key.Equals, "Equals", KeyCode.Equals ),
			new KeyInfo( Key.Backspace, "Backspace", "Delete", KeyCode.Backspace ),

			new KeyInfo( Key.Tab, "Tab", KeyCode.Tab ),
			new KeyInfo( Key.LeftBracket, "Left Bracket", KeyCode.LeftBracket ),
			new KeyInfo( Key.RightBracket, "Right Bracket", KeyCode.RightBracket ),
			new KeyInfo( Key.Backslash, "Backslash", KeyCode.Backslash ),

			new KeyInfo( Key.Semicolon, "Semicolon", KeyCode.Semicolon ),
			new KeyInfo( Key.Quote, "Quote", KeyCode.Quote ),
			new KeyInfo( Key.Return, "Return", KeyCode.Return ),

			new KeyInfo( Key.Comma, "Comma", KeyCode.Comma ),
			new KeyInfo( Key.Period, "Period", KeyCode.Period ),
			new KeyInfo( Key.Slash, "Slash", KeyCode.Slash ),

			new KeyInfo( Key.Space, "Space", KeyCode.Space ),

			new KeyInfo( Key.Insert, "Insert", KeyCode.Insert ),
			new KeyInfo( Key.Delete, "Delete", "Forward Delete", KeyCode.Delete ),
			new KeyInfo( Key.Home, "Home", KeyCode.Home ),
			new KeyInfo( Key.End, "End", KeyCode.End ),
			new KeyInfo( Key.PageUp, "PageUp", KeyCode.PageUp ),
			new KeyInfo( Key.PageDown, "PageDown", KeyCode.PageDown ),

			new KeyInfo( Key.LeftArrow, "Left Arrow", KeyCode.LeftArrow ),
			new KeyInfo( Key.RightArrow, "Right Arrow", KeyCode.RightArrow ),
			new KeyInfo( Key.UpArrow, "Up Arrow", KeyCode.UpArrow ),
			new KeyInfo( Key.DownArrow, "Down Arrow", KeyCode.DownArrow ),

			new KeyInfo( Key.Pad0, "Pad 0", KeyCode.Keypad0 ),
			new KeyInfo( Key.Pad1, "Pad 1", KeyCode.Keypad1 ),
			new KeyInfo( Key.Pad2, "Pad 2", KeyCode.Keypad2 ),
			new KeyInfo( Key.Pad3, "Pad 3", KeyCode.Keypad3 ),
			new KeyInfo( Key.Pad4, "Pad 4", KeyCode.Keypad4 ),
			new KeyInfo( Key.Pad5, "Pad 5", KeyCode.Keypad5 ),
			new KeyInfo( Key.Pad6, "Pad 6", KeyCode.Keypad6 ),
			new KeyInfo( Key.Pad7, "Pad 7", KeyCode.Keypad7 ),
			new KeyInfo( Key.Pad8, "Pad 8", KeyCode.Keypad8 ),
			new KeyInfo( Key.Pad9, "Pad 9", KeyCode.Keypad9 ),

			new KeyInfo( Key.Numlock, "Numlock", KeyCode.Numlock ),
			new KeyInfo( Key.PadDivide, "Pad Divide", KeyCode.KeypadDivide ),
			new KeyInfo( Key.PadMultiply, "Pad Multiply", KeyCode.KeypadMultiply ),
			new KeyInfo( Key.PadMinus, "Pad Minus", KeyCode.KeypadMinus ),
			new KeyInfo( Key.PadPlus, "Pad Plus", KeyCode.KeypadPlus ),
			new KeyInfo( Key.PadEnter, "Pad Enter", KeyCode.KeypadEnter ),
			new KeyInfo( Key.PadPeriod, "Pad Period", KeyCode.KeypadPeriod ),

			// Mac only?
			new KeyInfo( Key.Clear, "Clear", KeyCode.Clear ),
			new KeyInfo( Key.PadEquals, "Pad Equals", KeyCode.KeypadEquals ),
			new KeyInfo( Key.F13, "F13", KeyCode.F13 ),
			new KeyInfo( Key.F14, "F14", KeyCode.F14 ),
			new KeyInfo( Key.F15, "F15", KeyCode.F15 ),

			// Other
			new KeyInfo( Key.AltGr, "Alt Graphic", KeyCode.AltGr ),
			new KeyInfo( Key.CapsLock, "Caps Lock", KeyCode.CapsLock ),

			// Shifted / non-US keyboard keys.
			new KeyInfo( Key.ExclamationMark, "Exclamation", KeyCode.Exclaim ),
			new KeyInfo( Key.At, "At", KeyCode.At ),
			new KeyInfo( Key.Hash, "Hash", KeyCode.Hash ),
			new KeyInfo( Key.Dollar, "Dollar", KeyCode.Dollar ),
			new KeyInfo( Key.Caret, "Caret", KeyCode.Caret ),
			new KeyInfo( Key.Ampersand, "Ampersand", KeyCode.Ampersand ),
			new KeyInfo( Key.Asterisk, "Asterisk", KeyCode.Asterisk ),
			new KeyInfo( Key.LeftParen, "Left Paren", KeyCode.LeftParen ),
			new KeyInfo( Key.RightParen, "Right Paren", KeyCode.RightParen ),
			new KeyInfo( Key.Underscore, "Underscore", KeyCode.Underscore ),
			new KeyInfo( Key.Plus, "Plus", KeyCode.Plus ),
			new KeyInfo( Key.Colon, "Colon", KeyCode.Colon ),
			new KeyInfo( Key.DoubleQuote, "Double Quote", KeyCode.DoubleQuote ),
			new KeyInfo( Key.LessThan, "Less Than", KeyCode.Less ),
			new KeyInfo( Key.GreaterThan, "Greater Than", KeyCode.Greater ),
			new KeyInfo( Key.QuestionMark, "Question Mark", KeyCode.Question ),

#if UNITY_2018_3_OR_NEWER
			new KeyInfo( Key.Percent, "Percent", KeyCode.Percent ),
			new KeyInfo( Key.Tilde, "Tilde", KeyCode.Tilde ),
			new KeyInfo( Key.LeftBrace, "LeftBrace", KeyCode.LeftCurlyBracket ),
			new KeyInfo( Key.RightBrace, "RightBrace", KeyCode.RightCurlyBracket ),
			new KeyInfo( Key.Pipe, "Pipe", KeyCode.Pipe ),
#endif

			// Unity doesn't define/support these :(
			// new KeyInfo( Key.F16, "F16", KeyCode.F16 ),
			// new KeyInfo( Key.F17, "F17", KeyCode.F17 ),
			// new KeyInfo( Key.F18, "F18", KeyCode.F18 ),
			// new KeyInfo( Key.F19, "F19", KeyCode.F19 ),
		};
	}
}
