package com.house365.web.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.Reader;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.CharUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;

import com.house365.rest.exception.ServiceException;

/**
 * 通用的工具类
 */
public final class GeneralUtils
{
    /**
     * 判断对象是否为null , 为null返回true,否则返回false
     * @param obj 被判断的对象
     * @return boolean
     */
    public static boolean isNull(Object obj)
    {
        return (null == obj) ? true : false;
    }
    
    /**
     * 判断对象是否为null , 为null返回false,否则返回true
     * @param obj 被判断的对象
     * @return boolean
     */
    public static boolean isNotNull(Object obj)
    {
        return !isNull(obj);
    }
    
    
    /**
     * 判断字符串是否为null或者0长度，字符串在判断长度时，先去除前后的空格,空或者0长度返回false,否则返回true
     * @param str 被判断的字符串
     * @return boolean
     */
    public static boolean isNotNullOrZeroLenght(String str)
    {
        return !isNullOrZeroLenght(str);
    }
    
    /**
     * 判断str数组是否为null或者0长度，只要有一个空或者0长度返回false, 否则返回true
     * @param str String 字符数组
     * @return boolean
     * @author huanghui
     * @see [类、类#方法、类#成员]
     */
    public static boolean isNotNullOrZeroLenght(String... str)
    {
        if(str == null)
        {
            return false;
        }
        for (String s : str)
        {
            if (isNullOrZeroLenght(s))
            {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 判断str数组是否为null或者0长度，只要有一个空或者0长度返回true, 否则返回false
     * @param str String 字符数组
     * @return boolean
     * @author huanghui
     * @see [类、类#方法、类#成员]
     */
    public static boolean isNullOrZeroLenght(String... str)
    {
        return !isNotNullOrZeroLenght(str);
    }
    
    /**
     * 判断集合对象是否为null或者0大小 , 为空或0大小返回true ,否则返回false
     * @param c collection 集合接口
     * @return boolean 布尔值
     * @author huanghui
     * @see [类、类#方法、类#成员]
     */
    public static boolean isNullOrZeroSize(Collection<? extends Object> c)
    {
        return isNull(c) || c.isEmpty();
    }
    
    /**
     * 判断集合对象是否为null或者0大小 , 为空或0大小返回false, 否则返回true
     * @param c collection 集合接口
     * @return boolean 布尔值
     * @author huanghui
     * @see [类、类#方法、类#成员]
     */
    public static boolean isNotNullOrZeroSize(Collection<? extends Object> c)
    {
        return !isNullOrZeroSize(c);
    }
    
    /**
     * 判断数字类型是否为null或者0，如果是返回true，否则返回false
     * @param number 被判断的数字
     * @return boolean
     */
    public static boolean isNullOrZero(Number number)
    {
        if (GeneralUtils.isNotNull(number))
        {
            return (number.intValue() != 0) ? false : true;
        }
        return true;
    }
    
    /**
     * 判断数字类型是否不为null或者0，如果是返回true，否则返回false
     * @param number 被判断的数字
     * @return boolean
     */
    public static boolean isNotNullOrZero(Number number)
    {
        return !isNullOrZero(number);
    }
    
    /**
     * 将java.util.Date类型转化位String类型
     * @param date 要转换的时间
     * @param format 时间格式
     * @return 如果转换成功，返回指定格式字符串，如果转换失败，返回null
     */
    public static String date2String(Date date, String format)
    {
        if (GeneralUtils.isNull(date) || GeneralUtils.isNull(format))
        {
            return null;
        }
        
        return DateFormatUtils.format(date, format);
    }
    
    /**
     * 将字符串时间转换成java.util.Date类型
     * @param str 要转换的字符串
     * @param format 时间格式
     * @return 如果转换失败，返回null
     */
    public static Date string2Date(String str, String format)
    {
        if (GeneralUtils.isNull(str) || GeneralUtils.isNull(format))
        {
            return null;
        }
        
        // 定义日期/时间格式
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date date;
        
        try
        {
            // 转换日期/时间格式
            date = sdf.parse(str);
            // 判断转换前后时间是否一致
            
            if (!str.equals(sdf.format(date)))
            {
                date = null;
            }
        }
        catch (ParseException e)
        {
            date = null;
        }
        
        return date;
    }

    /**
     * 将字符串时间转换时间格式
     * @param str 要转换的字符串
     * @param formatF 初始时间格式
     * @param formatT 目标时间格式
     * @return 如果转换失败，返回null
     */
    public static String String2String(String str, String formatF,  String formatT)
    {
        return date2String(string2Date(str, formatF), formatT);
    }
    
    
    /**
     * 获取目录在系统中的绝对路径
     * @param path 路径
     * @return Sting
     */
    public static String getAbsolutePath(String path)
    {
        // 如果路进为null，则认为时当前目录
        path = (GeneralUtils.isNull(path)) ? "" : path;
        File file = new File(path);
        // 获取完整路径
        return FilenameUtils.separatorsToUnix(file.getAbsolutePath());
    }
    
    /**
     * 将字符串首字符待大写
     * @param str 源字符串
     * @return 首字符大写后的字符串
     * @see [类、类#方法、类#成员]
     */
    public static String firstCharUpper(String str)
    {
        char firstChar = CharUtils.toChar(str);
        String upFirstChar = StringUtils.upperCase(String.valueOf(firstChar));
        return StringUtils.replaceOnce(str, String.valueOf(firstChar), upFirstChar);
    }
    
    /**
     * Object - > String
     * @param obj  对象参数
     * @return  String 字符串
     */
    public static String object2String(Object obj)
    {
        if (isNull(obj))
        {
            return "";
        }
        else
        {
            return obj.toString();
        }
    }
    
    /**
     * 返回当前的时间戳
     * @return 时间戳
     */
    public static String getCurrentTimeStamp()
    {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
    
    
    
    /**
     * 删除文件
     * @param filePathname 文件路径
     * @throws Exception 
     * @throws ServiceException 业务异常
     */
    public static void deleteFile(String filePathname) throws Exception
    {
        // 如果路径为空或空字符串，直接返回不做处理
        if (isNullOrZeroLenght(filePathname))
        {
            return;
        }
        // 定义删除的文件
        File fileObject = new File(filePathname);
        // 如果文件不存在，直接返回
        if (!fileObject.exists() || !fileObject.isFile())
        {
            return;
        }
        // 如果删除文件失败，则抛出异常
        if (!fileObject.delete())
        {
            throw new Exception("删除文件失败");
        }
    }
    
    /**
     * 将以特定字符作为分隔符的字符串转换为List集合
     * @param strToBeConverted - 待转换的字符串
     * @param separator - 分隔符
     * @return - 转换后的列表对象
     */
    public static List<String> splitStringUseSpecifiedSeparator(String strToBeConverted, String separator)
    {
        // 转换后集合对象，初始设置为空。
        List<String> resultList = new ArrayList<String>();
        // 原始字符串为NULL或者为空，直接返回空Set
        if (StringUtils.isEmpty(strToBeConverted))
        {
            return resultList;
        }
        // 分隔符为NUlL或者空，返回只包含原始字符串的Set
        if (StringUtils.isEmpty(separator))
        {
            resultList.add(strToBeConverted);
        }
        // 按照指定分隔符拆分字符串
        String[] arrayString = strToBeConverted.split(separator);
        // 遍历数组，组装到Set集合中。方便调用程序处理。
        
        for (String str : arrayString)
        {
            resultList.add(str);
        }
        return resultList;
    }
    
    
    
    /**
     * 大字段转字符串
     * @param clob 大字段对象
     * @return 字符串
     * @throws Exception 异常
     */
    public static String clobToString(java.sql.Clob clob)
        throws Exception
    {
        if (isNull(clob))
        {
            return " ";
        }
        StringBuffer sb2 = new StringBuffer();
        Reader instream = null;
        instream = clob.getCharacterStream();
        BufferedReader in = new BufferedReader(instream);
        String line = null;
        while ((line = in.readLine()) != null)
        {
            sb2.append(line);
        }
        return sb2.toString();
    }
    
    /*
     * 数量格式化工具
     * 如果是1.0则格式化为1
     * 如果是1.10则格式化为1.1
     */
    public static String doubleToIntString(double number)
    {
        String numStr = String.valueOf(number);
        if (numStr.endsWith(".0"))
        {
            numStr = numStr.substring(0, numStr.indexOf(".0")); 
        }
        return numStr;
    }
    
    /**
     * 计算某天是星期几
     * @param date
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static int getWeekOfOneDay(Date date){  
        Calendar c = Calendar.getInstance();  
        c.setTime(date);  
        //SUNDAY:星期日；MONDAY:星期一；TUESDAY:星期二；WEDNESDAY:星期三；THURSDAY:星期四；FRIDAY:星期五；SATURDAY:星期六；
        int[] weekDays = {0, 1, 2, 3, 4, 5, 6};  
        // 一周中的第几天(国外周日是第一天,所以需要减1)  
        int n = c.get(Calendar.DAY_OF_WEEK)-1;  
        if (n < 0) n = 0;      
        return weekDays[n];  
    } 
    
    /**
     * 获取以若干字符开始后面是数字的字符串的前面字符部分   例如：VS00012
     * @param str
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static String getLettersOfString(String str)
    {
        if(isNullOrZeroLenght(str))
        {
            return null;
        }
        String reg = "^[A-Za-z]$";
        StringBuffer startStr = new StringBuffer();
        for(int i=0;i<str.length();i++)
        {
            if(str.substring(i, i+1).matches(reg))
            {
                startStr.append(str.substring(i, i+1));              
            }
            else 
            {
                break;
            }
        }
        if(isNotNull(startStr))
        {
            return startStr.toString();
        }
        else 
        {
            return null;
        }
    }
    
    public static Float floatTo2Bits(Float a)
    {
    	return new BigDecimal(a).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
    }
}
