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 public import dls.util.i18n.constants;
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.json : parseJSON;
35 
36     translations = parseJSON(translationsJson);
37     locale = defaultLocale;
38 
39     version (Windows)
40     {
41         import core.sys.windows.windef : DWORD, ERROR_SUCCESS, LONG, HKEY;
42         import core.sys.windows.winnt : KEY_READ;
43         import core.sys.windows.winreg : HKEY_USERS, RegOpenKeyExA, RegQueryValueExA;
44         import std..string : toStringz;
45 
46         HKEY hKey;
47         auto regKeyCStr = toStringz(`.DEFAULT\Control Panel\International`);
48 
49         if (RegOpenKeyExA(HKEY_USERS, regKeyCStr, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
50         {
51             return;
52         }
53 
54         DWORD size = 32;
55         auto buffer = new char[size];
56         auto localeNameCStr = toStringz("LocaleName");
57 
58         if (RegQueryValueExA(hKey, localeNameCStr, null, null, buffer.ptr, &size) != ERROR_SUCCESS)
59         {
60             return;
61         }
62 
63         if (size >= 2)
64         {
65             locale = buffer[0 .. 2].idup;
66         }
67     }
68     else version (Posix)
69     {
70         import std.process : environment;
71 
72         auto lang = environment.get("LANG", defaultLocale);
73 
74         if (lang.length >= 2)
75         {
76             locale = lang[0 .. 2];
77         }
78     }
79     else
80     {
81         locale = defaultLocale;
82     }
83 }
84 
85 string tr(Tr identifier, string[] args = [])
86 {
87     import std.ascii : newline;
88     import std.conv : text;
89     import std.range : replace;
90 
91     auto message = translations[identifier];
92     auto localizedMessage = message[locale in message ? locale : defaultLocale].str;
93 
94     foreach (i, arg; args)
95     {
96         localizedMessage = localizedMessage.replace('$' ~ text(i + 1), arg);
97     }
98 
99     return localizedMessage.replace("$n", newline);
100 }
101 
102 MessageType trType(Tr message)
103 {
104     auto t = translations[message];
105     return "_type" in t ? cast(MessageType) t["_type"].integer : MessageType.info;
106 }