package com.hboxs.serialport.plc.util;

import com.hboxs.serialport.plc.Command;

/**
 * 地址计算
 */
public class AddressUtils {
    private static int BASE_D_LOW = 0x1000;
    private static int BASE_D_HIGH = 0x0E00;
    private static int BASE_M_LOW = 0x0100;
    private static int BASE_M = 0x0800;
    private static int BASE_M_HIGH = 0x01E0;
    private static int BASE_Y = 0x00A0;
    private static int BASE_X = 0x0080;

    /**
     * 获取PLC真实地址
     *
     * @param addressStr 地址字符串，如：M600
     * @param cmd  读或写的命令
     * @return 地址字节数组，4字节
     */
    public static byte[] getAddress(String addressStr,byte cmd) {
        char area = addressStr.charAt(0);

        int address = Integer.parseInt(addressStr.substring(1, addressStr.length()));
        return parserAddress(area, address,cmd);
    }

    private static byte[] parserAddress(char area, int address,byte cmd) {
        switch (area) {
            case 'D':
                if (address >= 0 && address < 8000) {
                    address = (address * 2) + BASE_D_LOW;
                } else if (address >= 8000) {
                    address = ((address - 8000) * 2) + BASE_D_HIGH;
                }
                break;
//            case 'C':
//                break;
//            case 'T':
//                break;
            case 'M':

                if (cmd== Command.CMD_READ){
                    //读取使用旧的协议
                    if (address >= 0 && address < 8000) {
                    address = (address / 8) + BASE_M_LOW;
                } else if (address >= 8000) {
                    address = ((address - 8000) / 8) + BASE_M_HIGH;
                }
                }else {
                    //置位和复位采取新的协议
                    address=BASE_M+address;
                }

                break;
            case 'Y':
                address = (address / 8) + BASE_Y;
                break;
            case 'X':
                address = (address / 8) + BASE_X;
                break;
            case 'S':
                address = address / 8;
                break;
            default:
                return null;
        }

        // 剔除高位
        address = address & 0x00FFFF;

        // 转16进制
        String hexString = Integer.toHexString(address).toUpperCase();

        if (hexString.length() == 1) {
            return new byte[]{0x30, 0x30, 0x30, (byte) hexString.charAt(0)};
        } else if (hexString.length() == 2) {
            return new byte[]{0x30, 0x30, (byte) hexString.charAt(0), (byte) hexString.charAt(1)};
        } else if (hexString.length() == 3) {
            return new byte[]{0x30, (byte) hexString.charAt(0), (byte) hexString.charAt(1), (byte) hexString.charAt(2)};
        } else {
            return new byte[]{(byte) hexString.charAt(0), (byte) hexString.charAt(1), (byte) hexString.charAt(2), (byte) hexString.charAt(3)};
        }
    }

    public static void main(String[] args) {
        System.out.println(23 / 8);
        System.out.println(24 / 8);
        System.out.println(25 / 8);
        byte[] bytes = getAddress("Y10",Command.CMD_READ);
        for (byte b : bytes) {
            System.out.println(Integer.toHexString(b));
        }

        int i = 0b1000000100000000;
        System.out.println(Integer.toBinaryString(i));
    }
}
