package nc.pub.toolkits;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Dictionary;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import nc.bs.framework.common.NCLocator;
import nc.itf.bd.currtype.ICurrtypeQuery;
import nc.itf.uap.IUAPQueryBS;
import nc.itf.uapecpub.reference.uap.para.SysParaInitQuery;
import nc.vo.bd.currtype.CurrtypeVO;
import nc.vo.bd.material.measdoc.MeasdocVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.data.ValueUtils;

public class Toolkits {
	/**
	 * 功能: 检查传入的参数是否为空。 如果value的类型为String，并且value.length()为0，返回true。
	 * 如果value的类型为Object[]，并且value.length为0，返回true。
	 * 如果value的类型为Collection，并且value.size()为0，返回true。
	 * 如果value的类型为Dictionary，并且value.size()为0，返回true。
	 * 如果value的类型为Map，并且value.size()为0，返回true。 否则返回false。
	 * 
	 * @param value
	 *            被检查值。
	 * @returno
	 * @return boolean 如果被检查值为null，返回true。
	 */
	@SuppressWarnings("rawtypes")
	public static boolean isEmpty(Object value) {
		if (value == null) {
			return true;
		}
		if ((value instanceof String)
				&& (((String) value).trim().length() <= 0)) {
			return true;
		}
		if ((value instanceof Object[]) && (((Object[]) value).length <= 0)) {
			return true;
		}
		// 判断数组中的值是否全部为空null.
		if (value instanceof Object[]) {
			Object[] t = (Object[]) value;
			for (int i = 0; i < t.length; i++) {
				if (t[i] != null) {
					return false;
				}
			}
			return true;
		}
		if ((value instanceof Collection) && ((Collection) value).size() <= 0) {
			return true;
		}
		if ((value instanceof Dictionary) && ((Dictionary) value).size() <= 0) {
			return true;
		}
		if ((value instanceof Map) && ((Map) value).size() <= 0) {
			return true;
		}
		return false;
	}

	/**************************************************
	 * 功能: 去掉表达式中所有无用的空格 参数: strOldString 处理前的表达式 返回值: 处理后的表达式
	 ****************************************************/
	public String completeTrim(String strOldString) {
		char chrString[];
		int length = strOldString.length();
		chrString = new char[length];

		int iStartPos = 0;

		for (int i = 0; i < length; i++) {
			if (strOldString.charAt(i) != ' ')
				chrString[iStartPos++] = strOldString.charAt(i);
		}

		String strNewString = new String(chrString);
		strNewString = strNewString.substring(0, iStartPos);
		return strNewString;
	}

	/**
	 * 功能:转换int数组为List
	 * 
	 * @param iarray
	 * @return
	 * @return:List
	 */
	@SuppressWarnings("rawtypes")
	public static LinkedList toList(int[] iarray) {
		LinkedList<Integer> list = new LinkedList<Integer>();
		for (int i = 0; i < iarray.length; i++) {
			list.add(new Integer(iarray[i]));
		}
		return list;
	}

	/**
	 * 功能：将小数value 取N位小数后四舍五入
	 * 
	 * @param value
	 *            小数
	 * @param n
	 *            保存的小数位数
	 * @return
	 */
	public static UFDouble getUfdoubleNRound(UFDouble value, int n) {
		value = new UFDouble(value).setScale(n, UFDouble.ROUND_HALF_UP);
		// value = new UFDouble(value.doubleValue(), n);
		return value;
	}

	/**
	 * 功能：将小数value 取N位小数后舍弃，直接截取
	 * 
	 * @param value
	 *            小数
	 * @param n
	 *            保存的小数位数
	 * @return
	 */
	public static UFDouble getUFDoubleNRoundDOWN(UFDouble value, int n) {
		value = new UFDouble(value).setScale(n, UFDouble.ROUND_DOWN);
		return value;
	}

	/**
	 * 功能: 转换List为int数组
	 * 
	 * @param list
	 * @return
	 * @return:int[]
	 */
	@SuppressWarnings("rawtypes")
	public static int[] toArray(List list) {
		Object[] arr1 = list.toArray();
		int[] arr2 = new int[list.size()];
		for (int i = 0; i < arr1.length; i++) {
			arr2[i] = ((Integer) arr1[i]).intValue();
		}
		return arr2;
	}

	/**
	 * 将一个String数组变成带括号字符,便于带in条件的SQL语句使用 例:('111','222','333','')
	 * 
	 * @param array
	 * @return
	 */
	public static String combinArrayToString(String[] array) {
		if (isEmpty(array)) {
			return "('')";
		}
		StringBuffer str = new StringBuffer("('");
		for (int i = 0; i < array.length; i++) {
			str.append(array[i]);
			str.append("','");
		}
		str.append("')");
		return str.toString();
	}

	/**
	 * 将一个String数组变成带括号字符,便于带in条件的SQL语句使用 例:'111','222','333',''
	 * 
	 * @param array
	 * @return
	 */
	public static String combinArrayToString2(String[] array) {

		StringBuffer str = new StringBuffer("");
		for (int i = 0; i < array.length; i++) {
			str.append("'");
			str.append(array[i]);
			str.append("',");
		}
		str.append("''");
		return str.toString();
	}

	/**
	 * 将一个String数组变成带括号字符,便于带in条件的SQL语句使用 例:'111','222','333',''
	 * 
	 * @param array
	 * @return
	 */
	public static String combinArrayToString3(String[] pkvaluses) {
		String str = "'";
		if (pkvaluses != null) {
			for (int i = 0; i < pkvaluses.length; i++) {
				if (i == pkvaluses.length - 1) {
					str += pkvaluses[i] + "'";
				} else {
					str += pkvaluses[i] + "','";
				}
			}
			return str;
		} else {
			return null;
		}
	}

	/**
	 * 功能: 替换字符
	 * 
	 * @param str_par
	 *            原始字符串
	 * @param old_item
	 *            被替换的字符串
	 * @param new_item
	 *            替换的字符串
	 * @return
	 * @return:String
	 */
	public static synchronized String replaceAll(String str_par,
			String old_item, String new_item) {
		String str_return = "";
		String str_remain = str_par;
		boolean bo_1 = true;
		while (bo_1) {
			int li_pos = str_remain.indexOf(old_item);
			if (li_pos < 0) {
				break;
			} // 如果找不到,则返回
			String str_prefix = str_remain.substring(0, li_pos);
			str_return = str_return + str_prefix + new_item; // 将结果字符串加上原来前辍
			str_remain = str_remain.substring(li_pos + old_item.length(),
					str_remain.length());
		}
		str_return = str_return + str_remain; // 将剩余的加上
		return str_return;
	}

	/**
	 * 合计
	 * 
	 * @param value
	 * @return
	 */
	public static double total(double[] value) {
		double j = 0;
		for (int i = 0; i < value.length; i++) {
			j = j + value[i];
		}
		return j;
	}

	/**
	 * 功能: 比较两个字符串的大小,返回true表示后面比前面大
	 * 
	 * @param String
	 *            sa,String sb要比较的两个字符串
	 * @return boolean
	 */
	public static boolean compareStr(String sa, String sb) {
		boolean flag = false;
		int i = sa.compareTo(sb);
		if (i < 0) {
			flag = true;
			return flag;
		}
		return flag;
	}

	/**
	 * 功能: 比较两个数值的大小,返回true表示后面比前面大
	 * 
	 * @param String
	 *            sa,String sb要比较的两个字符串
	 * @return boolean
	 */
	public static boolean compareDou(UFDouble sa, UFDouble sb) {
		boolean flag = false;
		int i = sa.compareTo(sb);
		if (i < 0) {
			flag = true;
			return flag;
		}
		return flag;
	}

	// 把"1"转化成1时用下标找TOBIG[1]就是对应的
	private static final String[] TOBIG = new String[] { "零", "壹", "贰", "叁",
			"肆", "伍", "陆", "柒", "捌", "玖" };
	// 这里是单位从低到高的排列
	private static final String POS[] = new String[] { "", "拾", "佰", "仟", "万",
			"拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿" };

	/**
	 * 将数字转换成大写
	 * 
	 * @param number
	 *            java.lang.string
	 * @autor shipeng
	 * @return java.lang.String
	 */
	public static String getCapital(String number) {
		String capital;
		int len_zs = number.indexOf("."); // 整数
		if (len_zs < 0) {
			capital = getCapitalOfInt(number) + "整";// .concat("整");
		} else {
			int len_xs = number.substring(len_zs).length(); // 小数
			capital = getCapitalOfInt(number.substring(0, len_zs)).concat("点")
					.concat(getCapitalOfFloat(number.substring(len_zs + 1,
							len_zs + len_xs)));
		}
		return capital;
	}

	/**
	 * 将整数转换成大写
	 * 
	 * @return java.lang.String
	 * */
	public static String getCapitalOfInt(String str) {
		String newStr = "";
		for (int i = 0, j = str.length(); i < j; i++) {
			String s = str.substring(j - i - 1, j - i);
			newStr = TOBIG[Integer.parseInt(s)].concat(POS[i]) + newStr;
		}
		newStr = newStr.replace("零仟", "零");
		newStr = newStr.replace("零佰", "零");
		newStr = newStr.replace("零拾", "零");
		newStr = newStr.replace("零万", "万");
		for (int i = 0; i < 8; i++)
			newStr = newStr.replace("零零", "零");
		newStr = newStr.replace("零仟", "仟");
		newStr = newStr.replace("零佰", "佰");
		newStr = newStr.replace("零拾", "拾");
		newStr = newStr.replace("零万", "万");
		newStr = newStr.replace("零亿", "亿");
		if (newStr.endsWith("零"))
			newStr = newStr.substring(0, newStr.length() - 1);
		return newStr;
	}

	/**
	 * 将小数转换成大写
	 * 
	 * @return java.lang.String
	 * */
	public static String getCapitalOfFloat(String str) {
		String newStr = "";
		for (int i = 0, j = str.length(); i < j; i++) {
			String s = str.substring(j - i - 1, j - i);
			newStr = TOBIG[Integer.parseInt(s)] + newStr;
		}
		return newStr;
	}

	public static UFDate getUFDate(Object obj) {
		if (!Toolkits.isEmpty(obj)) {
			try {
				return new UFDate(obj.toString().trim());
			} catch (Exception e) {
				return null;
			}
		} else {
			return null;
		}
	}

	public static UFDouble getUFDouble(Object obj) {
		if (!Toolkits.isEmpty(obj)) {
			try {
				return new UFDouble(obj.toString().trim());
			} catch (Exception e) {
				return new UFDouble(0);
			}
		} else {
			return new UFDouble(0);
		}
	}

	public static UFBoolean getUFBoolean(Object obj) {
		if (!Toolkits.isEmpty(obj)) {
			try {
				return new UFBoolean(obj.toString().trim());
			} catch (Exception e) {
				return UFBoolean.FALSE;
			}
		} else {
			return UFBoolean.FALSE;
		}
	}

	public static UFDouble getUFDouble(String obj) {
		if (!Toolkits.isEmpty(obj)) {
			try {
				return new UFDouble(obj.trim());
			} catch (Exception e) {
				return new UFDouble(0);
			}
		} else {
			return new UFDouble(0);
		}
	}

	public static UFDouble getUFDouble(UFDouble ufd) {
		if (!Toolkits.isEmpty(ufd)) {
			try {
				return ufd;
			} catch (Exception e) {
				return new UFDouble(0);
			}
		} else {
			return new UFDouble(0);
		}
	}

	public static Integer getInteger(Object obj) {
		if (!Toolkits.isEmpty(obj)) {
			try {
				return Integer.parseInt(obj.toString().trim());
			} catch (Exception e) {
				return new Integer(0);
			}
		} else {
			return new Integer(0);
		}
	}

	public static Integer getInteger(String obj) {
		if (!Toolkits.isEmpty(obj)) {
			try {
				return Integer.parseInt(obj.trim());
			} catch (Exception e) {
				return new Integer(0);
			}
		} else {
			return new Integer(0);
		}
	}

	public static String getString(String obj) {
		if (!Toolkits.isEmpty(obj)) {
			try {
				return obj == null ? "" : obj.trim();
			} catch (Exception e) {
				return "";
			}
		} else {
			return "";
		}
	}

	public static String getString(Object obj) {
		if (!Toolkits.isEmpty(obj)) {
			try {
				return obj == null ? "" : obj.toString().trim();
			} catch (Exception e) {
				return "";
			}
		} else {
			return "";
		}
	}

	/**
	 * 
	 * @Title: cutZero
	 * @Description: 去掉小数后面的0
	 * @date 2013-8-28 下午06:04:11
	 * @return String 返回类型
	 * @throws
	 */
	public static String cutZero(String v) {
		if (v.indexOf(".") > -1) {
			while (true) {
				if (v.lastIndexOf("0") == (v.length() - 1)) {
					v = v.substring(0, v.lastIndexOf("0"));
				} else {
					break;
				}
			}
			if (v.lastIndexOf(".") == (v.length() - 1)) {
				v = v.substring(0, v.lastIndexOf("."));
			}
		}
		return v;
	}

	/**
	 * <b>function:</b> 处理oracle sql 语句in子句中（where id in (1, 2, ..., 1000,
	 * 1001)），如果子句中超过1000项就会报错。 这主要是oracle考虑性能问题做的限制。如果要解决次问题，可以用 where id (1,
	 * 2, ..., 1000) or id (1001, ...)
	 * 
	 * @createDate 2013-01-15下午02:36:03
	 * @param ids
	 *            in语句中的集合对象
	 * @param count
	 *            in语句中出现的条件个数
	 * @param field
	 *            in语句对应的数据库查询字段
	 * @return 返回 field in (...) or field in (...) 字符串
	 */
	public static String getOracleSQLIn(List<String> ids, int count,
			String field) {
		if (ids != null && ids.size() > 0) {
			count = Math.min(count, 1000);
			int len = ids.size();
			int size = len % count;
			if (size == 0) {
				size = len / count;
			} else {
				size = (len / count) + 1;
			}
			StringBuilder builder = new StringBuilder();
			for (int i = 0; i < size; i++) {
				int fromIndex = i * count;
				int toIndex = Math.min(fromIndex + count, len);
				String productId = StringUtils.defaultIfEmpty(StringUtils.join(
						ids.subList(fromIndex, toIndex).iterator(), "','"), "");
				if (i != 0) {
					builder.append(" or ");
				}
				builder.append(field).append(" in ('").append(productId)
						.append("')");
			}
			String result = " ("
					+ StringUtils.defaultIfEmpty(builder.toString(), field
							+ " in ('')") + ") ";
			return result;
		}
		return null;
	}

	/**
	 * <b>function:</b> 处理oracle sql 语句not in子句中（where id not in (1, 2, ...,
	 * 1000, 1001)），如果子句中超过1000项就会报错。 这主要是oracle考虑性能问题做的限制。如果要解决次问题，可以用 where id
	 * (1, 2, ..., 1000) or id (1001, ...)
	 * 
	 * @createDate 2013-01-15下午02:36:03
	 * @param ids
	 *            not in语句中的集合对象
	 * @param count
	 *            not in语句中出现的条件个数
	 * @param field
	 *            not in语句对应的数据库查询字段
	 * @return 返回 field in (...) or field in (...) 字符串
	 */
	public static String getOracleSQLNOTIn(List<String> ids, int count,
			String field) {
		if (ids != null && ids.size() > 0) {
			count = Math.min(count, 1000);
			int len = ids.size();
			int size = len % count;
			if (size == 0) {
				size = len / count;
			} else {
				size = (len / count) + 1;
			}
			StringBuilder builder = new StringBuilder();
			for (int i = 0; i < size; i++) {
				int fromIndex = i * count;
				int toIndex = Math.min(fromIndex + count, len);
				String productId = StringUtils.defaultIfEmpty(StringUtils.join(
						ids.subList(fromIndex, toIndex).iterator(), "','"), "");
				if (i != 0) {
					builder.append(" and ");
				}
				builder.append(field).append(" not in ('").append(productId)
						.append("')");
			}
			String reusltStr = " ("
					+ StringUtils.defaultIfEmpty(builder.toString(), field
							+ " not in ('')") + ") ";
			return reusltStr;
		}
		return null;
	}

	/**
	 * @param pk_group
	 *            : 这里传入集团主键
	 * @return 通过参数编码，找到对应的值
	 * 
	 */
	public static int getSalePoPricDigit(String pk_group) {
		int digit = ValueUtils.getInt(SysParaInitQuery.queryByParaCode(
				pk_group, "NC004").getValue());
		return digit;
	}

	/**
	 * @param pk_currtype
	 *            : 币种主键
	 * @return 通过币种主键取到该币种对应金额的小数点位数 add by gdt
	 * @throws BusinessException
	 */
	public static int getMnyDigitByCurrtype(String pk_currtype)
			throws BusinessException {
		ICurrtypeQuery ict = NCLocator.getInstance().lookup(
				ICurrtypeQuery.class);
		CurrtypeVO cvo = ict.findCurrtypeVOByPK(pk_currtype);
		return cvo.getCurrdigit();
	}

	/**
	 * @param pk_measdoc
	 *            : 计量单位主键
	 * @return 通过计量单位主键取到该计量单位对应数量的小数点位数 add by gdt
	 * @throws BusinessException
	 */
	public static int getNumDigitByMeas(String pk_measdoc)
			throws BusinessException {
		IUAPQueryBS qbs = NCLocator.getInstance().lookup(IUAPQueryBS.class);
		MeasdocVO mvo = (MeasdocVO) qbs.retrieveByPK(MeasdocVO.class,
				pk_measdoc);
		return mvo.getBitnumber();
	}

	// public static UFDouble getRoundUFDouble(UFDouble value, int scal) {
	// return new UFDouble(value.doubleValue(), scal);
	// }

	/**
	 * 
	 * @param TimeType
	 * 
	 * @param 0:yyyy-MM-dd HH:mm:ss
	 * @param 1:yyyyMMddHHmmss
	 * @param 2：yyyyMM
	 * @param 3:yyyy-MM-dd
	 * @param 默认为0
	 * @return 返回的时间类型
	 */
	public static String getNowTime(Integer TimeType, String strdate) {
		Date date = new Date();
		if (!isEmpty(strdate)) {
			date = getUFDate(strdate).toDate();
		}
		SimpleDateFormat from = null;
		switch (TimeType) {
		case 0:
			from = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			break;
		case 1:
			from = new SimpleDateFormat("yyyyMMddHHmmss");
			break;
		case 2:
			from = new SimpleDateFormat("yyyyMM");
			break;
		case 3:
			from = new SimpleDateFormat("yyyy-MM-dd");
			break;
		default:
			from = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			break;
		}
		return from.format(date);
	}

	public static String stringToAscii(String value) {
		StringBuffer sbu = new StringBuffer();
		char[] chars = value.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			if (i != chars.length - 1) {
				sbu.append((int) chars[i]).append(",");
			} else {
				sbu.append((int) chars[i]);
			}
		}
		return sbu.toString();
	}

	public static String asciiToString(String value) {
		StringBuffer sbu = new StringBuffer();
		String[] chars = value.split(",");
		for (int i = 0; i < chars.length; i++) {
			sbu.append((char) Integer.parseInt(chars[i]));
		}
		return sbu.toString();
	}

	/**
	 * 获取当前系统时间
	 * 
	 * @return
	 */
	public static String getSystemTime() {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS")
				.format(new Date());
	}

}