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 
48         if (RegOpenKeyExA(HKEY_USERS, toStringz(`.DEFAULT\Control Panel\International`),
49                 0, KEY_READ, &hKey) != ERROR_SUCCESS)
50         {
51             return;
52         }
53 
54         DWORD size = 32;
55         auto buffer = new char[size];
56 
57         if (RegQueryValueExA(hKey, toStringz("LocaleName"), null, null,
58                 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         static assert(false, "Platform not supported");
82     }
83 }
84 
85 string tr(Tr identifier, string[] args = [])
86 {
87     import std.conv : text;
88     import std.range : replace;
89 
90     auto message = translations[identifier];
91     auto localizedMessage = message[locale in message ? locale : defaultLocale].str;
92 
93     foreach (i, arg; args)
94     {
95         localizedMessage = localizedMessage.replace('$' ~ text(i + 1), arg);
96     }
97 
98     return localizedMessage;
99 }
100 
101 MessageType trType(Tr message)
102 {
103     auto t = translations[message];
104     return "_type" in t ? cast(MessageType) t["_type"].integer : MessageType.info;
105 }