package net.dev123.yibo.common;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import net.dev123.commons.ServiceProvider;
import net.dev123.commons.util.StringUtil;
import net.dev123.mblog.Emotions;
import net.dev123.yibo.R;
import net.dev123.yibo.YiBoApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.text.Spannable;
import android.text.style.ImageSpan;
import android.util.Config;
import android.util.Log;
/**
* @author Weiping Ye
* @version 创建时间:2011-9-8 下午1:03:28
**/
public class EmotionLoader {
public static final String TAG = EmotionLoader.class.getSimpleName();
public static final String BASE_TAB = "base";
//private static Logger logger = LoggerFactory.getLogger(EmotionLoader.class.getSimpleName());
private static android.graphics.BitmapFactory.Options opt = null;
private static HashMap<String, Map<String, String>> emotionTabMap
= new HashMap<String, Map<String, String>>();
private static Map<String, String[]> emotionsArrayMap = new HashMap<String, String[]>();
private static Set<String> tabNameSet = new HashSet<String>();
private static Application application = null;
private static int versionImages = 0;
private static boolean isInit = false;
private EmotionLoader(Context context) {
}
public static synchronized void init(Application app) {
if (isInit) {
return;
}
if (Config.DEBUG) {
Log.d(TAG, "init emotions...");
}
application = app;
InputStream isEmotionsFan2Jian = null;
InputStream isEmotionsSpecialized = null;
InputStream isEmotionsImages = null;
if (isEmotionsFan2Jian == null) {
isEmotionsFan2Jian = application.getResources().openRawResource(R.raw.emotions_fan2jian);
}
if (isEmotionsSpecialized == null) {
isEmotionsSpecialized = application.getResources().openRawResource(R.raw.emotions_specialized);
}
Emotions.init(isEmotionsFan2Jian, isEmotionsSpecialized);
try {
if (isEmotionsFan2Jian != null) {
isEmotionsFan2Jian.close();
}
if (isEmotionsSpecialized != null) {
isEmotionsSpecialized.close();
}
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
}
if (isEmotionsImages == null) {
isEmotionsImages = application.getResources().openRawResource(R.raw.emotions_images);
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(isEmotionsImages));
String emotionName = null;
String drawableName = null;
int equalIndex = -1;
int tabNameSeparate = -1;
String tabName = null;
String expression = null;
Map<String, String> map = null;
try {
do {
expression = bufferedReader.readLine();
if (StringUtil.isEmpty(expression) || expression.startsWith("#")) {
continue;
}
equalIndex = expression.indexOf('=');
if (equalIndex == -1) {
continue;
}
emotionName = expression.substring(0, equalIndex);
drawableName = expression.substring(equalIndex + 1, expression.length());
if (emotionName.equals("version")) {
try {
setVersionImages(Integer.valueOf(drawableName));
} catch(NumberFormatException e) {
Log.e(TAG, "Wrong versionImages: " + drawableName, e);
}
continue;
}
tabNameSeparate = drawableName.indexOf('|');
if (tabNameSeparate > -1) {
tabName = drawableName.substring(0, tabNameSeparate);
drawableName = drawableName.substring(tabNameSeparate + 1);
} else {
tabName = BASE_TAB;
}
tabNameSet.add(tabName);
map = emotionTabMap.get(tabName);
if (map == null) {
map = new LinkedHashMap<String, String>();
emotionTabMap.put(tabName, map);
}
map.put(emotionName, drawableName);
} while (expression != null);
} catch (IOException e) {
Log.e(TAG, "Failed to init emotions! " + e.getMessage(), e);
} finally {
try {
if (isEmotionsImages != null) {
isEmotionsImages.close();
}
} catch (IOException e) {
Log.e(TAG, "Failed to close stream!", e);
}
}
initEmotionArrayMap();
opt = new android.graphics.BitmapFactory.Options();
float standartDensity = 320f;
opt.inDensity = Math.round((standartDensity / YiBoApplication.getDisplayWidth()) * 160f);
isInit = true;
if (Config.DEBUG) Log.d(TAG, "init emotions complete...");
}
private static void initEmotionArrayMap() {
if (isInit) {
return;
}
String[] emotionsArray = null;
Map<String, String> emotionMap = null;
for(String key : emotionTabMap.keySet()) {
emotionsArray = new String[emotionTabMap.get(key).size()];
emotionMap = emotionTabMap.get(key);
int i = 0;
for(String subKey : emotionMap.keySet()) {
emotionsArray[i] = subKey;
i++;
}
emotionsArrayMap.put(key, emotionsArray);
}
}
public static boolean containsKey(String emotion) {
if (!isInit) {
return false;
}
String jian = Emotions.fan2Jian(emotion);
for(String key : emotionTabMap.keySet()) {
if (emotionTabMap.get(key).containsKey(jian)) {
return true;
}
}
return false;
}
public static String[] getEmotionsArray() {
return getEmotionsArray(BASE_TAB);
}
public static String[] getEmotionsArray(String tabName) {
if (!isInit) {
return null;
}
return emotionsArrayMap.get(tabName);
}
public static Drawable getDrawableByEmontionName(String emotionFileName) {
if (Constants.DEBUG) Log.d(TAG, emotionFileName);
Drawable drawable = null;
Bitmap bm = BitmapFactory.decodeFile(getEmotionsBaseDir() + emotionFileName, opt);
if (bm != null) {
drawable = new BitmapDrawable(bm);
} else {
String packageName = application.getPackageName();
int resId = 0;
if (emotionFileName.lastIndexOf('.') > -1) {
emotionFileName = emotionFileName.substring(0,
emotionFileName.lastIndexOf('.'));
}
resId = application.getResources().getIdentifier(
emotionFileName, "drawable", packageName);
if (resId == 0) {
return null;
}
drawable = application.getResources().getDrawable(resId);
}
return drawable;
}
public static Drawable getDrawableByEmontion(String emotion) {
String jian = Emotions.fan2Jian(emotion);
String emotionFileName = null;
for(String key : emotionTabMap.keySet()) {
if (emotionTabMap.get(key).containsKey(jian)) {
emotionFileName = emotionTabMap.get(key).get(jian);
}
}
if (emotionFileName == null) {
return null;
}
return getDrawableByEmontionName(emotionFileName);
}
public static Spannable getEmotionSpannable(ServiceProvider serviceProvider, String text) {
if (!isInit) {
return null;
}
if (StringUtil.isEmpty(text)) {
return null;
}
String content = Html.fromHtml(text).toString();
Spannable span = Spannable.Factory.getInstance().newSpannable(content);
Matcher m = Emotions.NORMALIZED_PATTERN.matcher(content);
Drawable drawable = null;
ImageSpan imageSpan = null;
String emotionKey = null;
while (m.find()) {
emotionKey = m.group(0);
drawable = EmotionLoader.getDrawableByEmontion(emotionKey);
if (drawable == null) {
continue;
}
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
span.setSpan(imageSpan, m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return span;
}
public static Set<String> getEmotionTabNameSet() {
return new HashSet<String>(tabNameSet);
}
public static int getVersionImages() {
return versionImages;
}
private static void setVersionImages(int versionImages) {
EmotionLoader.versionImages = versionImages;
}
public static String getEmotionsBaseDir() {
return YiBoApplication.getSdcardCachePath() + "/emotions/";
}
public static String getTraditionalToSimplifiedFilePath() {
return getEmotionsBaseDir() + "emotions_fan2jian.properties";
}
public static String getSpecializedFilePath() {
return getEmotionsBaseDir() + "emotions_specialized.properties";
}
public static String getImagesFilePath() {
return getEmotionsBaseDir() + "emotions_images.properties";
}
}