1 /*
2  *Copyright (C) 2018 Laurent Tréguier
3  *
4  *This file is part of DLS.
5  *
6  *DLS is free software: you can redistribute it and/or modify
7  *it under the terms of the GNU General Public License as published by
8  *the Free Software Foundation, either version 3 of the License, or
9  *(at your option) any later version.
10  *
11  *DLS is distributed in the hope that it will be useful,
12  *but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *GNU General Public License for more details.
15  *
16  *You should have received a copy of the GNU General Public License
17  *along with DLS.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 module dls.util.i18n;
22 
23 import dls.util.constants : Tr;
24 import dls.protocol.interfaces : MessageType;
25 import std.json : JSONValue;
26 
27 private enum translationsJson = import("translations.json");
28 private immutable JSONValue translations;
29 private immutable string locale;
30 private immutable defaultLocale = "en";
31 
32 shared static this()
33 {
34     import std.conv : to;
35     import std.json : parseJSON;
36 
37     translations = parseJSON(translationsJson);
38     locale = defaultLocale;
39 
40     version (Windows)
41     {
42         import core.sys.windows.windef : DWORD, ERROR_SUCCESS, LONG, HKEY;
43         import core.sys.windows.winnt : KEY_READ;
44         import core.sys.windows.winreg : HKEY_USERS, RegOpenKeyExA,
45             RegQueryValueExA;
46         import std..string : toStringz;
47 
48         HKEY hKey;
49 
50         if (RegOpenKeyExA(HKEY_USERS, toStringz(`.DEFAULT\Control Panel\International`),
51                 0, KEY_READ, &hKey) != ERROR_SUCCESS)
52         {
53             return;
54         }
55 
56         DWORD size = 32;
57         auto buffer = new char[size];
58 
59         if (RegQueryValueExA(hKey, toStringz("LocaleName"), null, null,
60                 buffer.ptr, &size) != ERROR_SUCCESS)
61         {
62             return;
63         }
64 
65         if (size >= 2)
66         {
67             locale = buffer[0 .. 2].to!string;
68         }
69     }
70     else version (Posix)
71     {
72         import std.process : environment;
73 
74         auto lang = environment.get("LANG", defaultLocale);
75 
76         if (lang.length >= 2)
77         {
78             locale = lang[0 .. 2];
79         }
80     }
81 }
82 
83 string tr(Tr message, string[] args = [])
84 {
85     import std.conv : to;
86     import std.range : replace;
87 
88     auto title = translations[message]["title"];
89     auto localizedTitle = title[locale in title ? locale : defaultLocale].str;
90 
91     foreach (i; 0 .. args.length)
92     {
93         localizedTitle = localizedTitle.replace('$' ~ (i + 1).to!string, args[i]);
94     }
95 
96     return localizedTitle;
97 }
98 
99 MessageType trType(Tr message)
100 {
101     import std.conv : to;
102 
103     auto t = translations[message];
104     return "messageType" in t ? t["messageType"].integer.to!MessageType : MessageType.info;
105 }