package com.uwsoft.editor.proxy;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.SystemUtils;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
import com.puremvc.patterns.proxy.BaseProxy;
import com.uwsoft.editor.Overlap2DFacade;
/**
* Created by azakhary on 4/24/2015.
*/
public class FontManager extends BaseProxy {
private static final String TAG = FontManager.class.getCanonicalName();
public static final String NAME = TAG;
private static final String cache_name = "overlap2d-fonts-cache";
private Preferences prefs;
private HashMap<String, String> systemFontMap = new HashMap<>();
public FontManager() {
super(NAME);
}
@Override
public void onRegister() {
super.onRegister();
facade = Overlap2DFacade.getInstance();
prefs = Gdx.app.getPreferences(cache_name);
generateFontsMap();
}
public String[] getSystemFontNames() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
}
public String[] getSystemFontsPaths() {
String[] result;
if (SystemUtils.IS_OS_WINDOWS) {
result = new String[1];
String path = System.getenv("WINDIR");
result[0] = path + "\\" + "Fonts";
return result;
} else if (SystemUtils.IS_OS_MAC_OSX || SystemUtils.IS_OS_MAC) {
result = new String[3];
result[0] = System.getProperty("user.home") + File.separator + "Library/Fonts";
result[1] = "/Library/Fonts";
result[2] = "/System/Library/Fonts";
return result;
} else if (SystemUtils.IS_OS_LINUX) {
String[] pathsToCheck = {
System.getProperty("user.home") + File.separator + ".fonts",
"/usr/share/fonts/truetype",
"/usr/share/fonts/TTF"
};
ArrayList<String> resultList = new ArrayList<>();
for (int i = pathsToCheck.length - 1; i >= 0; i--) {
String path = pathsToCheck[i];
File tmp = new File(path);
if (tmp.exists() && tmp.isDirectory() && tmp.canRead()) {
resultList.add(path);
}
}
if (resultList.isEmpty()) {
// TODO: show user warning, TextTool will be crash editor, because system font directories not found
result = new String[0];
}
else {
result = new String[resultList.size()];
result = resultList.toArray(result);
}
return result;
}
return null;
}
public List<File> getSystemFontFiles() {
// only retrieving ttf files
String[] extensions = new String[]{"ttf", "TTF"};
String[] paths = getSystemFontsPaths();
ArrayList<File> files = new ArrayList<>();
for (int i = 0; i < paths.length; i++) {
File fontDirectory = new File(paths[i]);
if (!fontDirectory.exists()) break;
files.addAll(FileUtils.listFiles(fontDirectory, extensions, true));
}
return files;
}
public void preCacheSystemFontsMap() {
List<File> fontFiles = getSystemFontFiles();
for (File file : fontFiles) {
Font f = null;
try {
if (!systemFontMap.containsValue(file.getAbsolutePath())) {
f = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream(file.getAbsolutePath()));
String name = f.getFamily();
systemFontMap.put(name, file.getAbsolutePath());
}
} catch (FontFormatException e) {
//e.printStackTrace();
} catch (IOException e) {
//e.printStackTrace();
}
}
prefs.put(systemFontMap);
prefs.flush();
}
public void loadCachedSystemFontMap() {
systemFontMap = (HashMap<String, String>) prefs.get();
}
public void invalidateFontMap() {
Array<String> names = new Array<>(getSystemFontNames());
for (Iterator<Map.Entry<String, String>> it = systemFontMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, String> entry = it.next();
if (!names.contains(entry.getKey(), false)) {
it.remove();
}
}
}
public void generateFontsMap() {
loadCachedSystemFontMap();
preCacheSystemFontsMap();
invalidateFontMap();
}
public HashMap<String, String> getFontsMap() {
return systemFontMap;
}
public Array<String> getFontNamesFromMap() {
AlphabeticalComparator comparator = new AlphabeticalComparator();
Array<String> fontNames = new Array<>();
for (Map.Entry<String, String> entry : systemFontMap.entrySet()) {
fontNames.add(entry.getKey());
}
fontNames.sort(comparator);
return fontNames;
}
public FileHandle getTTFByName(String fontName) {
return new FileHandle(systemFontMap.get(fontName));
}
public String getShortName(String longName) {
String path = systemFontMap.get(longName);
return FilenameUtils.getBaseName(path);
}
public String getFontFilePath(String fontFaily) {
return systemFontMap.get(fontFaily);
}
public class AlphabeticalComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
}
}