package net.cgt.weixin.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.cgt.weixin.R;
import net.cgt.weixin.domain.ChatEmoji;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ImageSpan;

/**
 * 表情转换工具
 * 
 * @author lijian
 * @date 2014-12-11 22:59:16
 */
public class FaceConversionUtil {

	private static final String LOGTAG = LogUtil.makeLogTag(FaceConversionUtil.class);

	/** 每一页表情的个数 */
	private int pageSize = 20;

	private static FaceConversionUtil mFaceConversionUtil;

	/** 保存于内存中的表情HashMap(key:[可爱]; value:emoji_1) */
	private HashMap<String, String> mMap_emoji = new HashMap<String, String>();

	/** 保存于内存中的表情集合 */
	private List<ChatEmoji> mList_emoji = new ArrayList<ChatEmoji>();

	/** 表情分页的结果集合 */
	public List<List<ChatEmoji>> emojiLists = new ArrayList<List<ChatEmoji>>();

	private FaceConversionUtil() {

	}

	public static FaceConversionUtil getInstace() {
		if (mFaceConversionUtil == null) {
			mFaceConversionUtil = new FaceConversionUtil();
		}
		return mFaceConversionUtil;
	}

	/**
	 * 得到一个SpanableString对象,通过传入的字符串,并进行正则判断<br>
	 * 将特定字符转换成对应"表情"
	 * 
	 * @param context 上下文
	 * @param str 要被匹配的字符串
	 * @return
	 */
	public SpannableString getExpressionString(Context context, String str) {
		SpannableString spannableString = new SpannableString(str);
		// 正则表达式匹配字符串里是否含有表情,如: 我好[开心]啊
		String zhengze = "\\[[^\\]]+\\]";
		// 通过传入的正则表达式来生成一个pattern
		Pattern sinaPatten = Pattern.compile(zhengze, Pattern.CASE_INSENSITIVE);
		try {
			dealExpression(context, spannableString, sinaPatten, 0);
		} catch (Exception e) {
			L.e(LOGTAG, e.getMessage());
		}
		return spannableString;
	}

	/**
	 * 添加表情
	 * 
	 * @param context 上下文
	 * @param imgId
	 * @param spannableString
	 * @return
	 */
	public SpannableString addFace(Context context, int imgId, String spannableString) {
		if (TextUtils.isEmpty(spannableString)) {
			return null;
		}
		Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), imgId);
		bitmap = Bitmap.createScaledBitmap(bitmap, 48, 48, true);
		ImageSpan imageSpan = new ImageSpan(context, bitmap);
		SpannableString spannable = new SpannableString(spannableString);
		spannable.setSpan(imageSpan, 0, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		return spannable;
	}

	/**
	 * 对spanableString进行正则判断,如果符合要求,则以表情图片代替
	 * 
	 * @param context 上下文
	 * @param spannableString 一个SpannableString对象
	 * @param patten 一个Pattern对象(正则)
	 * @param start 起始位置
	 * @throws Exception
	 */
	private void dealExpression(Context context, SpannableString spannableString, Pattern patten, int start) throws Exception {
		Matcher matcher = patten.matcher(spannableString);
		while (matcher.find()) {//尝试查找与该模式匹配的输入序列的下一个子序列
			String key = matcher.group();//返回由以前匹配操作所匹配的输入子序列
			// 返回第一个字符的索引的文本匹配整个正则表达式,ture 则继续递归
			if (matcher.start() < start) {//返回以前匹配的初始索引
				continue;
			}
			String value = mMap_emoji.get(key);
			if (TextUtils.isEmpty(value)) {
				continue;
			}
			int resId = context.getResources().getIdentifier(value, "drawable", context.getPackageName());
			// 通过上面匹配得到的字符串来生成图片资源id
			// Field field=R.drawable.class.getDeclaredField(value);
			// int resId=Integer.parseInt(field.get(null).toString());
			if (resId != 0) {
				Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId);
				bitmap = Bitmap.createScaledBitmap(bitmap, DensityUtil.dip2px(context, 48), DensityUtil.dip2px(context, 48), true);
				// 通过图片资源id来得到bitmap,用一个ImageSpan来包装
				ImageSpan imageSpan = new ImageSpan(bitmap);
				// 计算该图片名字的长度,也就是要替换的字符串的长度
				int end = matcher.start() + key.length();
				// 将该图片替换字符串中规定的位置中
				spannableString.setSpan(imageSpan, matcher.start(), end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
				if (end < spannableString.length()) {
					// 如果整个字符串还未验证完,则继续。。
					dealExpression(context, spannableString, patten, end);
				}
				break;
			}
		}
	}

	/**
	 * 加载文本文件(表情清单文件)
	 * 
	 * @param context
	 */
	public void getFileText(Context context) {
		ParseData(FileUtils.getEmojiFile(context), context);
	}

	/**
	 * 解析字符
	 * 
	 * @param data
	 */
	private void ParseData(List<String> data, Context context) {
		if (data == null) {
			return;
		}
		ChatEmoji emoji;
		try {
			for (String str : data) {
				String[] text = str.split(",");
				String fileName = text[0].substring(0, text[0].lastIndexOf("."));
				mMap_emoji.put(text[1], fileName);
				int resID = context.getResources().getIdentifier(fileName, "drawable", context.getPackageName());

				if (resID != 0) {
					emoji = new ChatEmoji();
					emoji.setId(resID);
					emoji.setDescription(text[1]);//可爱
					emoji.setFaceName(fileName);//emoji_1
					mList_emoji.add(emoji);
				}
			}
			//每页20个,总共能生成多少页
			int pageCount = (int) Math.ceil(mList_emoji.size() / 20 + 0.1);

			for (int i = 0; i < pageCount; i++) {
				emojiLists.add(getData(i));
			}
		} catch (Exception e) {
			e.printStackTrace();
			L.e(LOGTAG, "ParseData--->" + e);
		}
	}

	/**
	 * 获取分页数据
	 * 
	 * @param page
	 * @return
	 */
	private List<ChatEmoji> getData(int page) {
		int startIndex = page * pageSize;//第page页的表情开始
		int endIndex = startIndex + pageSize;//第page页的表情结束

		//处理最后一页不足20个表情的问题,避免角标越界
		if (endIndex > mList_emoji.size()) {
			endIndex = mList_emoji.size();
		}
		// 不这么写,会在viewpager加载中报集合操作异常,我也不知道为什么
		List<ChatEmoji> list = new ArrayList<ChatEmoji>();
		list.addAll(mList_emoji.subList(startIndex, endIndex));
		if (list.size() < pageSize) {//一页不足20个表情的,给其添加空表情对象,以凑齐20个
			for (int i = list.size(); i < pageSize; i++) {
				ChatEmoji empty_ChatEmoji = new ChatEmoji();
				list.add(empty_ChatEmoji);
			}
		}
		if (list.size() == pageSize) {
			ChatEmoji object = new ChatEmoji();
			object.setId(R.drawable.cgt_selector_chat_emoji_del_bg);
			list.add(object);
		}
		return list;
	}
}