/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.estsh.i3plus.ext.mes.pcn.apiservice.util.reader;


import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;


/**
 * @author 徐辛波(sinpo.xu @ hotmail.com) Oct 19, 2008
 */
public class ReaderJavaWTest extends Thread {
    @Override
    public void run() {
        //TestOri();//测试原始的

        TestOrm();//

    }


    public static void Bcd2AscEx(byte asc[], byte bcd[], int len) {
        int i, j;
        int k;

        j = (len + len % 2) / 2;
        k = 3 * j;
        for (i = 0; i < j; i++) {
            asc[3 * i] = (byte) ((bcd[i] >> 4) & 0x0f);
            asc[3 * i + 1] = (byte) (bcd[i] & 0x0f);
            asc[3 * i + 2] = 0x20;
        }
        for (i = 0; i < k; i++) {
            if ((i + 1) % 3 == 0) {
                continue;
            }
            if (asc[i] > 0x09) {
                asc[i] = (byte) (0x41 + asc[i] - 0x0a);
            } else {
                asc[i] += 0x30;
            }
        }

        asc[k] = 0;

    }

    public static void Bcd2AscEy(char asc[], char bcd[], int len) {
        int i, j;
        int k;

        j = (len + len % 2) / 2;
        k = 3 * j;
        for (i = 0; i < j; i++) {
            asc[3 * i] = (char) ((bcd[i] >> 4) & 0x0f);
            asc[3 * i + 1] = (char) (bcd[i] & 0x0f);
            asc[3 * i + 2] = 0x20;
        }
        for (i = 0; i < k; i++) {
            if ((i + 1) % 3 == 0) {
                continue;
            }
            if (asc[i] > 0x09) {
                asc[i] = (char) (0x41 + asc[i] - 0x0a);
            } else {
                asc[i] += 0x30;
            }
        }

        asc[k] = 0;

    }

    public static void TestOri() {

        Selector selector = null;
        try {
            DatagramChannel channel = DatagramChannel.open();
            DatagramSocket socket = channel.socket();
            channel.configureBlocking(false);
            socket.bind(new InetSocketAddress(5057));

            selector = Selector.open();
            channel.register(selector, SelectionKey.OP_READ);
        } catch (Exception e) {
            e.printStackTrace();
        }

        ByteBuffer byteBuffer = ByteBuffer.allocate(65536);

        //while (true) {
        if (true) {
            try {

                byte chTemp[] = new byte[1024];
                int eventsCount = selector.select(3000);
                if (eventsCount > 0) {
                    Set selectedKeys = selector.selectedKeys();
                    Iterator iterator = selectedKeys.iterator();
                    while (iterator.hasNext()) {
                        SelectionKey sk = (SelectionKey) iterator.next();
                        iterator.remove();
                        if (sk.isReadable()) {
                            DatagramChannel datagramChannel = (DatagramChannel) sk
                                    .channel();
                            SocketAddress sa = datagramChannel
                                    .receive(byteBuffer);
                            byteBuffer.flip();

                            // 测试：通过将收到的ByteBuffer首先通过缺省的编码解码成CharBuffer 再输出马储油平台
                            //CharBuffer charBuffer = Charset.defaultCharset().decode(byteBuffer);
                            //ByteBuffer btBuffer = Charset.defaultCharset().decode(byteBuffer);

                            Bcd2AscEx(chTemp, byteBuffer.array(), 8);
                            //System.out.println("receive message:"+ charBuffer.toString());
                            System.out.println("receive message:" + String.valueOf(chTemp));

                            byteBuffer.clear();

                            //String echo = "This is the reply message from 服务器。";
                            //ByteBuffer buffer = Charset.defaultCharset()
                            //		.encode(echo);
                            //chTemp = new char[2];
                            //chTemp[0] = 0x56;
                            //chTemp[1] = 0x78;

                            //ByteBuffer buffer = ByteBuffer.allocate(chTemp.length);
                            //Charset cs = Charset.forName ("UTF-8");
                            //CharBuffer cb = CharBuffer.allocate (chTemp.length);
                            //cb.put (chTemp);
                            //cb.flip ();

                            //ByteBuffer bb = cs.encode (cb);


                            //datagramChannel.send(bb, sa);
                            //datagramChannel.write(buffer);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


        System.out.println("Program end!\n");

    }


    //连接读写器测试
    public static void TestOrm() {

        Selector selector = null;
        try {
            DatagramChannel channel = DatagramChannel.open();
            DatagramSocket socket = channel.socket();
            channel.configureBlocking(false);
            socket.bind(new InetSocketAddress(5057));

            selector = Selector.open();
            channel.register(selector, SelectionKey.OP_READ);
            //byte[] chTemp = new byte[] {0x40, 0x03, 0x0F, 0x00, (byte)0xAE};
            //byte[] chTemp = new byte[] {0x40, 0x02, 0x02, (byte)0xBC};
            //cb9f
            // 0 1 2 3 4 5 6 7 8 9 a b c d e f
            // 读取数据
            //  40        0c        ec       01       cb9f      03      00          01             00 00 00 00           59
            //固定长度   包有效长度   命令码   命令参数1    标签      数据区   起始地址   一个字节数据长度    accessPassword密码     Check Sum
            //读取数据
        //    byte[] chTemp = new byte[]{0x40, 0x0c, (byte) 0xec,  , (byte) 0xcb, (byte) 0x9f,0x03,0x00,0x01,0x00,0x00,0x00,0x00,0x59};

            //列出标签
            //40  06  EE  mem  addr  LEN  Mask  CheckSum
            //40  06  ee   03  00    00    00    c9
            byte[] chTemp = new byte[]{0x40  ,0x06, (byte) 0xee,  0x03 ,0x00 ,0x00,0x00, (byte) 0xc9};

            //chTemp[0] = 0x40;
            //chTemp[1] = 0x03;
            //chTemp[2] = 0x0F;
            //chTemp[3] = 0x00;
            //chTemp[4] = (byte)0xAE;


            ByteBuffer bb = ByteBuffer.allocate(chTemp.length);
            bb.put(chTemp);
            bb.flip();


            //DatagramChannel ch= DatagramChannel.open();
            //DatagramSocket so = ch.socket();
            //ch.configureBlocking(false);
            //SocketAddress sa = so.getLocalSocketAddress();
//                        byte[] bs = new byte[] { (byte) 192, (byte) 168, 0, 71 };
            byte[] bs = new byte[]{(byte) 192, (byte) 168, 31, 100};
            InetAddress address = InetAddress.getByAddress(bs);
//                        SocketAddress sa = new InetSocketAddress(address, 8080);
            SocketAddress sa = new InetSocketAddress(address, 1969);
            channel.send(bb, sa);


        } catch (Exception e) {
            e.printStackTrace();
        }


        ByteBuffer byteBuffer = ByteBuffer.allocate(65535);

        //while (true) {
        if (true) {
            try {
                int iRecvLen = 0;
                byte[] chTemp = new byte[4096];
                int eventsCount = selector.select(5000);
                if (eventsCount > 0) {
                    Set selectedKeys = selector.selectedKeys();
                    Iterator iterator = selectedKeys.iterator();
                    while (iterator.hasNext()) {
                        SelectionKey sk = (SelectionKey) iterator.next();
                        iterator.remove();
                        if (sk.isReadable()) {

                            DatagramChannel datagramChannel = (DatagramChannel) sk
                                    .channel();
                            byteBuffer.clear();
                            SocketAddress sa = datagramChannel.receive(byteBuffer);
                            byteBuffer.flip();


                            iRecvLen = byteBuffer.limit();
                            // 测试：通过将收到的ByteBuffer首先通过缺省的编码解码成CharBuffer 再输出马储油平台
                            CharBuffer charBuffer = Charset.forName("UTF-8").decode(byteBuffer);
                            Bcd2AscEx(chTemp, byteBuffer.array(), iRecvLen * 2);
                            //System.out.println("receive message:"+ charBuffer.toString());
                            String s = new String(chTemp, "UTF-8");
                            System.out.println("receive message[" + iRecvLen + "]: " + s.trim());
//                            datagramChannel.close();
                            byteBuffer.clear();

                            //String echo = "This is the reply message from 服务器。";
                            //ByteBuffer buffer = Charset.defaultCharset()
                            //		.encode(echo);
                            //chTemp = new char[2];
                            //chTemp[0] = 0x56;
                            //chTemp[1] = 0x78;

                            //ByteBuffer buffer = ByteBuffer.allocate(chTemp.length);
                            //Charset cs = Charset.forName ("UTF-8");
                            //CharBuffer cb = CharBuffer.allocate (chTemp.length);
                            //cb.put (chTemp);
                            //cb.flip ();

                            //ByteBuffer bb = cs.encode (cb);


                            //要发送就下面打开
                            //datagramChannel.send(bb, sa);
                            //datagramChannel.write(buffer);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


        System.out.println("TestOrm end!\n");

    }


    // char转byte

    private byte[] getBytes(char[] chars) {
        Charset cs = Charset.forName("UTF-8");
        CharBuffer cb = CharBuffer.allocate(chars.length);
        cb.put(chars);
        cb.flip();
        ByteBuffer bb = cs.encode(cb);

        return bb.array();

    }

    // byte转char

    private char[] getChars(byte[] bytes) {
        Charset cs = Charset.forName("UTF-8");
        ByteBuffer bb = ByteBuffer.allocate(bytes.length);
        bb.put(bytes);
        bb.flip();
        CharBuffer cb = cs.decode(bb);

        return cb.array();
    }

    private byte checkSum(byte[] bytes) {
        byte result = 0;
        if (null == bytes || bytes.length == 0) {
            return result;
        }

        for (int i = 0; i < bytes.length; i++) {
            result += bytes[i];
        }
        result = (byte) (~result + 1);
        return result;

    }


    /**
     * 将二进制转换成16进制
     *
     * @param buf
     * @return
     */
    public static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 将16进制转换为二进制
     *
     * @param hexStr
     * @return
     */
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        }
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
                    16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }


    public static void main(String[] args) {

        ReaderJavaWTest readerJavaWTest = new ReaderJavaWTest();
//{0x40, 0x02, 0x06, (byte) 0xB8};
//        System.out.println("result=");
//
//        byte[] chTemp = new byte[]{0x40, 0x0b, 0x09, (byte) 0x0f};
//
//        byte[] chTemp2 = new byte[]{0x40, 0x02, 0x06};
//        byte test2 =  (byte) 0xB8;
//        System.out.println(readerJavaWTest.checkSum(chTemp2) == test2);
//        System.out.println(chTemp.toString());
//
//        byte sum1 = (byte) 0xb8;
//        System.out.println(Integer.toHexString(10));
//        System.out.println(Integer.decode("0x40"));
//        System.out.println(Integer.decode("0x02"));
//        System.out.println(Integer.decode("0x06"));
//        System.out.println(Integer.decode("0x40") + Integer.decode("0x02") + Integer.decode("0x06"));
//        int res = Integer.decode("0x40") + Integer.decode("0x02") + Integer.decode("0x06");
//        System.out.println(~res + 1);
//        System.out.println(Integer.toHexString(~res + 1));
//        System.out.println(sum1 == ((byte) (~res + 1)));
////        System.out.println(Integer.decode("0xB8"));
////        System.out.println(readerJavaWTest.checkSum(new byte[]{0x40, 0x02, 0x06, (byte) 0xB8}));
//        String javaStr = "48"; //十六进制
//        byte[] bytes = parseHexStr2Byte(javaStr);
//        byte temp;
//        for (int i = 0; i < bytes.length; i++) {
//            temp = bytes[i];
//            bytes[i] = (byte) (~temp);
//            System.out.println((byte) (~temp));
//        }
////        System.out.println( Integer.toBinaryString(48));
//        String bths = parseByte2HexStr(bytes);
//        System.err.println("按位取反后的结果:" + bths);

        byte[] testBytes = new byte[]{0x40  ,0x06, (byte) 0xee,  0x03 ,0x00 ,0x00,0x00, (byte) 0xc9};
//        byte sum = (byte) 0xcb;
        byte sum = (byte) 0xc9;
        System.out.println(parseByte2HexStr(new byte[]{readerJavaWTest.checkSum(testBytes)}));
        System.out.println(readerJavaWTest.checkSum(testBytes) == sum);
        readerJavaWTest.start();

    }

}
