package com.yeechart.dotMatrix.canvas;

import java.nio.ByteBuffer;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.IntStream;

/**
 * 点阵图 转换 工具
 */
public class DotMatrixConversionUtil {

    /**
     * 二进制点阵转换为16进制点阵数组
     *
     * @param twoBytes 字节型
     * @return
     */
    public static byte[] twoTo16Lattice(byte[] twoBytes) {

        int byteCount = twoBytes.length / 8;
        if (twoBytes.length % 8 > 0) {
            byteCount = byteCount + 1;
        }
        ByteBuffer byteBuffer = ByteBuffer.allocate(byteCount);
        int byteValue = 0;
        int bitCount = 0;

        for (int i = 0; i < twoBytes.length; i++) {
            int bit = twoBytes[i];
            byteValue = (byteValue << 1) | bit;
            bitCount++;

            if (bitCount == 8) {
                byteBuffer.put((byte) byteValue);
                byteValue = 0;
                bitCount = 0;
            }
        }

        if (bitCount > 0) {
            byteBuffer.put((byte) byteValue);
        }

        byteBuffer.flip();
        byte[] byteArray = new byte[byteBuffer.remaining()];
        byteBuffer.get(byteArray);

        return byteArray;


    }


    /**
     * 16进制点阵图转换为二进制点阵图
     *
     * @param sixteenBytes
     * @return
     */
    public static byte[] sixteenTo2Lattice(byte[] sixteenBytes) {

        int length = sixteenBytes.length * 8;
        byte[] result = new byte[length];

        int batchSize = 1024; // 每批次处理的字节数
        int numBatches = (sixteenBytes.length + batchSize - 1) / batchSize;

        ForkJoinPool.commonPool().submit(() -> IntStream.range(0, numBatches)
                .parallel()
                .forEach(batch -> {
                    int start = batch * batchSize;
                    int end = Math.min(start + batchSize, sixteenBytes.length);

                    for (int i = start; i < end; i++) {
                        for (int b = 7, k = i * 8; b >= 0; b--, k++) {
                            result[k] = (byte) ((sixteenBytes[i] & (1 << b)) != 0 ? 1 : 0);
                        }
                    }
                })).join();

        return result;
    }


    /**
     * 二进制点阵转换为16进制点阵数组
     *
     * @param canvasBitmapArrays 二位素组
     * @return
     */
    public static byte[] twoTo16Lattice(int[][] canvasBitmapArrays) {

        int[] twoBytes = new int[canvasBitmapArrays.length * canvasBitmapArrays[0].length];

        for (int i = 0; i < canvasBitmapArrays.length; i++) {
            for (int j = 0; j < canvasBitmapArrays[i].length; j++) {
                twoBytes[i * canvasBitmapArrays[i].length + j] = canvasBitmapArrays[i][j];
            }
        }

        int byteCount = twoBytes.length / 8;
        if (twoBytes.length % 8 > 0) {
            byteCount = byteCount + 1;
        }
        ByteBuffer byteBuffer = ByteBuffer.allocate(byteCount);
        int byteValue = 0;
        int bitCount = 0;

        for (int i = 0; i < twoBytes.length; i++) {
            int bit = twoBytes[i];
            byteValue = (byteValue << 1) | bit;
            bitCount++;

            if (bitCount == 8) {
                byteBuffer.put((byte) byteValue);
                byteValue = 0;
                bitCount = 0;
            }
        }

        if (bitCount > 0) {
            byteBuffer.put((byte) byteValue);
        }

        byteBuffer.flip();
        byte[] byteArray = new byte[byteBuffer.remaining()];
        byteBuffer.get(byteArray);

        return byteArray;

    }
}
