package com.framework.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * Title:StringUtils.java
 * </p>
 * <p>
 * Description:字串操作工具類
 * </p>
 * <p>
 * Copyright:Copyright (c) 2004 TECHMORE,Inc
 * </p>
 * <p>
 * Company:TECHMORE,Inc
 * </p>
 * 
 * @author Jason 2004-8-9
 * @version 1.0
 */
public class StringUtils {
	// private static final Log log = LogFactory.getLog(StringUtils.class);

	private static String defaultEncoding = "UTF-8";

	/**
	 * 對指定字串進行編碼, 不指定編碼則使用默認編碼UTF-8
	 * <p>
	 * <code>getEncodedString</code>
	 * </p>
	 * 
	 * @param s
	 *            String
	 * @param encoding
	 *            String 如果為空則使用此類的實例變量:defaultEncoding
	 * @throws UnsupportedEncodingException
	 * @return String
	 * @author Jason 2004-8-9
	 * @since 1.0
	 */
	public static String getEncodedString(String s, String encoding) throws java.io.UnsupportedEncodingException {
		if (encoding == null || "".equals(encoding.trim())) {
			encoding = defaultEncoding;
		}
		return new String(s.getBytes("ISO8859_1"), encoding);
	}

	/**
	 * 取得String的前n個字, <br>
	 * source等於null則返回null, <br>
	 * n大於source的長度則返回整個字串, <br>
	 * n小於等於0則返回null, <br>
	 * 
	 * @param source
	 *            String
	 * @param num
	 *            int
	 * @return String
	 * @author Jason 2004-8-9
	 * @since 1.0
	 */
	public static String getPrefixString(String source, int num) {
		if (num <= 0) {
			return null;
		}

		if (num > source.length()) {
			return source;
		}
		return source.substring(0, num);
	}

	/**
	 * 取得異常字串
	 * <p>
	 * <code>getExceptionStack</code>
	 * </p>
	 * 
	 * @param t
	 * @return
	 * @author Jason 2005-4-11
	 * @since 1.0
	 */
	public static String getExceptionStack(Throwable t) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw, true);
		t.printStackTrace(pw);
		return sw.getBuffer().toString();
	}

	/**
	 * 取得Object對應的字串,如果Object是Null則返回默認值def
	 * <p>
	 * <code>getString</code>
	 * </p>
	 * 
	 * @param s
	 * @param def
	 * @return
	 * @author Jason 2005-4-11
	 * @since 1.0
	 */
	public static String getString(Object s, String def) {
		if (s == null)
			return def;
		return s.toString();
	}

	/**
	 * 取得字串orig中以regex分隔的字串列表,如果orig等於null或空串,則返回空的數組
	 * <p>
	 * <code>getArray</code>
	 * </p>
	 * 
	 * @param orig
	 * @param regex
	 * @return
	 * @author Jason 2005-3-3
	 * @since 1.0
	 */
	public static String[] getArray(String orig, String regex) {
		if (orig == null || "".equals(orig.trim())) {
			return new String[0];
		}

		return orig.split(regex);
	}

	/**
	 * 取得字串orig中以regex分隔的字串列表,如果orig等於null或空串,則返回空的List
	 * <p>
	 * <code>getList</code>
	 * </p>
	 * 
	 * @param orig
	 * @param regex
	 * @return
	 * @author Jason 2005-3-3
	 * @since 1.0
	 */
	public static List getList(String orig, String regex) {
		List result = new ArrayList();

		if (orig == null || "".equals(orig.trim())) {
			return result;
		}

		String[] values = orig.split(regex);

		for (int i = 0; i < values.length; i++) {
			result.add(values[i]);
		}

		return result;
	}

	/**
	 * 用replacement替換src中所有與regex匹配的字串
	 * <p>
	 * <code>replaceAll</code>
	 * </p>
	 * 
	 * @param src
	 * @param regex
	 * @param replacement
	 * @return
	 * @author Jason 2005-3-3
	 * @since 1.0
	 */
	public static String replaceAll(String src, String regex, String replacement) {
		String result = src;

		String tempResult = src;
		while (true) {
			tempResult = replaceFirst(tempResult, regex, replacement);
			if (tempResult.equals(result)) {
				break;
			}
			result = tempResult;
		}
		return result;
	}

	/**
	 * 用replacement替換src中第一個與regex匹配的字串
	 * <p>
	 * <code>replaceFirst</code>
	 * </p>
	 * 
	 * @param src
	 * @param regex
	 * @param replacement
	 * @return
	 * @author Jason 2005-3-3
	 * @since 1.0
	 */
	public static String replaceFirst(String src, String regex, String replacement) {
		int firstStart = src.indexOf(regex);
		int firstEnd = firstStart + regex.length();

		if (firstStart >= 0) {
			StringBuffer result = new StringBuffer();
			result.append(src.subSequence(0, firstStart));
			result.append(replacement);
			result.append(src.substring(firstEnd));
			return result.toString();
		} else {
			return src;
		}
	}

	/**
	 * 將String中與Map中key對應的值都替換成Map中value的值
	 * <p>
	 * <code>replaceAll</code>
	 * </p>
	 * 
	 * @param orig
	 * @param replacementMap
	 * @return
	 * @author Jason 2005-3-9
	 * @since 1.0
	 */
	public static String replaceAll(String orig, Map replacementMap) {
		String temp = orig;

		for (Iterator it = replacementMap.keySet().iterator(); it.hasNext();) {
			String key = it.next().toString();
			temp = temp.replaceAll(key, replacementMap.get(key).toString());
		}

		return temp;
	}

	/**
	 * Check if a String has length.
	 * <p>
	 * 
	 * <pre>
	 *       StringUtils.hasLength(null) = false
	 *       StringUtils.hasLength(&quot;&quot;) = false
	 *       StringUtils.hasLength(&quot; &quot;) = true
	 *       StringUtils.hasLength(&quot;Hello&quot;) = true
	 * </pre>
	 * 
	 * @param str
	 *            the String to check, may be <code>null</code>
	 * @return <code>true</code> if the String is not null and has length
	 */
	public static boolean hasLength(Object str) {
		if (str == null) {
			return false;
		}

		String newstr = str instanceof String ? (String) str : str.toString();

		return newstr.length() > 0;
	}

	/**
	 * Check if a String has text. More specifically, returns <code>true</code> if
	 * the string not <code>null<code>, it's <code>length is > 0</code>, and it has
	 * at least one non-whitespace character.
	 * <p>
	 * 
	 * <pre>
	 *       StringUtils.hasText(null) = false
	 *       StringUtils.hasText(&quot;&quot;) = false
	 *       StringUtils.hasText(&quot; &quot;) = false
	 *       StringUtils.hasText(&quot;12345&quot;) = true
	 *       StringUtils.hasText(&quot; 12345 &quot;) = true
	 * </pre>
	 * 
	 * @param str
	 *            the String to check, may be <code>null</code>
	 * @return <code>true</code> if the String is not null, length > 0, and not
	 *         whitespace only
	 * @see java.lang.Character#isWhitespace
	 */
	public static boolean hasText(Object str) {
		int strLen;
		if (str == null) {
			return false;
		}

		String newstr = str instanceof String ? (String) str : str.toString();

		if ((strLen = newstr.length()) == 0) {
			return false;
		}

		for (int i = 0; i < strLen; i++) {
			if (!Character.isWhitespace(newstr.charAt(i))) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 組裝類似aaa/bbb/ccc/ddd這樣的字符串
	 * 
	 * @param src
	 * @param value
	 * @param regex
	 */
	public static void appendString(StringBuffer src, String value, String regex) {
		if (src == null)
			return;
		if (regex == null) {
			throw new IllegalArgumentException("分隔符不可為空!");
		}
		if (src.length() > 0) {
			src.append(regex);
		}
		src.append(value == null ? "" : value);
	}

	/**
	 * vo to string, the string is made up by all its public [get] methods exclude
	 * getInstance
	 * 
	 * @param vo
	 * @return
	 */
	public static String vo2string(Object vo) {
		StringBuffer returnValue = new StringBuffer("");
		Method[] ms = vo.getClass().getDeclaredMethods();
		for (int i = 0; i < ms.length; i++) {
			Method m = ms[i];
			String mname = m.getName();
			if (mname.startsWith("get") && !m.getReturnType().isInstance(vo)) {
				returnValue.append(mname.substring(3, 4).toLowerCase());
				returnValue.append(mname.substring(4));
				try {
					returnValue.append("=\"" + m.invoke(vo, new Object[] {}) + "\" ");
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		return returnValue.toString();
	}

	public static String vo2json(Object vo) {
		StringBuffer returnValue = new StringBuffer("{");
		Method[] ms = vo.getClass().getDeclaredMethods();
		for (int i = 0; i < ms.length; i++) {
			Method m = ms[i];
			String mname = m.getName();
			if (mname.startsWith("get") && !m.getReturnType().isInstance(vo)) {
				returnValue.append(mname.substring(3, 4).toLowerCase());
				returnValue.append(mname.substring(4));
				try {
					Object v = m.invoke(vo, new Object[] {});
					if (v == null)
						v = "";
					v = v.toString();
					v = ((String) v).replace("\n", "");
					v = ((String) v).replace("\r", "");
					returnValue.append(":\"" + v + "\"");
					if (i < ms.length - 2) {
						returnValue.append(",");
					}
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		returnValue.append("}");
		return returnValue.toString();
	}

	public static String subString(String s, int length) {
		if (s == null || s.length() <= length) {
			return s;
		} else {
			return s.substring(0, length);
		}

	}

	public static String trim(String s) {
		if (s == null)
			return null;
		return s.trim();
	}

	/**
	 * Integer like 1652356 performs as "1,652,356"
	 * 
	 * @author aquahuang
	 * @param origin
	 * @return
	 */
	public static String integerShow(Integer origin) {
		if (origin == null) {
			return "0";
		}
		String ori = origin.toString();
		StringBuffer temp = new StringBuffer();
		StringBuffer dest = new StringBuffer();
		if (ori.length() <= 3) {
			return ori;
		} else {
			// 1 652 356
			int prex = ori.length() % 3;
			if (prex != 0) {
				for (int i = prex; i < 3; i++) {
					temp.append("0");
				}
			}
			temp.append(ori);// 001 652 356
			for (int i = 0; i < temp.length() / 3; i++) {
				dest.append(temp.substring(i * 3, (i + 1) * 3)).append(",");
			} // 001,652,356,
			String deststr = dest.toString();
			if (deststr.endsWith(",")) {
				deststr = deststr.substring(0, deststr.length() - 1);
			} // 001,652,356
			for (int i = 0; i < 3; i++) {
				if (deststr.charAt(0) == '0') {
					deststr = deststr.substring(1, deststr.length());
				} else {
					break;
				}
			} // 1,652,356
			return deststr;
		}
	}

	/*
	 * private static final String[] NUMBER_STR_M = {"零", "一", "二", "三", "四", "五",
	 * "六", "七", "八", "九"};
	 * 
	 * private static final String[] BIT_STR_M = {"", "十", "百", "千", "万", "十", "百",
	 * "千", "億", "十", "百", "千"};
	 */

	private static final String[] NUMBER_STR_L = { "零", "壹", "贰", "參", "肆", "伍", "陸", "柒", "捌", "玖" };

	private static final String[] BIT_STR_L = { "", "拾", "佰", "仟", "萬", "拾", "佰", "仟", "億", "拾", "佰", "仟" };

	/**
	 * Integer like 15 performs as "拾伍"
	 * 
	 * @param digit
	 * @return String
	 * @author aquahuang 2007-8-17
	 */
	public static String convertDigit2Cn(Integer digit) {
		if (digit == null) {
			return null;
		}
		String digitStr = digit.toString();
		int len = digitStr.length();
		int i;
		String rStr, tempStr = "";
		for (i = len - 1; i >= 0; i--) {
			/* System.out.println(i+":"+digitStr.charAt(i)+","+(int)digitStr.charAt(i)); */
			tempStr = NUMBER_STR_L[digitStr.charAt(i) - 48] + BIT_STR_L[len - i - 1] + tempStr;
		}
		rStr = tempStr;
		rStr = rStr.replace("拾零", "拾");
		rStr = rStr.replace("零拾", "零");
		rStr = rStr.replace("零佰", "零");
		rStr = rStr.replace("零仟", "零");
		rStr = rStr.replace("零萬", "萬");
		for (i = 1; i <= 6; i++) {
			rStr = rStr.replace("零零", "零");
		}
		rStr = rStr.replace("零萬", "零");
		rStr = rStr.replace("零億", "億");
		rStr = rStr.replace("零零", "零");
		rStr = rStr.endsWith("零") ? rStr.substring(0, rStr.length() - 1) : rStr;

		return rStr;
	}

	public static String encodebase64String(String str) {
		// jdk 1.7
		sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
		return encoder.encodeBuffer(str.getBytes()).trim();

		// since jdk 9.0
		// Encoder encoder = Base64.getEncoder();
		// String encode = encoder.encodeToString(str.getBytes());
		// return encode;
	}
	
	public static boolean isBlank(String str) {
		if(str==null) {
			return true;
		}
		
		str = str.trim();
		if(str.length()==0) {
			return true;
		}
		
		return false;
	}
	
}