using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Cryville.Common.Font {
	public abstract class FontManager {
		public IReadOnlyDictionary<string, Typeface> MapFullNameToTypeface { get; private set; }
		public IReadOnlyDictionary<string, IReadOnlyCollection<Typeface>> MapNameToTypefaces { get; private set; }
		public FontManager() {
			var map1 = new Dictionary<string, Typeface>();
			var map2 = new Dictionary<string, List<Typeface>>();
			foreach (var f in EnumerateAllTypefaces()) {
				if (!map1.ContainsKey(f.FullName)) {
					map1.Add(f.FullName, f);
				}
				else {
					continue;
				}
				List<Typeface> set2;
				if (!map2.TryGetValue(f.FamilyName, out set2)) {
					map2.Add(f.FamilyName, set2 = new List<Typeface>());
				}
				set2.Add(f);
			}
			MapFullNameToTypeface = map1;
			MapNameToTypefaces = map2.ToDictionary(i => i.Key, i => (IReadOnlyCollection<Typeface>)i.Value);
		}
		protected abstract IEnumerable<Typeface> EnumerateAllTypefaces();
		protected static IEnumerable<Typeface> ScanDirectoryForTypefaces(string dir) {
			foreach (var f in new DirectoryInfo(dir).EnumerateFiles()) {
				FontFile file;
				try {
					file = FontFile.Create(f);
				}
				catch (InvalidDataException) {
					continue;
				}
				if (file == null) continue;
				var enumerator = file.GetEnumerator();
				while (enumerator.MoveNext()) {
					Typeface ret;
					try {
						ret = enumerator.Current;
					}
					catch (InvalidDataException) {
						continue;
					}
					yield return ret;
				}
				file.Close();
			}
		}
	}
	public class FontManagerAndroid : FontManager {
		protected override IEnumerable<Typeface> EnumerateAllTypefaces() {
			return ScanDirectoryForTypefaces("/system/fonts");
		}
	}
	public class FontManagerWindows : FontManager {
		protected override IEnumerable<Typeface> EnumerateAllTypefaces() {
			return ScanDirectoryForTypefaces("C:/Windows/Fonts");
		}
	}
}
