package com.imdroid.common.util;


import java.io.*;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * The type Byte util.
 */
public class ByteUtil {

    private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    public static byte[] getBytes(int data) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) (data & 0xff);
        bytes[1] = (byte) ((data & 0xff00) >> 8);
        bytes[2] = (byte) ((data & 0xff0000) >> 16);
        bytes[3] = (byte) ((data & 0xff000000) >> 24);
        return bytes;
    }

    public static short getShort(byte[] bytes) {
        return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8)));
    }

    public static short getShort(byte high, byte low) {
        return (short) (((high & 0xff) << 8) | (low & 0xff));
    }

    public static byte[] getBytes(String data, String charsetName) {
        Charset charset = Charset.forName(charsetName);
        return data.getBytes(charset);
    }

    public static byte[] getBytes(String data) {
        return getBytes(data, "GBK");
    }

    public static String getString(byte[] bytes) {
        return getString(bytes, "GBK");
    }

    public static String getString(byte[] bytes, String charsetName) {
        return new String(bytes, Charset.forName(charsetName));
    }


    public static int toUnsignedInt(byte paramByte) {
        return paramByte & 0xFF;
    }

    /**
     * 获取byte类型的时间
     *
     * @param time
     * @return 获取byte类型的时间
     */
    public static byte[] getTimeToBytes(Date time) {
        String times = new SimpleDateFormat("yy MM dd HH mm ss", Locale.CHINA).format(time)
                .replaceAll(" ", "");
        byte[] date = new byte[6];

        for (int i = 0, j = 0; i < times.length(); i += 2, j++) {
            date[j] = Byte.decode("0x" + times.charAt(i) + ""
                    + times.charAt(i + 1));
        }

        return date;
    }

    /**
     * 数组转16char数组
     *
     * @param data        the data
     * @param toLowerCase the to lower case
     * @return the char [ ]
     */
    public static char[] encodeHex(byte[] data, boolean toLowerCase) {
        return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
    }

    /**
     * 数组转16char数组
     *
     * @param data     the data
     * @param toDigits the to digits
     * @return the char [ ]
     */
    protected static char[] encodeHex(byte[] data, char[] toDigits) {
        if (data == null) {
            return null;
        }
        int l = data.length;
        char[] out = new char[l << 1];
        for (int i = 0, j = 0; i < l; i++) {
            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
            out[j++] = toDigits[0x0F & data[i]];
        }
        return out;
    }

    /**
     * 数组转16进制字符串
     *
     * @param data the data
     * @return the string
     */
    public static String encodeHexStr(byte[] data) {
        return encodeHexStr(data, true);
    }

    /**
     * 数组转16进制字符串
     *
     * @param data        byte[]
     * @param toLowerCase ture小写  false大写
     * @return 结果
     */
    public static String encodeHexStr(byte[] data, boolean toLowerCase) {
        return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
    }

    /**
     * 锟斤拷锟街斤拷锟斤拷锟斤拷转锟斤拷为十锟斤拷锟斤拷锟斤拷锟街凤拷锟斤拷
     *
     * @param data     byte[]
     * @param toDigits 锟斤拷锟节匡拷锟斤拷锟斤拷锟斤拷锟絚har[]
     * @return 十锟斤拷锟斤拷锟斤拷String string
     */
    protected static String encodeHexStr(byte[] data, char[] toDigits) {
        return new String(encodeHex(data, toDigits));
    }


    /**
     * long转16进制byte数组
     *
     * @param iSource   the source
     * @param iArrayLen the array len
     * @return the byte [ ]
     */
    public static byte[] tobyteArray(long iSource, int iArrayLen) {
        byte[] bLocalArr = new byte[iArrayLen];
        int i = 0;
        int j = iArrayLen - 1;
        for (; (i < 4) && (i < iArrayLen); i++, j--) {
            bLocalArr[j] = (byte) (iSource >> 8 * i & 0xFF);
        }
        while (j >= 0) {
            bLocalArr[j] = 0;
            j--;
        }
        return bLocalArr;
    }

    /**
     * int转16进制byte数组
     *
     * @param iSource   the source
     * @param iArrayLen the array len
     * @return byte [ ]
     */
    public static byte[] tobyteArray(int iSource, int iArrayLen) {
        byte[] bLocalArr = new byte[iArrayLen];
        int i = 0;
        int j = iArrayLen - 1;
        for (; (i < 4) && (i < iArrayLen); i++, j--) {
            bLocalArr[j] = (byte) (iSource >> 8 * i & 0xFF);
        }
        while (j >= 0) {
            bLocalArr[j] = 0;
            j--;
        }
        return bLocalArr;
    }

    /**
     * 16进制字节转成int
     *
     * @param bRefArr the b ref arr
     * @return int
     */
    public static int toInt(byte[] bRefArr) {
        int iOutcome = 0;
        byte bLoop;

        for (int i = bRefArr.length - 1; i >= 0; i--) {
            bLoop = bRefArr[i];
            iOutcome += (bLoop & 0xFF) << (8 * (bRefArr.length - 1 - i));
        }
        return iOutcome;
    }


    /**
     * Char tobyte byte.
     *
     * @param c the c
     * @return the byte
     */
    public static byte charTobyte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /**
     * 2进制转byte
     *
     * @param str the str
     * @return int
     */
    public static int Binarytobyte(String str) {
        String intstr = Integer.toString(Integer.parseInt(str, 2), 10);
        return Integer.valueOf(intstr);
    }

    /**
     * 2进制字符转byte数组
     *
     * @param str the str
     * @return the byte [ ]
     */
    public static byte[] Binarytobytes(String str) {
        int tmpint = 0;
        for (int i = 0, j = 0; i < str.length(); i += 8, j++) {
            String binarystr = str.charAt(i) + ""
                    + str.charAt(i + 1) + "" + str.charAt(i + 2) + ""
                    + str.charAt(i + 3) + "" + str.charAt(i + 4) + ""
                    + str.charAt(i + 5) + "" + str.charAt(i + 6) + ""
                    + str.charAt(i + 7);
            System.out.println(i);
            tmpint += Binarytobyte(binarystr);
        }
        System.out.println(tmpint);
        return getBytes(tmpint);
    }

    /**
     * 将long转为byte数组
     *
     * @param number
     * @return 将long转为byte数组
     */
    public static byte[] longTobyte(long number) {
        byte[] b = new byte[8];

        b[0] = (byte) (number >> 56);
        b[1] = (byte) (number >> 48);
        b[2] = (byte) (number >> 40);
        b[3] = (byte) (number >> 32);
        b[4] = (byte) (number >> 24);
        b[5] = (byte) (number >> 16);
        b[6] = (byte) (number >> 8);
        b[7] = (byte) number;

        return b;
    }

    /**
     * 将short转为byte数组
     *
     * @param number
     * @return 将short转为byte数组
     */
    public static byte[] shortTobyte(short number) {
        byte[] b = new byte[2];

        b[0] = (byte) (number >> 8);
        b[1] = (byte) number;

        return b;
    }

    /**
     * 将int转为byte数组
     *
     * @param number
     * @return 将int转为byte数组
     */
    public static byte[] intTobyte(int number) {
        byte[] b = new byte[4];

        b[0] = (byte) (number >> 24);
        b[1] = (byte) (number >> 16);
        b[2] = (byte) (number >> 8);
        b[3] = (byte) number;

        return b;
    }

    /**
     * 八字节转成long
     *
     * @param b the b
     * @return the long
     */
    public static long toLong(byte[] b)

    {
        long l = 0;

        l = b[0];

        l |= ((long) b[1] << 8);

        l |= ((long) b[2] << 16);

        l |= ((long) b[3] << 24);

        l |= ((long) b[4] << 32);

        l |= ((long) b[5] << 40);

        l |= ((long) b[6] << 48);

        l |= ((long) b[7] << 56);

        return l;
    }


    /**
     * 数组转成十六进制字符串
     *
     * @param b the b
     * @return HexString string
     */
    public static String bytesToHexString(byte[] b) {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < b.length; ++i) {
            buffer.append(byteToHexString(b[i]));
        }
        return buffer.toString();
    }

    /**
     * byte转成16进制字符串
     *
     * @param b the b
     * @return the string
     */
    public static String byteToHexString(byte b) {
        String s = Integer.toHexString(b & 0xFF);
        if (s.length() == 1) {
            return "0" + s;
        } else {
            return s;
        }
    }


    /**
     * 图片路径转成byte
     *
     * @param path the path
     * @return the byte [ ]
     */
    public static byte[] image2byte(String path) {
        byte[] data = null;
        FileInputStream input = null;
        try {
            input = new FileInputStream(new File(path));
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int numBytesRead = 0;
            while ((numBytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, numBytesRead);
            }
            data = output.toByteArray();
            output.close();
            input.close();
        } catch (FileNotFoundException ex1) {
            ex1.printStackTrace();
        } catch (IOException ex1) {
            ex1.printStackTrace();
        }
        return data;
    }

    /**
     * Byte 2 image boolean.
     *
     * @param data the data
     * @param path the path
     * @return the boolean
     */
// byte数组到图片
    public static boolean byte2image(byte[] data, String path) {
        if (data.length < 3 || "".equals(path)) {
            return false;
        }
        try {
            FileOutputStream imageOutput = new FileOutputStream(
                    new File(path));
            imageOutput.write(data, 0, data.length);
            imageOutput.close();
            System.out.println("Make Picture success,Please find image in "
                    + path);
        } catch (Exception ex) {
            System.out.println("Exception: " + ex);
            ex.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * byte叠加
     *
     * @param data1 the data 1
     * @param data2 the data 2
     * @return the byte [ ]
     */
    public static byte[] addBytes(byte[] data1, byte[] data2) {
        byte[] data3 = new byte[data1.length + data2.length];
        System.arraycopy(data1, 0, data3, 0, data1.length);
        System.arraycopy(data2, 0, data3, data1.length, data2.length);
        return data3;
    }

    /**
     * Bcd 2 str string.
     *
     * @param bytes the bytes
     * @return the string
     */
    public static String bcd2Str(byte[] bytes) {

        StringBuffer temp = new StringBuffer(bytes.length * 2);

        for (int i = 0; i < bytes.length; i++) {

            temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
            temp.append((byte) (bytes[i] & 0x0f));
        }
        while (temp.charAt(0) == '0') {
            temp.deleteCharAt(0);
        }
        return temp.toString();
    }




    /**
     * 获得参数内容
     */
    public static byte[] getParameter(byte[] body, int length) {
        byte[] content = new byte[length];
        System.arraycopy(body, body.length - length, content, 0, length);
        return content;
    }

    /**
     * 把16进制字符串转换成字节数组
     *
     * @return byte[]
     */
    public static byte[] hexStringTobyte(String hex) {
        hex = hex.toUpperCase();
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] achar = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (tobyte(achar[pos]) << 4 | tobyte(achar[pos + 1]));
        }
        return result;
    }

    /**
     * 字符串转16进制字符串
     *
     * @param strPart
     * @return
     */
    public static String string2HexString(String strPart) {
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < strPart.length(); i++) {
            int ch = (int) strPart.charAt(i);
            String strHex = Integer.toHexString(ch);
            hexString.append(strHex);
        }
        return hexString.toString();
    }

    private static int tobyte(char c) {
        byte b = (byte) "0123456789ABCDEF".indexOf(c);
        return b;
    }

    /**
     * 转换总里程
     *
     * @param value
     * @return 转换总里程
     */
    public static String oneDecimal(double value) {
        BigDecimal b = new BigDecimal(value);
        return b.setScale(1, BigDecimal.ROUND_HALF_UP).toString();
    }
    //------工具区(经纬度解析)--------------------------------------------------
    public static Double getLONG(Double location) {
        if (location != 0.0) {
            int head = Integer.parseInt(String.valueOf(location).substring(0, 3));
            //System.out.println(head);
            return head + (location / 100 - head) * 10 / 6;
        }
        return 0.0;
    }

    //一度为60分
    public static Double getLAT(Double location) {
        if (location != 0.0) {
            int head = Integer.parseInt(String.valueOf(location).substring(0, 2));
            // System.out.println(head);
            return head + (location / 100 - head) * 10 / 6;
        }
        return 0.0;
    }

    /**
     * 将byte数组数据转换成float
     * @param arr
     * @return
     */
    public static float bytes2Float(byte[] arr) {
        float f = ByteBuffer.wrap(arr).order(ByteOrder.BIG_ENDIAN).getFloat();
        return f;
    }

    /**
     * byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序
     *
     * @param src byte数组
     * @return int数值
     */
    public static int bytesToInt(byte[] src) {
        int value;
        value = (int) ((src[0] & 0xFF)
                | ((src[1] & 0xFF)<<8)
                | ((src[2] & 0xFF)<<16)
                | ((src[3] & 0xFF)<<24));
        return value;
    }

    /**
     * 把byte数组转化成2进制字符串
     * @param bArr
     * @return
     */
    public static String getBinaryStrFromByteArr(byte[] bArr){
        String result ="";
        for(byte b:bArr ){
            result += getBinaryStrFromByte(b);
        }
        return result;
    }
    /**
     * 把byte转化成2进制字符串
     * @param b
     * @return
     */
    public static String getBinaryStrFromByte(byte b){
        String result ="";
        byte a = b; ;
        for (int i = 0; i < 8; i++){
            byte c=a;
            a=(byte)(a>>1);//每移一位如同将10进制数除以2并去掉余数。
            a=(byte)(a<<1);
            if(a==c){
                result="0"+result;
            }else{
                result="1"+result;
            }
            a=(byte)(a>>1);
        }
        return result;
    }

    /**
     * 二进制字符串转int
     * @param binary
     * @return
     */
    public  static  int  binaryToInt(String binary) {
        if  (binary ==  null ) {
            System.  out .println( "can't input null ！"  );
        }
        if  (binary.isEmpty()) {
            System.  out .println( "you input is Empty !"  );
        }
        int  max = binary.length();
        String new_binary =  "" ;
        if  (max >= 2 && binary.startsWith( "0" )) {
            int  position = 0;
            for  ( int  i = 0; i < binary.length(); i++) {
                char  a = binary.charAt(i);
                if  (a !=  '0'  ) {
                    position = i;
                    break ;
                }
            }
            if  (position == 0) {
                new_binary = binary.substring(max - 1, max);
            }  else  {
                new_binary = binary.substring(position, max);
            }
        }  else  {
            new_binary = binary;
        }
        int  new_width = new_binary.length();

        long  result = 0;
        if  (new_width < 32) {
            for  ( int  i = new_width; i > 0; i--) {
                char  c = new_binary.charAt(i - 1);
                int  algorism = c -  '0'  ;
                result += Math. pow(2, new_width - i) * algorism;
            }
        }  else  if  (new_width == 32) {
            for  ( int  i = new_width; i > 1; i--) {
                char  c = new_binary.charAt(i - 1);
                int  algorism = c -  '0'  ;
                result += Math. pow(2, new_width - i) * algorism;
            }
            result += -2147483648;
        }
        int  a =  new  Long(result).intValue();
        return  a;
    }

}

