1/*
2 * Copyright 2003-2011, Axel D��rfler, axeld@pinc-software.de.
3 * Copyright 2009-2019, Adrien Destugues, pulkomandy@gmail.com.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8#include <unicode/uversion.h>
9#include <Country.h>
10
11#include <AutoDeleter.h>
12#include <IconUtils.h>
13#include <List.h>
14#include <Language.h>
15#include <LocaleRoster.h>
16#include <Resources.h>
17#include <String.h>
18
19#include <unicode/locid.h>
20#include <unicode/ulocdata.h>
21#include <ICUWrapper.h>
22
23#include <iostream>
24#include <map>
25#include <monetary.h>
26#include <new>
27#include <stdarg.h>
28#include <stdlib.h>
29
30
31U_NAMESPACE_USE
32
33
34BCountry::BCountry(const char* countryCode)
35	:
36	fICULocale(NULL)
37{
38	SetTo(countryCode);
39}
40
41
42BCountry::BCountry(const BCountry& other)
43	:
44	fICULocale(new icu::Locale(*other.fICULocale))
45{
46}
47
48
49BCountry&
50BCountry::operator=(const BCountry& other)
51{
52	if (this == &other)
53		return *this;
54
55	if (!fICULocale)
56		fICULocale = new icu::Locale(*other.fICULocale);
57	else
58		*fICULocale = *other.fICULocale;
59
60	return *this;
61}
62
63
64BCountry::~BCountry()
65{
66	delete fICULocale;
67}
68
69
70status_t
71BCountry::SetTo(const char* countryCode)
72{
73	delete fICULocale;
74	fICULocale = new icu::Locale("", countryCode);
75
76	return InitCheck();
77}
78
79
80status_t
81BCountry::InitCheck() const
82{
83	if (fICULocale == NULL)
84		return B_NO_MEMORY;
85
86	if (fICULocale->isBogus())
87		return B_BAD_DATA;
88
89	return B_OK;
90}
91
92
93status_t
94BCountry::GetNativeName(BString& name) const
95{
96	status_t valid = InitCheck();
97	if (valid != B_OK)
98		return valid;
99
100	UnicodeString string;
101	fICULocale->getDisplayCountry(*fICULocale, string);
102	string.toTitle(NULL, *fICULocale);
103
104	name.Truncate(0);
105	BStringByteSink converter(&name);
106	string.toUTF8(converter);
107
108	return B_OK;
109}
110
111
112status_t
113BCountry::GetName(BString& name, const BLanguage* displayLanguage) const
114{
115	status_t status = InitCheck();
116	if (status != B_OK)
117		return status;
118
119	BString appLanguage;
120	if (displayLanguage == NULL) {
121		BMessage preferredLanguages;
122		status = BLocaleRoster::Default()->GetPreferredLanguages(
123			&preferredLanguages);
124		if (status == B_OK)
125			status = preferredLanguages.FindString("language", 0, &appLanguage);
126	} else {
127		appLanguage = displayLanguage->Code();
128	}
129
130	if (status == B_OK) {
131		UnicodeString uString;
132		fICULocale->getDisplayCountry(Locale(appLanguage), uString);
133		name.Truncate(0);
134		BStringByteSink stringConverter(&name);
135		uString.toUTF8(stringConverter);
136	}
137
138	return status;
139}
140
141
142status_t
143BCountry::GetPreferredLanguage(BLanguage& language) const
144{
145#if U_ICU_VERSION_MAJOR_NUM < 63
146	return ENOSYS;
147#else
148	status_t status = InitCheck();
149	if (status != B_OK)
150		return status;
151
152	icu::Locale* languageLocale = fICULocale->clone();
153	if (languageLocale == NULL)
154		return B_NO_MEMORY;
155
156	UErrorCode icuError = U_ZERO_ERROR;
157	languageLocale->addLikelySubtags(icuError);
158
159	if (U_FAILURE(icuError))
160		return B_ERROR;
161
162	status = language.SetTo(languageLocale->getLanguage());
163
164	delete languageLocale;
165
166	return status;
167#endif
168}
169
170
171const char*
172BCountry::Code() const
173{
174	status_t status = InitCheck();
175	if (status != B_OK)
176		return NULL;
177
178	return fICULocale->getCountry();
179}
180
181
182status_t
183BCountry::GetIcon(BBitmap* result) const
184{
185	status_t status = InitCheck();
186	if (status != B_OK)
187		return status;
188
189	return BLocaleRoster::Default()->GetFlagIconForCountry(result, Code());
190}
191
192
193status_t
194BCountry::GetAvailableTimeZones(BMessage* timeZones) const
195{
196	status_t status = InitCheck();
197	if (status != B_OK)
198		return status;
199
200	return BLocaleRoster::Default()->GetAvailableTimeZonesForCountry(timeZones,
201		Code());
202}
203
204