package com.rrtx.services.common.utils;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;


public class CommonUtil {

    //数字
    public static final String REG_NUMBER = ".*\\d+.*";
    //大写字母
    public static final String REG_UPPERCASE = ".*[A-Z]+.*";
    //小写字母
    public static final String REG_LOWERCASE = ".*[a-z]+.*";
    //长度
    public static final String REG_LENGTH = ".{8,16}";

	/**
	 * 判断登录密码是否符合规则：密码长度8-16位，包含大小写字母，数字
	 * 判断登录密码是否含有特殊字符
	 * @param pwd
	 * @return
	 */
	public static boolean isLoginPwd(String pwd){
//		String pwdRegex = "(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[a-zA-Z0-9]{8,16}";
        Boolean flag = true;
        Boolean Lenglag = pwd.matches(REG_LENGTH);
        Boolean numFlag = pwd.matches(REG_NUMBER);
        Boolean upperCase = pwd.matches(REG_UPPERCASE);
        Boolean lowerCase = pwd.matches(REG_LOWERCASE);
        System.out.println(" Lenglag = "+Lenglag+"\n numFlag == "+numFlag+ "\n upperCase = "+upperCase +"\n lowerCase="+lowerCase);
        if(numFlag && upperCase && lowerCase && Lenglag){
//           String specialChar = "@;&;#;$";
            String specialChar = TranslateUtil.val4Sys("SPECIAL_CHARACTER");
            if(specialChar == null){
                flag = false;
                return flag;
            }else{
                String[] specialChars = specialChar.split(";");
                for(String sc : specialChars){
                    if(pwd.contains(sc)){
                        flag = true;
                        break;
                    }else{
                        flag = false;
                        continue;
                    }
                }
            }
        }else{
            flag = false;
        }


        return flag;

	}

	private final static String pwdRegex = "(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[a-zA-Z0-9]{8,16}";

	private final static double EARTH_RADIUS = 6378.137;

	public static boolean isMatches(String str, String matcher){ 
		   Pattern pattern = Pattern.compile(matcher); 
		   Matcher isMatches = pattern.matcher(str);
		   if( !isMatches.matches() ){
		       return false; 
		   } 
		   return true; 
	}

    /***
     * 手机号校验
     * @param str
     * @return
     */
    public static boolean isMobile(String str)
    {
        String regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$";

        if(str.length() != 11){
            return false;
        }else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(str);
            if(m.matches() == false){
                return false;
            }else{
                return true;
            }
        }

    }

	 public static boolean isMoney(String str) 
    { 
        Pattern pattern= Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$"); // 判断小数点后2位的数字的正则表达式
        Matcher match=pattern.matcher(str);
        if(match.matches()==false) 
        { 
           return false; 
        } 
        else 
        { 
           return true; 
        } 
    }
	 
	/**
	 * 格式化金额
	 * 
	 * @param str
	 * @return
	 */
	public static String formatCurrency(String str) {
		if(isEmpty(str)) {
			return "0";
		}
		return new DecimalFormat(",##0.00").format((new BigDecimal(str)).doubleValue());
	}
	
	/**
	 * 格式化金额
	 * 
	 * @param str
	 * @return
	 */
	public static String formatCurrency4Point(String str) {
		if(isEmpty(str)) {
			return "0";
		}
		return new DecimalFormat(",##0.0000").format((new BigDecimal(str)).doubleValue());
	}
	/**
	 * obj to String
	 * 
	 * @param pObject
	 * @return
	 */
	public static String objToString(Object pObject) {
		String strValue = "";
		try {
			strValue = pObject.toString();
		} catch (Exception e) {
			strValue = "";
		}
		if ("null".equals(strValue)) {
			strValue = "";
		}
		return strValue;
	}

	/**
	 * 
	 * @param pObject
	 * @return
	 */
	public static BigDecimal objToBigDecimal(final Object pObject) {
		BigDecimal result = null;
		String str = "";

		if (pObject != null) {
			str = pObject.toString();
		} else {
			str = "";
		}

		try {
			if ("".equals(str)) {
				return new BigDecimal(0);
			} else {
				result = new BigDecimal(str);
			}
		} catch (NumberFormatException e) {
			return BigDecimal.ZERO;
		}
//		 result = result.setScale(2, RoundingMode.HALF_UP);
		return result;
	}

	public static int objToint(final Object pObject) {
		int intReturn = 0;
		int intIndex = 0;
		try {
			if (pObject != null && !("".equals(pObject.toString().trim()))) {
				String strObject = pObject.toString().trim();
				intIndex = strObject.indexOf(".");
				if (intIndex == -1) {
					intReturn = new Integer(strObject).intValue();
				} else {
					intReturn = new Integer(strObject.substring(0, intIndex))
							.intValue();
				}
			} else {
				intReturn = 0;
			}
		} catch (Exception e) {
			intReturn = 0;
		}
		return intReturn;
	}

	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}

	public static boolean isEmpty(String str) {
		if (str == null 
				|| "".equals(str) 
				|| "null".equals(str) 
				|| "undefined".equals(str)) {
			return true;
		}
		return false;
	}

	/**
	 * str1 加上 str2
	 * 
	 * @param str1
	 * @param str2
	 * @return
	 */
	public static String add(String str1, String str2) {
		return objToString(objToBigDecimal(str1).add(objToBigDecimal(str2)));
	}

	public static String add(Object str1, Object str2) {
		return objToString(objToBigDecimal(str1).add(objToBigDecimal(str2)));
	}
	/**
	 * str1 减去 str2
	 * 
	 * @param str1
	 * @param str2
	 * @return
	 */
	public static String subtract(String str1, String str2) {
		return objToString(objToBigDecimal(str1)
				.subtract(objToBigDecimal(str2)));
	}

	/**
	 * 比较
	 * 
	 * @param str1
	 * @param str2
	 * @return 0 : str1 == str2 1 : str1 > str2 -1 : str1 < str2
	 */
	public static int compare(String str1, String str2) {
		if (str1 == null || "".equals(str1) || "null".equals(str1)) {
			str1 = "0";
		}
		if (str2 == null || "".equals(str2) || "null".equals(str2)) {
			str2 = "0";
		}
		BigDecimal big1 = new BigDecimal(str1);
		BigDecimal big2 = new BigDecimal(str2);
		int iRet = big1.compareTo(big2);
		if (iRet > 0) {
			return 1;
		} else if (iRet < 0) {
			return -1;
		}

		return 0;
	}

	/**
	 * 相除
	 * 
	 * @param str1
	 * @param str2
	 * @return
	 */
	public static String divide(String str1, String str2) {
		if (str1 == null || "".equals(str1) || "null".equals(str1)) {
			str1 = "0";
		}
		if (str2 == null || "".equals(str2) || "null".equals(str2)) {
			str2 = "0";
		}
		BigDecimal big1 = new BigDecimal(str1);
		BigDecimal big2 = new BigDecimal(str2);
		BigDecimal iRet = big1.divide(big2);
		return iRet.toString();
	}

	/**
	 * 相乘
	 * 
	 * @param str1
	 * @param str2
	 * @return
	 */
	public static String multiply(String str1, String str2) {
		if (str1 == null || "".equals(str1) || "null".equals(str1)) {
			str1 = "0";
		}
		if (str2 == null || "".equals(str2) || "null".equals(str2)) {
			str2 = "0";
		}
		BigDecimal big1 = new BigDecimal(str1);
		BigDecimal big2 = new BigDecimal(str2);
		BigDecimal iRet = big1.multiply(big2);
		return iRet.toString();
	}

	public static String multiply(String str1, String str2, int pointWs) {
		
		return objToString(objToBigDecimal(multiply(str1, str2)).setScale(pointWs, BigDecimal.ROUND_HALF_UP));
	}
	public static String divide(String str1, String str2, int pointWs) {
		
		if (str1 == null || "".equals(str1) || "null".equals(str1)) {
			str1 = "0";
		}
		if (str2 == null || "".equals(str2) || "null".equals(str2)) {
			str2 = "0";
		}
		BigDecimal big1 = new BigDecimal(str1);
		BigDecimal big2 = new BigDecimal(str2);
		BigDecimal iRet = big1.divide(big2, pointWs, BigDecimal.ROUND_HALF_UP);
		
		return objToString(iRet);
	}
	/**
	 * 生成15位随机码
	 * 
	 * @return
	 */
	public static String getCode() {
		Random random = new Random();
		String sRand = "";
		for (int i = 0; i < 15; i++) {
			String rand = String.valueOf(random.nextInt(10));
			sRand += rand;
		}
		return sRand;
	}

	/**
	 * getting ip address from remote request
	 * 
	 * @author shihh
	 * @param request
	 *            request object
	 * @return String request ip address
	 */
	public static String getRequestIpAddr(HttpServletRequest request) {

		String ip = request.getHeader("x-forwarded-for");

		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

			ip = request.getHeader("Proxy-Client-IP");

		}

		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

			ip = request.getHeader("WL-Proxy-Client-IP");

		}

		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

			ip = request.getRemoteAddr();

		}
		return ip;

	}

	/**
	 * getting the current time of system
	 * 
	 * @author shihh
	 * @param format
	 *            time format
	 * @return String time is formatted
	 */
	public static String getSystemTime(String format) {
		String systemTime = null;
		try {
			SimpleDateFormat df = new SimpleDateFormat(format);// 设置日期格式
			systemTime = df.format(new Date());
		} catch (Exception ex) {
			return systemTime;
		}
		return systemTime;
	}

	/**
	 * getting value of source string that is separated by some separator by key
	 * if there is any error , return null for example: it return string "merry"
	 * when invoking the function getVauleBySeparator
	 * ("username=merry&sex=f","username","&","=");
	 * 
	 * @author shihh
	 * @param src
	 * @param key
	 * @param outSeparator
	 * @param innerSeparator
	 * @return String
	 */
	public static String getVauleBySeparator(String src, String key,
			String outSeparator, String innerSeparator) {

		String ret = null;
		if (isEmpty(src) || isEmpty(key) || isEmpty(innerSeparator)
				|| isEmpty(outSeparator))
			return ret;

		int keyPos = src.indexOf(key);
		if (keyPos < 0) {
			return ret;
		}

		int inSepPos = src.indexOf(innerSeparator, keyPos + key.length() - 1);
		int ouSepPos = src.indexOf(outSeparator, inSepPos + 1);
		if (ouSepPos == -1)
			ret = src.substring(inSepPos + 1);
		else
			ret = src.substring(inSepPos + 1, ouSepPos);
		return ret;
	}


	public static String timeFormat(String time, String format) {
		String systemTime = null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			Date date = sdf.parse(time);
			SimpleDateFormat todf = new SimpleDateFormat(format);// 设置日期格式
			systemTime = todf.format(date);
		} catch (Exception ex) {
			return systemTime;
		}
		return systemTime;
	}

	/**
	 * getting special format's date string
	 * 
	 * @author shihh
	 * @param format
	 *            time format
	 * @return String time is formatted
	 */
	public static String getFmtDateString(Date date, String format) {
		String dateStr = null;
		try {
			SimpleDateFormat df = new SimpleDateFormat(format);// 设置日期格式
			dateStr = df.format(date);
		} catch (Exception ex) {
			return dateStr;
		}
		return dateStr;
	}

	/**
	 * judge if an element be contained in array
	 * 
	 * @author shihh
	 * @param
	 * @return boolean
	 */
	public static boolean isContainInArray(String element, String[] array) {
		boolean isContain = false;
		for (String subElement : array) {
			if (subElement.equals(element)) {
				isContain = true;
				break;
			}
		}
		return isContain;
	}


	/**
	 * 比较时间差，time1-time2,time1>time2返回正数，time1<time2返回负数
	 * 返回Long数组【】,Long[6]=周差,Long
	 * [5]=年差，Long[4]=月差，Long[3]=日差，Long[2]=时差，Long[1]=分差，Long[0]=秒差 暂不考虑周差
	 * 月只比较月数的差值，如2012年12月31日与2013年1月1日，计算结果为相差1月 年按月的基数基数按，每相差12个月为1年。
	 * 
	 * @param time1
	 *            要笔记哦的时间1，格式yyyyMMddHHmmss
	 * @param time2
	 *            要笔记哦的时间2，格式yyyyMMddHHmmss
	 * @return
	 */
	public static long[] getTD(String time1, String time2) {
		Calendar cal1 = Calendar.getInstance();
		Calendar cal2 = Calendar.getInstance();
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

		Date date1 = null;
		Date date2 = null;
		try {
			date1 = df.parse(time1);
			cal1.setTime(date1);
			date2 = df.parse(time2);
			cal2.setTime(date2);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

		long l = date1.getTime() - date2.getTime();

		long day = l / (24 * 60 * 60 * 1000);

		long hour = (l / (60 * 60 * 1000));

		long min = ((l / (60 * 1000)));

		long s = (l / 1000);

		int yeardiff = cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR);
		int month = 0;

		if (yeardiff > 1) {// time1>time2，相差超过2年的除了要计算time1和time2的月差距，还要加上中间间隔年数的月差距
			month = (cal1.get(Calendar.MONTH) + 1)
					+ (11 - cal2.get(Calendar.MONTH)) + (yeardiff - 1) * 12;
		} else if (yeardiff < -1) {// time1<time2，相差超过2年的除了要计算time1和time2的月差距，还要加上中间间隔年数的月差距
			month = -((11 - cal1.get(Calendar.MONTH)) + (cal2
					.get(Calendar.MONTH) + 1)) + (yeardiff + 1) * 12;
		} else if (yeardiff == 1) {// time1>time2，相差1年的除了只计算time1和time2的月差距
			month = (cal1.get(Calendar.MONTH) + 1)
					+ (11 - cal2.get(Calendar.MONTH));
		} else if (yeardiff == -1) {// time1<time2，相差1年的除了只计算time1和time2的月差距
			month = (11 - cal1.get(Calendar.MONTH))
					+ (cal2.get(Calendar.MONTH) + 1);
			month = -month;
		} else if (yeardiff == 0) {// 同年份的比较只需计算月差即可
			month = cal1.get(Calendar.MONTH) - cal2.get(Calendar.MONTH);
		}

		int time1monthmax = cal1.getActualMaximum(Calendar.DATE);// time1当月最大天数
		int time2monthmax = cal2.getActualMaximum(Calendar.DATE);// time2当月最大天数
		int monthmax = 30;
		boolean wholeMonthDiff = false;
		// 计算两个日期之间是否正好相差了一个整月，由于二月存在其特殊性，暂时按两个月是否相差30天来计算。
		if (month > 0) {
			wholeMonthDiff = time1monthmax - cal1.get(Calendar.DAY_OF_MONTH)
					+ cal2.get(Calendar.DAY_OF_MONTH) > monthmax;
			if (!wholeMonthDiff) {
				month--;
			}
		} else {
			wholeMonthDiff = time2monthmax - cal2.get(Calendar.DAY_OF_MONTH)
					+ cal1.get(Calendar.DAY_OF_MONTH) > monthmax;
			month++;
		}

		long[] td = new long[7];

		td[0] = s;
		td[1] = min;
		td[2] = hour;
		td[3] = day;
		td[4] = month;
		td[5] = month / 12;
		td[6] = day / 7;
		return td;
	}

	/**
	 * return
	 * 
	 * @author shihh
	 *            latitude or longitude
	 * @return double
	 */
	private static double rad(double d)
	{
	   return d * Math.PI / 180.0;
	} 
	/**
	 * return distance between two points
	 * 
	 * @author shihh
	 * @param lat1 - 纬度
	 * @param lng1 - 经度
	 * @param lat2 - 纬度
	 * @param lng2 - 经度        
	 * @return double
	 */
	public static double GetDistance(double lat1, double lng1, double lat2, double lng2)
	{
	   double radLat1 = rad(lat1);
	   double radLat2 = rad(lat2);
	   double a = radLat1 - radLat2;
	   double b = rad(lng1) - rad(lng2);

	   double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +
	    Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
	   s = s * EARTH_RADIUS;
	   //s = Math.round(s * 10000) / 10000;
	   return s;
	}
	
	
	/**
	 * 
	 * @param i 0代表不增加，0+1 都代表增加几天
	 * @return
	 */
	public static Timestamp getSystemTime(int i){
		Timestamp ts = new Timestamp(new Date().getTime());
		if(i > 0){
			Calendar c = Calendar.getInstance();
			c.add(Calendar.DATE,i);
			ts.setTime(c.getTimeInMillis());
			return ts;
		}else{
			return ts;
		}
	}
	
	/**
	 * 截取+补位
	 * @param str 原始字符串
	 * @param maxLength 最大长度
	 * @param rightPad true :右边补位， false：左边补位
	 * @return
	 */
	public static String padAndSub(String str, int maxLength, boolean rightPad) {
		str = StringUtils.substring(str, 0, maxLength - 1);
		if(rightPad) {
			str = StringUtils.rightPad(str, maxLength, "");
		}
		else {
			str = StringUtils.leftPad(str, maxLength, "");
		}
		return str;
	}
	
	/**
	 * 银行卡掩码
	 * @param sCardNo 银行卡号
	 * @return
	 */
	public static String getYanMaCardNo (String sCardNo) {
		String sYaMa = "****************************************";
		if (sCardNo==null || sCardNo.equals("")) {
            return sCardNo;
        } else {
        	 int iLength = sCardNo.length();
        	 if (iLength>4) {
        		 // 截取前4位
        		 String str1 = sCardNo.substring(0, 4);
        		 // 截取后4位
        		 String str2=sCardNo.substring(iLength-4, iLength);
        		 // 截取掩码
        		 String sYaMa1=sYaMa.substring(0,iLength-8);
        		 // 组合
        		 return str1+sYaMa1+str2;
        	 } else {
        		 return sCardNo;
        	 }
        } 	
	}
	
	/**
	 * 根据List转成IN的sql
	 * 
	 * @param strLst
	 * @return
	 */
	public static String listToStr4InSql(List<String> strLst) {
		StringBuffer sb = new StringBuffer();

		for (String val : strLst) {
			sb.append("'");
			sb.append(val);
			sb.append("',");
		}
		if (sb.length() > 0) {
			return sb.substring(0, sb.length() - 1);
		}
		return "";
	}

	public static Object mapToObject(Map<String, Object> map, Class<?> beanClass) throws Exception {
		if (map == null)
			return null;

		Object obj = beanClass.newInstance();

		org.apache.commons.beanutils.BeanUtils.populate(obj, map);

		return obj;
	}

	public static Map<?, ?> objectToMap(Object obj) {
		if (obj == null)
			return null;

		return new org.apache.commons.beanutils.BeanMap(obj);
	}

	/**
	 * 身份证号掩码
	 * @param ctfNo
	 * @return
	 */
	public static String maskCardNo(String ctfNo) {
		if(isEmpty(ctfNo)) {
			return "";
		}
		String cardNo = ctfNo;
		if(cardNo.length() > 17){
			cardNo = cardNo.replaceAll("(\\d{4})\\d{11}(\\d{4})","$1***********$2");
		}

		return cardNo;
	}

	/**
	 * 手机号掩码
	 * @param mobile
	 * @return
	 */
	public static String maskMobile(String mobile) {
		if(isEmpty(mobile)) {
			return "";
		}
		String tel = mobile;
		if(mobile.length() > 7) {
			int strLeng = mobile.length() - 8;
			String regex ="(\\S{4})\\S{" + strLeng + "}(\\S{4})";
			tel = tel.replaceAll(regex, "$1****$2");
		}

//		String tel = mobile;
//		if(mobile.length() == 12) {
//			tel = tel.replaceAll("(\\d{4})\\d{4}(\\d{4})", "$1****$2");
//		}
//		else if(mobile.length() == 11) {
//			tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
//		}
//		else if(mobile.length() == 10) {
//			tel = tel.replaceAll("(\\d{2})\\d{4}(\\d{4})", "$1****$2");
//		}
//		else if(mobile.length() == 9) {
//			tel = tel.replaceAll("(\\d{2})\\d{4}(\\d{3})", "$1****$2");
//		}
//		else if(mobile.length() == 8) {
//			tel = tel.replaceAll("(\\d{2})\\d{3}(\\d{3})", "$1****$2");
//		}
//		else if(mobile.length() == 7) {
//			tel = tel.replaceAll("(\\d{1})\\d{3}(\\d{3})", "$1****$2");
//		}
		return tel;
	}

	public static String maskAccount(String account) {
		if(isEmpty(account)) {
			return "";
		}
		String tel = account;
		if(account.length() > 10) {
			int strLeng = account.length() - 8;
			String regex ="(\\S{4})\\S{" + strLeng + "}(\\S{4})";
			tel = tel.replaceAll(regex, "$1****$2");
		}
		return tel;
	}

	/**
	 * 拼接用户名
	 * @param firstName
	 * @param midName
	 * @param lastName
	 * @return
	 */
	public static String splUserName(String firstName, String midName, String lastName) {
		return splUserName(firstName, midName, lastName, false);
	}

	/**
	 * 拼接用户名 + 掩码
	 * @param firstName
	 * @param midName
	 * @param lastName
	 * @param isMask
	 * @return
	 */
	public static String splUserName(String firstName, String midName, String lastName, boolean isMask) {
		StringBuffer sb = new StringBuffer();
		if(isNotEmpty(firstName)) {
			sb.append(firstName);
		}

		if(isNotEmpty(midName)) {
			sb.append(midName);
		}

		if(isNotEmpty(lastName)) {
			sb.append(lastName);
		}
		// 是否掩码
		if(isMask) {
			String str = sb.toString();
			if(str.length() > 10) {
				return StringUtils.substring(str, 0, 4).concat("***")
						.concat(StringUtils.substring(str, str.length() - 4, str.length()));
			}
		}
		return sb.toString();
	}
}
