private void LoadCulture(String culture)
        {
            var fileName   = "Plain Keyboard\\layout." + culture + ".json";
            var layoutPath = Path.Combine(layoutsPath, fileName);

            if (!File.Exists(layoutPath))
            {
                LoadDefault();
            }

            string content = File.ReadAllText(layoutPath, Encoding.UTF8);

            KeyboardKey[] keyboard = JsonConvert.DeserializeObject <KeyboardKey[]>(content, new JsonSerializerSettings {
                ObjectCreationHandling = ObjectCreationHandling.Replace
            });

            virtual_keyboard_group = new VirtualGroup(keyboard);

            /*
             * if (keyboard.Count > 0)
             *  keyboard.Last().line_break = false;
             *
             * keyboard.Add(new KeyboardKey("Mouse/\r\nHeadset", Devices.DeviceKeys.Peripheral, true, true, 12, 45, -60, 90, 90, 6, 6, 4, -3));
             *
             * if (keyboard.Count > 0)
             *  keyboard.Last().line_break = true;
             */
        }
        public void LoadBrand(PreferredKeyboard keyboard_preference = PreferredKeyboard.None, PreferredMouse mouse_preference = PreferredMouse.None, MouseOrientationType mouse_orientation = MouseOrientationType.RightHanded)
        {
            try
            {
                //System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");

                //Global.logger.LogLine("Loading brand: " + brand.ToString() + " for: " + System.Threading.Thread.CurrentThread.CurrentCulture.Name);

                //Load keyboard layout
                if (Directory.Exists(layoutsPath))
                {
                    string culture = System.Threading.Thread.CurrentThread.CurrentCulture.Name;

                    switch (Global.Configuration.keyboard_localization)
                    {
                    case PreferredKeyboardLocalization.None:
                        break;

                    case PreferredKeyboardLocalization.intl:
                        culture = "intl";
                        break;

                    case PreferredKeyboardLocalization.us:
                        culture = "en-US";
                        break;

                    case PreferredKeyboardLocalization.uk:
                        culture = "en-GB";
                        break;

                    case PreferredKeyboardLocalization.ru:
                        culture = "ru-RU";
                        break;

                    case PreferredKeyboardLocalization.fr:
                        culture = "fr-FR";
                        break;

                    case PreferredKeyboardLocalization.de:
                        culture = "de-DE";
                        break;

                    case PreferredKeyboardLocalization.jpn:
                        culture = "ja-JP";
                        break;
                    }

                    switch (culture)
                    {
                    case ("ja-JP"):
                        LoadCulture("jpn");
                        break;

                    case ("de-DE"):
                    case ("hsb-DE"):
                    case ("dsb-DE"):
                        _loaded_localization = PreferredKeyboardLocalization.de;
                        LoadCulture("de");
                        break;

                    case ("fr-FR"):
                    case ("br-FR"):
                    case ("oc-FR"):
                    case ("co-FR"):
                    case ("gsw-FR"):
                        _loaded_localization = PreferredKeyboardLocalization.fr;
                        LoadCulture("fr");
                        break;

                    case ("cy-GB"):
                    case ("gd-GB"):
                    case ("en-GB"):
                        _loaded_localization = PreferredKeyboardLocalization.uk;
                        LoadCulture("uk");
                        break;

                    case ("ru-RU"):
                    case ("tt-RU"):
                    case ("ba-RU"):
                    case ("sah-RU"):
                        _loaded_localization = PreferredKeyboardLocalization.ru;
                        LoadCulture("ru");
                        break;

                    case ("en-US"):
                        _loaded_localization = PreferredKeyboardLocalization.us;
                        LoadCulture("us");
                        break;

                    default:
                        _loaded_localization = PreferredKeyboardLocalization.intl;
                        LoadCulture("intl");
                        break;
                    }
                }

                var layoutConfigPath = "";

                if (keyboard_preference == PreferredKeyboard.Logitech_G910)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "logitech_g910.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Logitech_G810)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "logitech_g810.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Logitech_G410)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "logitech_g410.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Corsair_K95)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "corsair_k95.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Corsair_K70)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "corsair_k70.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Corsair_K65)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "corsair_k65.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Corsair_STRAFE)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "corsair_strafe.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Razer_Blackwidow)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "razer_blackwidow.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Razer_Blackwidow_X)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "razer_blackwidow_x.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Razer_Blackwidow_TE)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "razer_blackwidow_te.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Masterkeys_Pro_L)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "masterkeys_pro_l.json");
                }
                else if (keyboard_preference == PreferredKeyboard.Masterkeys_Pro_S)
                {
                    layoutConfigPath = Path.Combine(layoutsPath, "masterkeys_pro_s.json");
                }
                //else if (keyboard_preference == PreferredKeyboard.Roccat_Ryos)
                //    layoutConfigPath = Path.Combine(layoutsPath, "roccat_ryos.json");
                else
                {
                    LoadNone();
                    return;
                }

                if (!String.IsNullOrWhiteSpace(layoutConfigPath) && File.Exists(layoutConfigPath))
                {
                    string content = File.ReadAllText(layoutConfigPath, Encoding.UTF8);
                    VirtualGroupConfiguration layoutConfig = JsonConvert.DeserializeObject <VirtualGroupConfiguration>(content, new JsonSerializerSettings {
                        ObjectCreationHandling = ObjectCreationHandling.Replace
                    });

                    if (layoutConfig.replace_RWin_with_FN)
                    {
                        virtual_keyboard_group.AdjustFNKey();
                    }

                    virtual_keyboard_group.SetNewLineKeys(layoutConfig.keys_to_set_as_new_line);
                    virtual_keyboard_group.RemoveKeys(layoutConfig.keys_to_remove);

                    foreach (string feature in layoutConfig.included_features)
                    {
                        string feature_path = Path.Combine(layoutsPath, "Extra Features", feature);

                        if (File.Exists(feature_path))
                        {
                            string       feature_content = File.ReadAllText(feature_path, Encoding.UTF8);
                            VirtualGroup feature_config  = JsonConvert.DeserializeObject <VirtualGroup>(feature_content, new JsonSerializerSettings {
                                ObjectCreationHandling = ObjectCreationHandling.Replace
                            });

                            virtual_keyboard_group.AddFeature(feature_config.grouped_keys.ToArray(), feature_config.origin_region);
                        }
                    }

                    string mouse_feature_path = "";

                    switch (mouse_preference)
                    {
                    case PreferredMouse.Logitech_G900:
                        mouse_feature_path = Path.Combine(layoutsPath, "Extra Features", "logitech_g900_features.json");
                        break;

                    case PreferredMouse.Corsair_Sabre:
                        mouse_feature_path = Path.Combine(layoutsPath, "Extra Features", "corsair_sabre_features.json");
                        break;

                    case PreferredMouse.Corsair_M65:
                        mouse_feature_path = Path.Combine(layoutsPath, "Extra Features", "corsair_m65_features.json");
                        break;

                    case PreferredMouse.Corsair_Katar:
                        mouse_feature_path = Path.Combine(layoutsPath, "Extra Features", "corsair_katar_features.json");
                        break;

                    case PreferredMouse.Clevo_Touchpad:
                        mouse_feature_path = Path.Combine(layoutsPath, "Extra Features", "clevo_touchpad_features.json");
                        break;
                    }

                    if (!string.IsNullOrWhiteSpace(mouse_feature_path))
                    {
                        string       feature_content = File.ReadAllText(mouse_feature_path, Encoding.UTF8);
                        VirtualGroup feature_config  = JsonConvert.DeserializeObject <VirtualGroup>(feature_content, new JsonSerializerSettings {
                            ObjectCreationHandling = ObjectCreationHandling.Replace
                        });

                        if (mouse_orientation == MouseOrientationType.LeftHanded)
                        {
                            if (feature_config.origin_region == KeyboardRegion.TopRight)
                            {
                                feature_config.origin_region = KeyboardRegion.TopLeft;
                            }
                            else if (feature_config.origin_region == KeyboardRegion.BottomRight)
                            {
                                feature_config.origin_region = KeyboardRegion.BottomLeft;
                            }

                            double outline_width      = 0.0;
                            int    outline_width_bits = 0;

                            foreach (var key in feature_config.grouped_keys)
                            {
                                if (outline_width == 0.0 && outline_width_bits == 0) //We found outline (NOTE: Outline has to be first in the grouped keys)
                                {
                                    if (key.tag == DeviceKeys.NONE)
                                    {
                                        outline_width      = key.width + 2 * key.margin_left;
                                        outline_width_bits = key.width_bits + 2 * key.margin_left_bits;
                                    }
                                }

                                key.margin_left      -= outline_width;
                                key.margin_left_bits -= outline_width_bits;
                            }
                        }

                        virtual_keyboard_group.AddFeature(feature_config.grouped_keys.ToArray(), feature_config.origin_region);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            //Perform end of load functions
            CalculateBitmap();
            CreateUserControl();

            KeyboardLayoutUpdated?.Invoke(this);
        }
        public void LoadDefault()
        {
            List <KeyboardKey> keyboard = new List <KeyboardKey>();

            keyboard.Add(new KeyboardKey("ESC", Devices.DeviceKeys.ESC));

            keyboard.Add(new KeyboardKey("F1", Devices.DeviceKeys.F1, true, false, 12, 32));
            keyboard.Add(new KeyboardKey("F2", Devices.DeviceKeys.F2));
            keyboard.Add(new KeyboardKey("F3", Devices.DeviceKeys.F3));
            keyboard.Add(new KeyboardKey("F4", Devices.DeviceKeys.F4));

            keyboard.Add(new KeyboardKey("F5", Devices.DeviceKeys.F5, true, false, 12, 34));
            keyboard.Add(new KeyboardKey("F6", Devices.DeviceKeys.F6));
            keyboard.Add(new KeyboardKey("F7", Devices.DeviceKeys.F7));
            keyboard.Add(new KeyboardKey("F8", Devices.DeviceKeys.F8));

            keyboard.Add(new KeyboardKey("F9", Devices.DeviceKeys.F9, true, false, 12, 29));
            keyboard.Add(new KeyboardKey("F10", Devices.DeviceKeys.F10));
            keyboard.Add(new KeyboardKey("F11", Devices.DeviceKeys.F11));
            keyboard.Add(new KeyboardKey("F12", Devices.DeviceKeys.F12));

            keyboard.Add(new KeyboardKey("PRINT", Devices.DeviceKeys.PRINT_SCREEN, true, false, 9, 14));
            keyboard.Add(new KeyboardKey("SCRL\r\nLOCK", Devices.DeviceKeys.SCROLL_LOCK, true, false, 9));
            keyboard.Add(new KeyboardKey("PAUSE", Devices.DeviceKeys.PAUSE_BREAK, true, true, 9));

            keyboard.Add(new KeyboardKey("~", Devices.DeviceKeys.TILDE));
            keyboard.Add(new KeyboardKey("1", Devices.DeviceKeys.ONE));
            keyboard.Add(new KeyboardKey("2", Devices.DeviceKeys.TWO));
            keyboard.Add(new KeyboardKey("3", Devices.DeviceKeys.THREE));
            keyboard.Add(new KeyboardKey("4", Devices.DeviceKeys.FOUR));
            keyboard.Add(new KeyboardKey("5", Devices.DeviceKeys.FIVE));
            keyboard.Add(new KeyboardKey("6", Devices.DeviceKeys.SIX));
            keyboard.Add(new KeyboardKey("7", Devices.DeviceKeys.SEVEN));
            keyboard.Add(new KeyboardKey("8", Devices.DeviceKeys.EIGHT));
            keyboard.Add(new KeyboardKey("9", Devices.DeviceKeys.NINE));
            keyboard.Add(new KeyboardKey("0", Devices.DeviceKeys.ZERO));
            keyboard.Add(new KeyboardKey("-", Devices.DeviceKeys.MINUS));
            keyboard.Add(new KeyboardKey("=", Devices.DeviceKeys.EQUALS));
            keyboard.Add(new KeyboardKey("BACKSPACE", Devices.DeviceKeys.BACKSPACE, true, false, 12, 7, 0, 67));

            keyboard.Add(new KeyboardKey("INSERT", Devices.DeviceKeys.INSERT, true, false, 9, 14));
            keyboard.Add(new KeyboardKey("HOME", Devices.DeviceKeys.HOME, true, false, 9));
            keyboard.Add(new KeyboardKey("PAGE\r\nUP", Devices.DeviceKeys.HOME, true, false, 9));

            keyboard.Add(new KeyboardKey("NUM\r\nLOCK", Devices.DeviceKeys.NUM_LOCK, true, false, 9, 14));
            keyboard.Add(new KeyboardKey("/", Devices.DeviceKeys.NUM_SLASH));
            keyboard.Add(new KeyboardKey("*", Devices.DeviceKeys.NUM_ASTERISK));
            keyboard.Add(new KeyboardKey("-", Devices.DeviceKeys.NUM_MINUS, true, true));

            keyboard.Add(new KeyboardKey("TAB", Devices.DeviceKeys.TAB, true, false, 12, 7, 0, 50));
            keyboard.Add(new KeyboardKey("Q", Devices.DeviceKeys.Q));
            keyboard.Add(new KeyboardKey("W", Devices.DeviceKeys.W));
            keyboard.Add(new KeyboardKey("E", Devices.DeviceKeys.E));
            keyboard.Add(new KeyboardKey("R", Devices.DeviceKeys.R));
            keyboard.Add(new KeyboardKey("T", Devices.DeviceKeys.T));
            keyboard.Add(new KeyboardKey("Y", Devices.DeviceKeys.Y));
            keyboard.Add(new KeyboardKey("U", Devices.DeviceKeys.U));
            keyboard.Add(new KeyboardKey("I", Devices.DeviceKeys.I));
            keyboard.Add(new KeyboardKey("O", Devices.DeviceKeys.O));
            keyboard.Add(new KeyboardKey("P", Devices.DeviceKeys.P));
            keyboard.Add(new KeyboardKey("{", Devices.DeviceKeys.OPEN_BRACKET));
            keyboard.Add(new KeyboardKey("}", Devices.DeviceKeys.CLOSE_BRACKET));
            keyboard.Add(new KeyboardKey("\\", Devices.DeviceKeys.BACKSLASH, true, false, 12, 7, 0, 49));

            keyboard.Add(new KeyboardKey("DEL", Devices.DeviceKeys.DELETE, true, false, 9, 12));
            keyboard.Add(new KeyboardKey("END", Devices.DeviceKeys.END, true, false, 9));
            keyboard.Add(new KeyboardKey("PAGE\r\nDOWN", Devices.DeviceKeys.PAGE_DOWN, true, false, 9));

            keyboard.Add(new KeyboardKey("7", Devices.DeviceKeys.NUM_SEVEN, true, false, 12, 14));
            keyboard.Add(new KeyboardKey("8", Devices.DeviceKeys.NUM_EIGHT));
            keyboard.Add(new KeyboardKey("9", Devices.DeviceKeys.NUM_NINE));
            keyboard.Add(new KeyboardKey("+", Devices.DeviceKeys.NUM_PLUS, true, true, 12, 7, 0, 30, 69));

            keyboard.Add(new KeyboardKey("CAPS\r\nLOCK", Devices.DeviceKeys.CAPS_LOCK, true, false, 9, 7, 0, 60));
            keyboard.Add(new KeyboardKey("A", Devices.DeviceKeys.A));
            keyboard.Add(new KeyboardKey("S", Devices.DeviceKeys.S));
            keyboard.Add(new KeyboardKey("D", Devices.DeviceKeys.D));
            keyboard.Add(new KeyboardKey("F", Devices.DeviceKeys.F));
            keyboard.Add(new KeyboardKey("G", Devices.DeviceKeys.G));
            keyboard.Add(new KeyboardKey("H", Devices.DeviceKeys.H));
            keyboard.Add(new KeyboardKey("J", Devices.DeviceKeys.J));
            keyboard.Add(new KeyboardKey("K", Devices.DeviceKeys.K));
            keyboard.Add(new KeyboardKey("L", Devices.DeviceKeys.L));
            keyboard.Add(new KeyboardKey(":", Devices.DeviceKeys.SEMICOLON));
            keyboard.Add(new KeyboardKey("\"", Devices.DeviceKeys.APOSTROPHE));
            keyboard.Add(new KeyboardKey("ENTER", Devices.DeviceKeys.ENTER, true, false, 12, 7, 0, 76));

            keyboard.Add(new KeyboardKey("4", Devices.DeviceKeys.NUM_FOUR, true, false, 12, 130));
            keyboard.Add(new KeyboardKey("5", Devices.DeviceKeys.NUM_FIVE));
            keyboard.Add(new KeyboardKey("6", Devices.DeviceKeys.NUM_SIX, true, true));
            //Space taken up by +

            keyboard.Add(new KeyboardKey("SHIFT", Devices.DeviceKeys.LEFT_SHIFT, true, false, 12, 7, 0, 78));
            keyboard.Add(new KeyboardKey("Z", Devices.DeviceKeys.Z));
            keyboard.Add(new KeyboardKey("X", Devices.DeviceKeys.X));
            keyboard.Add(new KeyboardKey("C", Devices.DeviceKeys.C));
            keyboard.Add(new KeyboardKey("V", Devices.DeviceKeys.V));
            keyboard.Add(new KeyboardKey("B", Devices.DeviceKeys.B));
            keyboard.Add(new KeyboardKey("N", Devices.DeviceKeys.N));
            keyboard.Add(new KeyboardKey("M", Devices.DeviceKeys.M));
            keyboard.Add(new KeyboardKey("<", Devices.DeviceKeys.COMMA));
            keyboard.Add(new KeyboardKey(">", Devices.DeviceKeys.PERIOD));
            keyboard.Add(new KeyboardKey("?", Devices.DeviceKeys.FORWARD_SLASH));
            keyboard.Add(new KeyboardKey("SHIFT", Devices.DeviceKeys.RIGHT_SHIFT, true, false, 12, 7, 0, 95));

            keyboard.Add(new KeyboardKey("UP", Devices.DeviceKeys.ARROW_UP, true, false, 9, 49));

            keyboard.Add(new KeyboardKey("1", Devices.DeviceKeys.NUM_ONE, true, false, 12, 51));
            keyboard.Add(new KeyboardKey("2", Devices.DeviceKeys.NUM_TWO));
            keyboard.Add(new KeyboardKey("3", Devices.DeviceKeys.NUM_THREE));
            keyboard.Add(new KeyboardKey("ENTER", Devices.DeviceKeys.NUM_ENTER, true, true, 9, 7, 0, 30, 67));

            keyboard.Add(new KeyboardKey("CTRL", Devices.DeviceKeys.RIGHT_CONTROL, true, false, 12, 7, 0, 51));
            keyboard.Add(new KeyboardKey("WIN", Devices.DeviceKeys.RIGHT_WINDOWS, true, false, 12, 5, 0, 39));
            keyboard.Add(new KeyboardKey("ALT", Devices.DeviceKeys.RIGHT_ALT, true, false, 12, 5, 0, 42));

            keyboard.Add(new KeyboardKey("SPACE", Devices.DeviceKeys.SPACE, true, false, 12, 7, 0, 208));
            keyboard.Add(new KeyboardKey("ALT", Devices.DeviceKeys.LEFT_ALT, true, false, 12, 5, 0, 41));
            keyboard.Add(new KeyboardKey("WIN", Devices.DeviceKeys.LEFT_WINDOWS, true, false, 12, 5, 0, 41));
            keyboard.Add(new KeyboardKey("APP", Devices.DeviceKeys.APPLICATION_SELECT, true, false, 12, 5, 0, 41));
            keyboard.Add(new KeyboardKey("CTRL", Devices.DeviceKeys.LEFT_CONTROL, true, false, 12, 5, 0, 50));

            keyboard.Add(new KeyboardKey("LEFT", Devices.DeviceKeys.ARROW_LEFT, true, false, 9, 12));
            keyboard.Add(new KeyboardKey("DOWN", Devices.DeviceKeys.ARROW_DOWN, true, false, 9));
            keyboard.Add(new KeyboardKey("RIGHT", Devices.DeviceKeys.ARROW_DOWN, true, false, 9));

            keyboard.Add(new KeyboardKey("0", Devices.DeviceKeys.NUM_ZERO, true, false, 12, 14, 0, 67));
            keyboard.Add(new KeyboardKey(".", Devices.DeviceKeys.NUM_PERIOD, true, true));

            virtual_keyboard_group = new VirtualGroup(keyboard.ToArray());

            _loaded_localization = PreferredKeyboardLocalization.None;
        }