using System.IO; using System.Text; using System; using System.Collections.Generic; using System.Linq; namespace LanguageGenerator { public enum CIRCLESECTION { Right = 0, Bottom = 1, Left = 2, Top = 3 } public static class Program { private static readonly char[,] smallCharacters = new char[4, 8] { {'k', 's', 'i', 'n', 'e', 'l', 'a', 't'}, {'g', 'b', 'm', 'o', 'z', 'r', 'y', 'v'}, {'x', 'p', 'f', 'd', 'j', 'c', 'u', 'h'}, {'q', '?', '!', 'w', '@', ',', '.', '\''} }; private static readonly char[,] capitalCharacters = new char[4, 8] { {'K', 'S', 'I', 'N', 'E', 'L', 'A', 'T'}, {'G', 'B', 'M', 'O', 'Z', 'R', 'Y', 'V'}, {'X', 'P', 'F', 'D', 'J', 'C', 'U', 'H'}, {'Q', '-', '_', 'W', '*', '/', ':', '\"'} }; private static readonly string[] upperCaseFlags = new string[] { "1" }; private const string fileName = "hu_eight_pen_original.xml"; private static readonly Dictionary diacritics = new() { { 'a', new char[] { 'á' } }, { 'e', new char[] { 'é' } }, { 'i', new char[] { 'í' } }, { 'o', new char[] { 'ó', 'ö', 'ő' } }, { 'u', new char[] { 'ú', 'ü', 'ű' } }, { 'A', new char[] { 'Á' } }, { 'E', new char[] { 'É' } }, { 'I', new char[] { 'Í' } }, { 'O', new char[] { 'Ó', 'Ö', 'Ő' } }, { 'U', new char[] { 'Ú', 'Ü', 'Ű' } }, }; public static void Main() { var keyboardActions = new List(); foreach (var (characters, extraLine) in new[] { (smallCharacters, 0), (capitalCharacters, 4) }) { for (var x = 0; x < characters.GetLength(0); x++) { for (var y = 0; y < characters.GetLength(1); y++) { keyboardActions.Add(CharToKeyboardAction(characters[x, y], x + extraLine, y)); } } } foreach (var keyboardAction in new List(keyboardActions)) { if (keyboardAction.Content is KeyCodeContent keyCodeContent && diacritics.ContainsKey(keyCodeContent.KeyCode)) { var keyCode = keyCodeContent.KeyCode; var diacriticsForChar = diacritics[keyCode]; for (var i = 0; i < diacriticsForChar.Length; i++) { var diacritic = diacriticsForChar[i]; var (baseMovementSequence, startToLeft) = PositionToMovementSequence(keyCodeContent.Circle, keyCodeContent.Line); startToLeft = !startToLeft; var movements = new List(baseMovementSequence); var currentSection = movements.Last(); for (var i2 = 0; i2 < i + 1; i2++) { var nextSection = GetNextSection(currentSection, startToLeft); movements.Add(nextSection); currentSection = nextSection; } keyboardActions.Add( new KeyboardAction( new StringContent(diacritic.ToString()), PositionToMovementSequenceEdges(movements.Select(m => CircleSectionToString(m))) ) ); } } } var generatedOutput = new StringBuilder(); foreach (var keyboardAction in keyboardActions) { var keyboardActionsString = $@" {keyboardAction.Content.GetActionType()} {string.Join(";", keyboardAction.MovementActions) + ";"} {keyboardAction.Content.GetContent()}{(keyboardAction.Flags.Count > 0 ? $"\n \n {string.Join("\n ", keyboardAction.Flags)}\n " : "")} "; generatedOutput.Append(keyboardActionsString); } using var writer = File.CreateText(fileName); writer.Write("" + Environment.NewLine); writer.Write(generatedOutput); writer.Write(File.ReadAllText("append.xml")); writer.Write(Environment.NewLine + ""); } private static KeyboardAction CharToKeyboardAction(char chr, int circle, int line) { var movementActions = PositionToMovementSequenceEdges(circle, line); return chr switch { var c when c >= 'a' && c <= 'z' => new KeyboardAction(new KeyCodeContent(c, circle, line), movementActions), var c when c >= 'A' && c <= 'Z' => new KeyboardAction(new KeyCodeContent(c, circle, line), movementActions, upperCaseFlags), /* var c when c == '?' => new KeyboardAction(new StringContent("?"), movementActions), var c when c == '!' => new KeyboardAction(new StringContent("!"), movementActions), var c when c == '@' => new KeyboardAction(new StringContent("@"), movementActions), var c when c == ',' => new KeyboardAction(new StringContent(","), movementActions), var c when c == '.' => new KeyboardAction(new StringContent("."), movementActions), var c when c == '\'' => new KeyboardAction(new StringContent("\'"), movementActions), var c when c == '-' => new KeyboardAction(new StringContent("?"), movementActions), var c when c == '_' => new KeyboardAction(new StringContent("!"), movementActions), var c when c == '*' => new KeyboardAction(new StringContent("@"), movementActions), var c when c == '/' => new KeyboardAction(new StringContent(","), movementActions), var c when c == ':' => new KeyboardAction(new StringContent("."), movementActions), var c when c == '\"' => new KeyboardAction(new StringContent("\'"), movementActions), */ var c => new KeyboardAction(new StringContent(c.ToString()), movementActions) //_ => throw new ArgumentException($"Unknown character: '{chr}' ({(int)chr})") }; } private static List PositionToMovementSequenceEdges(int fakeCircle, int line) { return PositionToMovementSequenceEdges( PositionToMovementSequence(fakeCircle, line) .movements .Select(m => CircleSectionToString(m)) ); } private static List PositionToMovementSequenceEdges(IEnumerable movements) { var allMovements = new List() { "INSIDE_CIRCLE" }; allMovements.AddRange(movements); allMovements.Add("INSIDE_CIRCLE"); return allMovements; } private static (List movements, bool startToLeft) PositionToMovementSequence(int fakeCircle, int line) { var movements = new List(); var (startPos, startToLeft) = line switch { var l when l == 0 => (CIRCLESECTION.Top, false), var l when l == 1 => (CIRCLESECTION.Right, true), var l when l == 2 => (CIRCLESECTION.Right, false), var l when l == 3 => (CIRCLESECTION.Bottom, true), var l when l == 4 => (CIRCLESECTION.Bottom, false), var l when l == 5 => (CIRCLESECTION.Left, true), var l when l == 6 => (CIRCLESECTION.Left, false), var l when l == 7 => (CIRCLESECTION.Top, true), _ => throw new Exception() }; movements.Add(startPos); var currentSection = startPos; for (var i = 0; i < fakeCircle + 1; i++) { var nextSection = GetNextSection(currentSection, startToLeft); movements.Add(nextSection); currentSection = nextSection; } return (movements, startToLeft); } private static CIRCLESECTION GetNextSection(CIRCLESECTION currentSection, bool toLeft) => currentSection switch { CIRCLESECTION.Top => toLeft ? CIRCLESECTION.Left : CIRCLESECTION.Right, CIRCLESECTION.Right => toLeft ? CIRCLESECTION.Top : CIRCLESECTION.Bottom, CIRCLESECTION.Bottom => toLeft ? CIRCLESECTION.Right : CIRCLESECTION.Left, CIRCLESECTION.Left => toLeft ? CIRCLESECTION.Bottom : CIRCLESECTION.Top, _ => throw new ArgumentException($"Unkown value of {nameof(CIRCLESECTION)}", nameof(currentSection)) }; private static string CircleSectionToString(CIRCLESECTION section) => section switch { CIRCLESECTION.Top => "TOP", CIRCLESECTION.Right => "RIGHT", CIRCLESECTION.Bottom => "BOTTOM", CIRCLESECTION.Left => "LEFT", _ => throw new ArgumentException($"Unkown value of {nameof(CIRCLESECTION)}", nameof(section)) }; } public class KeyboardAction { public KeyboardAction(IKeyboardContent content, IEnumerable movementActions, IEnumerable flags = null) { if (movementActions is null) throw new ArgumentNullException(nameof(movementActions)); Content = content; MovementActions.AddRange(movementActions); if (flags != null) Flags.AddRange(flags); } public IKeyboardContent Content { get; } public List Flags { get; } = new List(); public List MovementActions { get; } = new List(); } public interface IKeyboardContent { string GetContent(); string GetActionType(); } public class KeyCodeContent : IKeyboardContent { public KeyCodeContent(char keyCode, int circle, int line) { KeyCode = keyCode; KeyCodeText = "KEYCODE_" + keyCode.ToString().ToUpper(); Circle = circle; Line = line; } public string KeyCodeText { get; } public char KeyCode { get; } public int Circle { get; } public int Line { get; } public string GetContent() => $"{KeyCodeText}"; public string GetActionType() =>"INPUT_KEY"; } public class StringContent : IKeyboardContent { public StringContent(string content) { Content = content; } public string Content { get; } public string GetContent() => $"{Content}"; public string GetActionType() => "INPUT_TEXT"; } }