#ifndef CLANG_H
#define CLANG_H

#include "GdCPP_Exports.h"
#include "json\_nlohmann_json_wrapper.h"
//#include "LangEnum.h"

/// 界面语言相关。
/// - 定义了一组界面语言和对应的字符串
/// - 定义了界面语言的静态成员，方便全局访问。
/// - 定义了与json互转的函数
struct GDCPP_API CLang
{
	///界面语言的枚举
	enum eLang {
		undef=-1,  ///< 未定义
		zh=0,  ///< 简体中文
		en,     ///< 英语
		vn,		///< 越南语
		th,		///< 泰语
		sp,		///< 西班牙语
		jp,		///< 日语
		ru,		///< 俄语
		LangNum
	};

	CLang() = default;

	/// 复制构造函数
	CLang(const CLang & p) :Lang(p.Lang) {}
	
	CLang(const CLang::eLang& e) :Lang(e) {}


    /// 当前语言的枚举
    eLang Lang = eLang::zh;

    /// 字符串转枚举
    static eLang fromStr(const char * str);

    /// 用于json文件的英文字符串
	static const char* LangStr[LangNum];

    /// 用于UI显示的中英文字符串
	static const wchar_t* LangWStr[LangNum];

	static const wchar_t* LangWStrCn[LangNum];

    /// @brief 实例名称后面加括号直接返回
    inline  eLang operator()() {return Lang;}

	/// 重载比较运算符
	inline bool operator == (const CLang& l) { return Lang == l.Lang; }
	inline bool operator != (const CLang& l) { return Lang != l.Lang; }

	inline bool operator == (eLang l) { return Lang == l; }
	inline bool operator != (eLang l) { return Lang != l; }

	inline bool operator == (const std::string & l) { return l == LangStr[Lang]; }
	inline bool operator != (const std::string & l) { return l != LangStr[Lang]; }

	inline bool operator == (const char * l) { return strcmp(l, LangStr[Lang]) == 0; }
	inline bool operator != (const char * l) { return strcmp(l, LangStr[Lang]) != 0; }
	
	// const char *类型转换操作符重载
	inline operator const char *()
	{
		return LangStr[Lang];
	}
	
	// std::string类型转换操作符重载
	inline operator std::string()
	{
		return LangStr[Lang];
	}

};

/// \brief 全局共用的语言实例。
/// \details 界面刷新时使用全局实例，参数设置里用局部实例。
/// 加载：
///  app从设置文件中加载配置到局部实例，赋值给全局实例。
/// 设置：
///  界面上修改局部实例，确认时赋值给全局实例，保存到配置文件。
/// 
/// 为什么不直接用静态成员变量？
/// 如果以exe与dll中都用到，且是用静态库或直接使用源码，exe与dll的静态成员不是同一个变量。
GDCPP_API extern CLang gLang;

void GDCPP_API to_json(jsonobj& j, const CLang & p);
void GDCPP_API from_json(const jsonobj& j, CLang& p);


#endif // CAPPSETTING_H
