//******************************************************************************
//
// MIDITrail / MTStringEncodingList
//
// 文字列エンコーディングリストクラス
//
// Copyright (C) 2010-2017 WADA Masashi. All Rights Reserved.
//
//******************************************************************************

#import "MTStringEncodingList.h"
#import "YNBaseLib.h"


//******************************************************************************
// コンストラクタ
//******************************************************************************
MTStringEncodingList::MTStringEncodingList(void)
{
	m_pEncodingNameArray = nil;
	m_pEncodingIdArray = nil;
}

//******************************************************************************
// デストラクタ
//******************************************************************************
MTStringEncodingList::~MTStringEncodingList(void)
{
	Clear();
}

//******************************************************************************
// 初期化
//******************************************************************************
int MTStringEncodingList::Initialize()
{
	int result = 0;
	NSNumber* pEncodingId = nil;
	NSMutableDictionary* pDictionary = nil;
	NSArray* pSortedKeys = nil;
	NSString* pName = nil;
	const NSStringEncoding* pEncoding;
	
	Clear();
	
	//作業用辞書を生成
	pDictionary = [[NSMutableDictionary alloc] init];
	
	//配列を生成
	m_pEncodingNameArray = [[NSMutableArray alloc] init];
	m_pEncodingIdArray = [[NSMutableArray alloc] init];
	
	//エンコーディング一覧を取得
	//pId = CFStringGetListOfAvailableEncodings();
	pEncoding = [NSString availableStringEncodings];
	
	//全エンコーディングを取得
	while (*pEncoding) {
		//エンコーディングに対応するエンコーディング名称を取得
		//  iOS 5.1 では CFStringGetNameOfEncoding, NSString:localizedNameOfStringEncoding
		//  がほとんどのエンコーディングに対して空文字を返す。これが不具合なのか仕様なのかは不明。
		//  Mac OS X と同等の文字列を返す関数を自作して対処する。
		//pName = [NSString localizedNameOfStringEncoding:(*pEncoding)];
		pName = _GetNameOfEncoding(*pEncoding);
		
		//辞書登録
		if (pName != nil) {
			pEncodingId = [[NSNumber alloc] initWithUnsignedLong:(*pEncoding)];
			[pDictionary setObject:pEncodingId forKey:pName];
			[pEncodingId release];
			pEncodingId = nil;
			pName = nil;
		}
		
		//次のエンコーディングIDへ移る
		pEncoding++;
	}
	
	//辞書に登録されたエンコーディング名称一覧をソートして取得
	pSortedKeys = [[pDictionary allKeys] sortedArrayUsingSelector:@selector(compare:)];
	
	//ソートしたエンコーディング名称とエンコーディングIDを配列に保存
	for (pName in pSortedKeys) {
		[m_pEncodingNameArray addObject:pName];
		[m_pEncodingIdArray addObject:[pDictionary objectForKey:pName]];
	}
	
EXIT:;
	[pDictionary release];
	return result;
}

//******************************************************************************
// エンコーディング数取得
//******************************************************************************
unsigned int MTStringEncodingList::GetSize()
{
	return (unsigned int)[m_pEncodingNameArray count];
}

//******************************************************************************
// エンコーディング名称取得
//******************************************************************************
NSString* MTStringEncodingList::GetEncodingName(unsigned int index)
{
	NSString* pEncodingName = @"";
	
	if (index >= [m_pEncodingNameArray count]) {
		goto EXIT;
	}
	
	pEncodingName = [m_pEncodingNameArray objectAtIndex:index];
	
EXIT:;
	return pEncodingName;
}

//******************************************************************************
//エンコーディングID称取得(NSStringEncoding)
//******************************************************************************
NSStringEncoding MTStringEncodingList::GetEncodingId(unsigned int index)
{
	NSStringEncoding encodingId = 0;
	
	if (index >= [m_pEncodingNameArray count]) {
		goto EXIT;
	}
	
	encodingId = [[m_pEncodingIdArray objectAtIndex:index] unsignedLongValue];
	
EXIT:;
	return encodingId;
}

//******************************************************************************
// クリア
//******************************************************************************
void MTStringEncodingList::Clear()
{
	[m_pEncodingNameArray release];
	m_pEncodingNameArray = nil;
	[m_pEncodingIdArray release];
	m_pEncodingIdArray = nil;
}

//******************************************************************************
// 文字列エンコーディング名称取得
//******************************************************************************
NSString* MTStringEncodingList::_GetNameOfEncoding(NSStringEncoding encoding)
{
	NSString* pName = nil;
	
	switch (encoding) {
		case 0x00000001: pName = @"Western (ASCII)";                    break;
		case 0x00000002: pName = @"Western (NextStep)";                 break;
		case 0x00000003: pName = @"Japanese (EUC)";                     break;
		case 0x00000004: pName = @"Unicode (UTF-8)";                    break;
		case 0x00000005: pName = @"Western (ISO Latin 1)";              break;
		case 0x00000006: pName = @"Symbol (Mac OS)";                    break;
		case 0x00000007: pName = @"Non-lossy ASCII";                    break;
		case 0x00000008: pName = @"Japanese (Windows, DOS)";            break;
		case 0x00000009: pName = @"Central European (ISO Latin 2)";     break;
		case 0x0000000A: pName = @"Unicode (UTF-16)";                   break;
		case 0x0000000B: pName = @"Cyrillic (Windows)";                 break;
		case 0x0000000C: pName = @"Western (Windows Latin 1)";          break;
		case 0x0000000D: pName = @"Greek (Windows)";                    break;
		case 0x0000000E: pName = @"Turkish (Windows Latin 5)";          break;
		case 0x0000000F: pName = @"Central European (Windows Latin 2)";	break;
		case 0x00000015: pName = @"Japanese (ISO 2022-JP)";             break;
		case 0x0000001E: pName = @"Western (Mac OS Roman)";             break;
		case 0x80000001: pName = @"Japanese (Mac OS)";                  break;
		case 0x80000002: pName = @"Traditional Chinese (Mac OS)";       break;
		case 0x80000003: pName = @"Korean (Mac OS)";                    break;
		case 0x80000004: pName = @"Arabic (Mac OS)";                    break;
		case 0x80000005: pName = @"Hebrew (Mac OS)";                    break;
		case 0x80000006: pName = @"Greek (Mac OS)";                     break;
		case 0x80000007: pName = @"Cyrillic (Mac OS)";                  break;
		case 0x80000009: pName = @"Devanagari (Mac OS)";                break;
		case 0x8000000A: pName = @"Gurmukhi (Mac OS)";                  break;
		case 0x8000000B: pName = @"Gujarati (Mac OS)";                  break;
		case 0x80000015: pName = @"Thai (Mac OS)";                      break;
		case 0x80000019: pName = @"Simplified Chinese (Mac OS)";        break;
		case 0x8000001A: pName = @"Tibetan (Mac OS)";                   break;
		case 0x8000001D: pName = @"Central European (Mac OS)";          break;
		case 0x80000022: pName = @"Dingbats (Mac OS)";                  break;
		case 0x80000023: pName = @"Turkish (Mac OS)";                   break;
		case 0x80000024: pName = @"Croatian (Mac OS)";                  break;
		case 0x80000025: pName = @"Icelandic (Mac OS)";                 break;
		case 0x80000026: pName = @"Romanian (Mac OS)";                  break;
		case 0x80000027: pName = @"Celtic (Mac OS)";                    break;
		case 0x80000028: pName = @"Gaelic (Mac OS)";                    break;
		case 0x80000029: pName = @"Keyboard Symbols (Mac OS)";          break;
		case 0x8000008C: pName = @"Farsi (Mac OS)";                     break;
		case 0x80000098: pName = @"Cyrillic (Mac OS Ukrainian)";        break;
		case 0x800000EC: pName = @"Inuit (Mac OS)";                     break;
		case 0x80000203: pName = @"Western (ISO Latin 3)";              break;
		case 0x80000204: pName = @"Central European (ISO Latin 4)";     break;
		case 0x80000205: pName = @"Cyrillic (ISO 8859-5)";              break;
		case 0x80000206: pName = @"Arabic (ISO 8859-6)";                break;
		case 0x80000207: pName = @"Greek (ISO 8859-7)";                 break;
		case 0x80000208: pName = @"Hebrew (ISO 8859-8)";                break;
		case 0x80000209: pName = @"Turkish (ISO Latin 5)";              break;
		case 0x8000020A: pName = @"Nordic (ISO Latin 6)";               break;
		case 0x8000020B: pName = @"Thai (ISO 8859-11)";                 break;
		case 0x8000020D: pName = @"Baltic (ISO Latin 7)";               break;
		case 0x8000020E: pName = @"Celtic (ISO Latin 8)";               break;
		case 0x8000020F: pName = @"Western (ISO Latin 9)";              break;
		case 0x80000210: pName = @"Romanian (ISO Latin 10)";            break;
		case 0x80000400: pName = @"Latin-US (DOS)";                     break;
		case 0x80000405: pName = @"Greek (DOS)";                        break;
		case 0x80000406: pName = @"Baltic (DOS)";                       break;
		case 0x80000410: pName = @"Western (DOS Latin 1)";              break;
		case 0x80000411: pName = @"Greek (DOS Greek 1)";                break;
		case 0x80000412: pName = @"Central European (DOS Latin 2)";     break;
		case 0x80000413: pName = @"Cyrillic (DOS)";                     break;
		case 0x80000414: pName = @"Turkish (DOS)";                      break;
		case 0x80000415: pName = @"Portuguese (DOS)";                   break;
		case 0x80000416: pName = @"Icelandic (DOS)";                    break;
		case 0x80000417: pName = @"Hebrew (DOS)";                       break;
		case 0x80000418: pName = @"Canadian French (DOS)";              break;
		case 0x80000419: pName = @"Arabic (DOS)";                       break;
		case 0x8000041A: pName = @"Nordic (DOS)";                       break;
		case 0x8000041B: pName = @"Russian (DOS)";                      break;
		case 0x8000041C: pName = @"Greek (DOS Greek 2)";                break;
		case 0x8000041D: pName = @"Thai (Windows, DOS)";                break;
		case 0x80000421: pName = @"Simplified Chinese (Windows, DOS)";  break;
		case 0x80000422: pName = @"Korean (Windows, DOS)";              break;
		case 0x80000423: pName = @"Traditional Chinese (Windows, DOS)"; break;
		case 0x80000505: pName = @"Hebrew (Windows)";                   break;
		case 0x80000506: pName = @"Arabic (Windows)";                   break;
		case 0x80000507: pName = @"Baltic (Windows)";                   break;
		case 0x80000508: pName = @"Vietnamese (Windows)";               break;
		case 0x80000628: pName = @"Japanese (Shift JIS X0213)";         break;
		case 0x80000631: pName = @"Chinese (GBK)";                      break;
		case 0x80000632: pName = @"Chinese (GB 18030)";                 break;
		case 0x80000821: pName = @"Japanese (ISO 2022-JP-2)";           break;
		case 0x80000822: pName = @"Japanese (ISO 2022-JP-1)";           break;
		case 0x80000830: pName = @"Chinese (ISO 2022-CN)";              break;
		case 0x80000840: pName = @"Korean (ISO 2022-KR)";               break;
		case 0x80000930: pName = @"Simplified Chinese (GB 2312)";       break;
		case 0x80000931: pName = @"Traditional Chinese (EUC)";          break;
		case 0x80000940: pName = @"Korean (EUC)";                       break;
		case 0x80000A01: pName = @"Japanese (Shift JIS)";               break;
		case 0x80000A02: pName = @"Cyrillic (KOI8-R)";                  break;
		case 0x80000A03: pName = @"Traditional Chinese (Big 5)";        break;
		case 0x80000A04: pName = @"Western (Mac Mail)";                 break;
		case 0x80000A05: pName = @"Simplified Chinese (HZ GB 2312)";    break;
		case 0x80000A06: pName = @"Traditional Chinese (Big 5 HKSCS)";  break;
		case 0x80000A08: pName = @"Ukrainian (KOI8-U)";                 break;
		case 0x80000A09: pName = @"Traditional Chinese (Big 5-E)";      break;
		case 0x80000C01: pName = @"Western (EBCDIC Latin Core)";        break;
		case 0x80000C02: pName = @"Western (EBCDIC Latin 1)";           break;
		case 0x84000100: pName = @"Unicode (UTF-7)";                    break;
		case 0x8C000100: pName = @"Unicode (UTF-32)";                   break;
		case 0x90000100: pName = @"Unicode (UTF-16BE)";                 break;
		case 0x94000100: pName = @"Unicode (UTF-16LE)";                 break;
		case 0x98000100: pName = @"Unicode (UTF-32BE)";                 break;
		case 0x9C000100: pName = @"Unicode (UTF-32LE)";                 break;
		default: pName = nil; break;
	}
	
	return pName;
}

//******************************************************************************
// デフォルトエンコーディング名取得
//******************************************************************************
NSString* MTStringEncodingList::GetDefaultEncodingName()
{
	unsigned int index = 0;
	NSStringEncoding defaultEncodingId = 0;
	NSString* pDefaultEncodingName = @"";
	
	//デフォルトエンコーディングID取得
	defaultEncodingId = GetDefaultEncodingId();
	
	//エンコーディングIDを一覧から検索
	for (index = 0; index < GetSize(); index++) {
		if (defaultEncodingId == GetEncodingId(index)) {
			pDefaultEncodingName = GetEncodingName(index);
			break;
		}
	}
	
	//ロケールが日本なら ShiftJIS  @"Japanese (Windows, DOS)"
	//それ以外は Windows-1252    @"Western (Windows Latin 1)"
	
	return pDefaultEncodingName;
}

//******************************************************************************
// デフォルトエンコーディングID取得
//******************************************************************************
NSStringEncoding MTStringEncodingList::GetDefaultEncodingId()
{
	NSStringEncoding encodingId = 0;
	NSArray* pLanguages = nil;
	NSString* pLanguage = nil;
	
	//選択されている言語を取得
	pLanguages = [NSLocale preferredLanguages];
	pLanguage = [pLanguages objectAtIndex:0];
	
	//言語によってエンコーディングを切り替える
    //iOS9以降はpreferredLanguagesの返却値が"ja"から"ja-JP"に変わっている
	//if ([pLanguage isEqualToString:@"ja"]) {
    if ([pLanguage hasPrefix:@"ja"]) {
		//日本語の場合 ShiftJIS
		encodingId = NSShiftJISStringEncoding;
	}
	else {
		//それ以外は Windows-1252 （ISO-8859-1の方が適切？）
		encodingId = NSWindowsCP1252StringEncoding;
	}
	
	return encodingId;
}


