package com.gary.msr.proto;

import java.util.ArrayList;
import java.util.List;

import android.util.Log;

import com.gary.msr.proto.MSRLayerParams.MSRLayer1Params;
import com.gary.msr.proto.MSRLayerParams.MSRLayer2Params;
import com.gary.msr.proto.MSRLayerParams.MSRLayerNParam;

/**
 * 
 * 处理与层有关数据，不包括0x7E
 */
public class MSRProto {

	public static MSRLayer[] allLayers = new MSRLayer[11];

	static {
		for (int i = 0; i < allLayers.length; i++)
			allLayers[i] = new MSRLayer();
	}

	// 清除第3-11层数据
	public static void clearLayerNDatas() {
		for (int i = 2; i < allLayers.length; i++) {
			allLayers[i].num = MSRLayer.INVALIND_LAYER_NUM;
			allLayers[i].data = null;
			allLayers[i].dataLen = 0;
		}
	}

	// 层到配置数据
	public static int constructMSRConfigData(int[] configData) {
		int dataLen = 0;
		if (configData == null)
			return dataLen;
		int layerNum = MSRLayer.INVALIND_LAYER_NUM;
		for (MSRLayer layer : allLayers) {
			if (layer == null)
				continue;
			layerNum = layer.num;
			if (layerNum == MSRLayer.INVALIND_LAYER_NUM)
				continue;
			configData[dataLen] = layerNum;
			dataLen++;
			configData[dataLen] = layer.dataLen;
			dataLen++;
			System.arraycopy(layer.data, 0, configData, dataLen, layer.dataLen);
			dataLen += layer.dataLen;
		}
		return dataLen;
	}

	// 配置数据到层
	// 某一层固定放某一层的数据
	public static int deconstructMSRConfigData(int[] configData) {
		int pos = 0;
		if (configData == null)
			return pos;
		// for (MSRLayer layer : layers) {
		// layer.num = configData[pos];
		// pos++;
		// layer.dataLen = configData[pos];
		// pos++;
		// layer.data = new int[layer.dataLen];
		// System.arraycopy(configData, pos, layer.data, 0, layer.dataLen);
		// pos += layer.dataLen;
		// }

		while (configData[pos] > 0) {
			// int layernum = configData[pos];
			int layernum = configData[pos];
			pos++;
			MSRLayer layer = new MSRLayer();
			layer.num = layernum;
			layer.dataLen = configData[pos];
			pos++;
			layer.data = new int[layer.dataLen];
			System.arraycopy(configData, pos, layer.data, 0, layer.dataLen);
			pos += layer.dataLen;
			if (layernum > 16) {
				allLayers[(layernum & 0xf) - 1] = layer;
				continue;
			}
			if ((layernum - 1) < 0 || (layernum - 1) > 10)
				continue;
			allLayers[layernum - 1] = layer;
		}

		return pos;
	}

	private static byte b2i(boolean flag) {
		if (flag)
			return (byte) 1;
		return (byte) 0;
	}

	// 未勾选时磁道号传0
	// 层到层参数
	public static MSRLayer1Params resolveMSRLayer1() {     //20210803 zzy
		MSRLayer1Params params = new MSRLayer1Params();
		MSRLayer layer1 = allLayers[0];
		int[] bs = layer1.data;

		params.ch1ss = (char) bs[0];
		params.ch1es = (char) bs[1];
		params.ch2ss = (char) bs[2];
		params.ch2es = (char) bs[3];
		params.ch3ss = (char) bs[4];
		params.ch3es = (char) bs[5];
		params.beepFlag = ((bs[6] >> 0 & 1) == 1);
		params.ibmFlag = ((bs[6] >> 2 & 1) == 1);
		params.checkFormatFlag = ((bs[6] >> 3 & 1) == 1);
		params.usbModeFlag = ((bs[6] >> 4 & 1) == 1);
		params.newFlag = ((bs[6] >> 5 & 1) == 1);

		params.card1 = bs[7] & 0x3;
		params.chard1EnterFlag = ((bs[7] >> 2 & 0x01) == 1);
		params.card2 = bs[8] & 0x3;
		params.chard2EnterFlag = ((bs[8] >> 2 & 0x01) == 1);
		params.card3 = bs[9] & 0x3;
		params.chard3EnterFlag = ((bs[9] >> 2 & 0x01) == 1);

		params.iButtonOnOffsetStart = bs[10] >> 0 & 0xf;
		params.iButtonOnOffsetType = bs[10] >> 4 & 0xf;

		params.iButtonOnOffsetLen = bs[11] >> 0 & 0xf;
		params.iButtonOnBeepFlag = ((bs[11] >> 4 & 0x01) == 1);

		params.iButtonOffOffsetStart = bs[12] >> 0 & 0xf;
		params.iButtonOffOffsetType = bs[12] >> 4 & 0xf;

		params.iButtonOffOffsetLen = bs[13] >> 0 & 0xf;
		params.iButtonOffBeepFlag = ((bs[13] >> 4 & 0x01) == 1);

		params.iButtonss = (char) bs[14];
		params.iButtones = (char) bs[15];
		params.jis2ss = (char) bs[16];
		params.jis2es = (char) bs[17];

		System.arraycopy(layer1.data, 0, bs, 0, bs.length);

		return params;
	}

	// 层参数到层
	public static void buildMSRLayer1Data(MSRLayer1Params params) {
		MSRLayer layer1 = new MSRLayer(1, MSRPacket.MSR_LAYER1_LEN);
		int[] bs = new int[MSRPacket.MSR_LAYER1_LEN];

		bs[0] = params.ch1ss;
		bs[1] = params.ch1es;
		bs[2] = params.ch2ss;
		bs[3] = params.ch2es;
		bs[4] = params.ch3ss;
		bs[5] = params.ch3es;
		bs[6] = ((b2i(params.beepFlag) << 0) | (b2i(params.ibmFlag) << 2)
				| (b2i(params.checkFormatFlag) << 3)
				| (b2i(params.usbModeFlag) << 4) | (b2i(params.newFlag) << 5));
		bs[7] = (((0x30 + params.card1) << 0) | (b2i(params.chard1EnterFlag) << 2));
		bs[8] = (((0x30 + params.card2) << 0) | (b2i(params.chard2EnterFlag) << 2));
		bs[9] = (((0x30 + params.card3) << 0) | (b2i(params.chard3EnterFlag) << 2));

		bs[10] = ((params.iButtonOnOffsetStart << 0) | (params.iButtonOnOffsetType << 4));
		bs[11] = ((params.iButtonOnOffsetLen << 0) | (b2i(params.iButtonOnBeepFlag) << 4));
		bs[12] = ((params.iButtonOffOffsetStart << 0) | (params.iButtonOffOffsetType << 4));
		bs[13] = ((params.iButtonOffOffsetLen << 0) | (b2i(params.iButtonOffBeepFlag) << 4));

		bs[14] = params.iButtonss;
		bs[15] = params.iButtones;
		bs[16] = params.jis2ss;
		bs[17] = params.jis2es;

		for (int i = 0; i < MSRPacket.MSR_LAYER1_LEN; i++)
			bs[i] &= ~(1 << 8);
		System.arraycopy(bs, 0, layer1.data, 0, bs.length);
		allLayers[0] = layer1;
	}

	private static int[] arr2ToArr1(int[][] arr2, int row, int col) {
		int[] arr1 = new int[row * col];
		int k = 0;
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				arr1[k] = arr2[i][j];
				k++;
			}
		}
		return arr1;
	}

	// 层到层参数
	public static MSRLayer2Params resolveMSRLayer2() {
		MSRLayer2Params param2 = new MSRLayer2Params();
		MSRLayer layer2 = allLayers[1];
		param2.index = layer2.data[0];
		return param2;
	}

	// 层参数到层
	public static void buildMSRLayer2Data(int index) {
		int[][] codes = MSRConstants.HID_SCANCODE[index];
		int[] data = arr2ToArr1(codes, MSRConstants.ROW, MSRConstants.COL);
		// 语言类型-2个结束符
		MSRLayer layer2 = new MSRLayer(2, (data.length + 1 - 2));
		layer2.data[0] = index;
		System.arraycopy(data, 0, layer2.data, 1, (data.length - 2));
		allLayers[1] = layer2;
		Log.e("gary", "buildMSRLayer2Data " + (data.length + 1 - 2));
	}

	public static void invalidateMSRLayerNData(int n) {
		allLayers[n - 1].num = MSRLayer.INVALIND_LAYER_NUM;
	}

	// 构建第3->11层
	// 层参数到层
	public static void buildMSRLayerNData(MSRLayerNParam param3) {
		int n = param3.n;
		boolean asciiMode = param3.asciiMode;
		int[] data = param3.data;
		if (n < 3 || n > 11)
			return;
		int laynum = asciiMode ? (0x10 | n) : n;
		MSRLayer layern = new MSRLayer(laynum, data.length);

		if (layern.dataLen == 0 || layern.data == null
				|| layern.data.length < 1)
			layern.num = MSRLayer.INVALIND_LAYER_NUM;
		else
			System.arraycopy(data, 0, layern.data, 0, data.length);
		allLayers[n - 1] = layern;
		return;
	}

	// 层到层参数
	public static MSRLayerNParam resolveMSRLayerN(int n) {
		if (n < 3 || n > 11)
			return null;
		MSRLayer layern = allLayers[n - 1];
		if (layern.num == MSRLayer.INVALIND_LAYER_NUM)
			return null;
		MSRLayerNParam paramN = new MSRLayerNParam();
		paramN.n = n;
		paramN.asciiMode = ((layern.num >> 4 & 0x1) == 1);
		paramN.data = new int[layern.dataLen];
		System.arraycopy(layern.data, 0, paramN.data, 0, layern.dataLen);
		return paramN;
	}

	public static List<MSRLayerNParam> resolveMSRLayerNs() {
		List<MSRLayerParams.MSRLayerNParam> paramLst = new ArrayList<MSRLayerParams.MSRLayerNParam>();
		MSRLayerParams.MSRLayerNParam paramn = null;
		for (int n = 3; n < 12; n++) {
			paramn = resolveMSRLayerN(n);
			if (paramn == null)
				continue;
			paramLst.add(paramn);
		}
		return paramLst;
	}
}
