package cn.smssdk.gui;
import static com.mob.tools.utils.R.getRawRes;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.zip.GZIPInputStream;
import cn.smssdk.utils.SMSLog;
import com.mob.tools.utils.Hashon;
import android.content.Context;
public class SearchEngine {
private static final String DB_FILE = "smssdk_pydb";
private static HashMap<String, Object> hanzi2Pinyin;
private boolean caseSensitive;
private ArrayList<SearchIndex> index;
public static void prepare(final Context context, final Runnable afterPrepare) {
Runnable act = new Runnable() {
public void run() {
synchronized (DB_FILE) {
if (hanzi2Pinyin == null || hanzi2Pinyin.size() <= 0) {
try {
int resId = getRawRes(context, DB_FILE);
if (resId <= 0) {
hanzi2Pinyin = new HashMap<String, Object>();
} else {
InputStream is = context.getResources().openRawResource(resId);
GZIPInputStream gzis = new GZIPInputStream(is);
InputStreamReader isr = new InputStreamReader(gzis);
BufferedReader br = new BufferedReader(isr);
String json = br.readLine();
br.close();
hanzi2Pinyin = new Hashon().fromJson(json);
}
} catch (Throwable t) {
SMSLog.getInstance().w(t);
hanzi2Pinyin = new HashMap<String, Object>();
}
}
if (afterPrepare != null) {
afterPrepare.run();
}
}
}
};
if (afterPrepare != null) {
new Thread(act).start();
} else {
act.run();
}
}
public void setCaseSensitive(boolean caseSensitive) {
this.caseSensitive = caseSensitive;
}
public void setIndex(ArrayList<String> index) {
this.index = new ArrayList<SearchIndex>();
for (String i : index) {
this.index.add(new SearchIndex(i, hanzi2Pinyin));
}
}
public ArrayList<String> match(String token) {
ArrayList<String> res = new ArrayList<String>();
if (index == null) {
return res;
}
for (SearchIndex si : index) {
if (si.match(token, caseSensitive)) {
res.add(si.getText());
}
}
return res;
}
private static class SearchIndex {
private String text;
private ArrayList<String> pinyin;
private ArrayList<String> firstLatters;
public SearchIndex(String text, HashMap<String, Object> hanzi2Pinyin) {
this.text = text;
this.pinyin = new ArrayList<String>();
firstLatters = new ArrayList<String>();
createPinyinList(hanzi2Pinyin);
}
private void createPinyinList(HashMap<String, Object> hanzi2Pinyin) {
if (hanzi2Pinyin != null && hanzi2Pinyin.size() > 0) {
char[] cArr = text.toCharArray();
ArrayList<String[]> pinyin = new ArrayList<String[]>();
for (char c : cArr) {
String s = String.valueOf(c);
@SuppressWarnings("unchecked")
ArrayList<HashMap<String, Object>> yins
= (ArrayList<HashMap<String, Object>>) hanzi2Pinyin.get(s);
int size = yins == null ? 0 : yins.size();
String[] py = new String[size];
for (int i = 0; i < size; i++) {
String yin = (String) yins.get(i).get("yin");
if ("none".equals(yin)) {
yin = "";
}
py[i] = yin;
}
pinyin.add(py);
}
HashSet<String> pyRes = new HashSet<String>();
HashSet<String> flRes = new HashSet<String>();
toPinyinArray("", "", pyRes, flRes, pinyin);
this.pinyin.addAll(pyRes);
firstLatters.addAll(flRes);
}
}
private void toPinyinArray(String base, String firstLatter, HashSet<String> pyRes,
HashSet<String> flRes, ArrayList<String[]> pys) {
if (pys.size() > 0) {
String[] py = pys.get(0);
ArrayList<String[]> cpys = new ArrayList<String[]>();
cpys.addAll(pys);
cpys.remove(0);
for (String y : py) {
if (y.length() > 0) {
toPinyinArray(base + y, firstLatter + y.charAt(0), pyRes, flRes, cpys);
} else {
toPinyinArray(base, firstLatter, pyRes, flRes, cpys);
}
}
} else {
pyRes.add(base);
flRes.add(firstLatter);
}
}
public String getText() {
return text;
}
private boolean match(String token, boolean caseSensitive) {
if (token == null || token.trim().length() <= 0) {
return true;
}
String keyToSearch = token;
if (!caseSensitive) {
keyToSearch = token.toLowerCase();
}
if (text != null && text.toLowerCase().contains(keyToSearch)) {
return true;
}
for (String py : pinyin) {
if (py.contains(keyToSearch)) {
return true;
}
}
for (String fl : firstLatters) {
if (fl.contains(keyToSearch)) {
return true;
}
}
return false;
}
public String toString() {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("text", text);
map.put("pinyin", pinyin);
map.put("firstLatters", firstLatters);
return map.toString();
}
}
}