package com.fuyuanshen.common.core.utils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class ImageToCArrayConverter {

/*    public static void main(String[] args) {
        try {
            byte[] imageData = convertImageToCArray("E:\\workspace\\6170_强光_160_80_2.jpg", 160, 80,25600);
            System.out.println("长度："+imageData.length);
//            int[] ints =convertHexToDecimal(imageData);
//            System.out.println("Image data: " + Arrays.toString(ints));
//            writeFile("E:\\workspace\\output.c", imageData,160,80);
//            System.out.println("转换成功！");
            ArrayList<Integer> intData = new ArrayList<>();
            intData.add(2);
            buildArr(convertHexToDecimal(imageData),intData);
            intData.add(0);
            intData.add(0);
            intData.add(0);
            intData.add(0);
            Map<String, Object> map = new HashMap<>();
            map.put("instruct", intData);
            System.out.println(JSON.toJSONString( map));
        } catch (IOException e) {
            System.err.println("转换失败: " + e.getMessage());
        }
    }*/

    public static void main(String[] args) throws IOException {

        byte[] largeData = convertImageToCArray("E:\\workspace\\demo.png", 160, 80,25600);
        System.out.println("长度："+largeData.length);

        System.out.println("原始数据大小: " + largeData.length + " 字节");

        // 将25600字节的数据分割成512字节的块
//        List<byte[]> chunks = splitByteArrayIntoChunks(largeData, 512);
//        printChunkInfo(chunks);
//
//        // 打印前几块的数据示例
//        System.out.println("\n前3块数据示例（十进制显示）:");
//        for (int i = 0; i < Math.min(50, chunks.size()); i++) {
//            System.out.println("块 " + i + ":");
//            int[] ints = convertHexToDecimal(chunks.get(i));
//            System.out.println(Arrays.toString(ints));
//        }

        // 示例：获取特定块的数据
        byte[] specificChunk = getChunk(largeData, 5, 512); // 获取第6块（索引5）
        System.out.println("第6块数据大小: " + specificChunk.length + " 字节");

        // 生成预览图片
//        BufferedImage image = convertByteArrayToImage(bitmapData, 12, 80);
//        ImageIO.write(image, "PNG", new File("D:\\bitmap_preview.png"));
//        System.out.println("成功生成预览图片: D:\\bitmap_preview.png");
//
//        // 生成C文件
//        generateCFile(bitmapData, "bitmap_data.c", "chinese_text");
    }
    /**
     * 获取指定块的数据
     *
     * @param data 原始字节数组
     * @param chunkIndex 块索引（从0开始）
     * @param chunkSize 每块大小
     * @return 指定块的字节数组，如果索引无效则返回空数组
     */
    public static byte[] getChunk(byte[] data, int chunkIndex, int chunkSize) {
        if (data == null || chunkSize <= 0 || chunkIndex < 0) {
            return new byte[0];
        }

        int start = chunkIndex * chunkSize;
        if (start >= data.length) {
            return new byte[0]; // 索引超出范围
        }

        int end = Math.min(start + chunkSize, data.length);
        int length = end - start;

        byte[] chunk = new byte[length];
        System.arraycopy(data, start, chunk, 0, length);
        return chunk;
    }

    public static String[] getChunk2(String[] data, int chunkIndex, int chunkSize) {
        if (data == null || chunkSize <= 0 || chunkIndex < 0) {
            return new String[0];
        }

        int start = chunkIndex * chunkSize;
        if (start >= data.length) {
            return new String[0]; // 索引超出范围
        }

        int end = Math.min(start + chunkSize, data.length);
        int length = end - start;

        String[] chunk = new String[length];
        System.arraycopy(data, start, chunk, 0, length);
        return chunk;
    }

    public static void  buildArr(int[]  data,List<Integer> intData){
        for (int datum : data) {
            intData.add(datum);
        }
    }

    /**
     * 打印分块信息
     *
     * @param chunks 分块后的字节数组列表
     */
    public static void printChunkInfo(List<byte[]> chunks) {
        System.out.println("总共分割成 " + chunks.size() + " 块");
        for (int i = 0; i < chunks.size(); i++) {
            System.out.println("块 " + i + ": " + chunks.get(i).length + " 字节");
        }
    }
    /**
     * 将大字节数组分割成固定大小的块
     *
     * @param data 原始字节数组
     * @param chunkSize 每块大小（字节数）
     * @return 分割后的字节数组列表
     */
    public static List<byte[]> splitByteArrayIntoChunks(byte[] data, int chunkSize) {
        if (data == null || data.length == 0 || chunkSize <= 0) {
            return new ArrayList<>();
        }

        List<byte[]> chunks = new ArrayList<>();
        int totalChunks = (int) Math.ceil((double) data.length / chunkSize);

        for (int i = 0; i < totalChunks; i++) {
            int start = i * chunkSize;
            int end = Math.min(start + chunkSize, data.length);
            int length = end - start;

            byte[] chunk = new byte[length];
            System.arraycopy(data, start, chunk, 0, length);
            chunks.add(chunk);
        }

        return chunks;
    }

    public static int[] convertHexToDecimal(byte[] data) {
        if (data == null) {
            return new int[0];
        }

        int[] decimalArray = new int[data.length];
        for (int i = 0; i < data.length; i++) {
            // 将字节转换为无符号整数（十进制）
            decimalArray[i] = data[i] & 0xFF;
        }

        return decimalArray;
    }

    public static byte[] convertImageToCArray(InputStream inputStream,
                                              int width, int height, int fixedLength) throws IOException {
        // 读取原始图片
        BufferedImage originalImage = ImageIO.read(inputStream);

        // 调整图片尺寸
        BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        resizedImage.getGraphics().drawImage(
                originalImage, 0, 0, width, height, null);

        // 转换像素数据为RGB565格式（高位在前）
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = resizedImage.getRGB(x, y);

                // 提取RGB分量
                int r = (rgb >> 16) & 0xFF;
                int g = (rgb >> 8) & 0xFF;
                int b = rgb & 0xFF;

                // 转换为RGB565（5位红，6位绿，5位蓝）
                int r5 = (r >> 3) & 0x1F;
                int g6 = (g >> 2) & 0x3F;
                int b5 = (b >> 3) & 0x1F;

                // 组合为16位值
                int rgb565 = (r5 << 11) | (g6 << 5) | b5;

                // 高位在前（大端序）写入字节
                byteStream.write((rgb565 >> 8) & 0xFF); // 高字节
                byteStream.write(rgb565 & 0xFF);        // 低字节
            }
        }
        // 调整到固定长度
        byte[] rawData = byteStream.toByteArray();
        byte[] result = new byte[fixedLength];
        int copyLength = Math.min(rawData.length, fixedLength);
        System.arraycopy(rawData, 0, result, 0, copyLength);
        return result;
    }

    public static byte[] convertImageToCArray(String inputPath,
                                            int width, int height, int fixedLength) throws IOException {
        // 读取原始图片
        BufferedImage originalImage = ImageIO.read(new File(inputPath));

        // 调整图片尺寸
        BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        resizedImage.getGraphics().drawImage(
                originalImage, 0, 0, width, height, null);

        // 转换像素数据为RGB565格式（高位在前）
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = resizedImage.getRGB(x, y);

                // 提取RGB分量
                int r = (rgb >> 16) & 0xFF;
                int g = (rgb >> 8) & 0xFF;
                int b = rgb & 0xFF;

                // 转换为RGB565（5位红，6位绿，5位蓝）
                int r5 = (r >> 3) & 0x1F;
                int g6 = (g >> 2) & 0x3F;
                int b5 = (b >> 3) & 0x1F;

                // 组合为16位值
                int rgb565 = (r5 << 11) | (g6 << 5) | b5;

                // 高位在前（大端序）写入字节
                byteStream.write((rgb565 >> 8) & 0xFF); // 高字节
                byteStream.write(rgb565 & 0xFF);        // 低字节
            }
        }
        // 调整到固定长度
        byte[] rawData = byteStream.toByteArray();
        byte[] result = new byte[fixedLength];
        int copyLength = Math.min(rawData.length, fixedLength);
        System.arraycopy(rawData, 0, result, 0, copyLength);
        return result;
    }

    private static void writeFile(String outputPath, byte[] imageData,int width, int height) throws IOException {
        // 生成C语言数组文件
        try (FileOutputStream fos = new FileOutputStream(outputPath)) {
            // 写入注释行（包含尺寸信息）
            String header = String.format("/* 0X10,0X10,0X00,0X%02X,0X00,0X%02X,0X01,0X1B, */\n",
                    width, height);
            fos.write(header.getBytes());

            // 写入数组声明
            fos.write("const unsigned char gImage_data[] = {\n".getBytes());

            // 写入数据（每行16个字节）
            for (int i = 0; i < imageData.length; i++) {
                // 写入0X前缀
                fos.write(("0X" + String.format("%02X", imageData[i] & 0xFF)).getBytes());

                // 添加逗号（最后一个除外）
                if (i < imageData.length - 1) {
                    fos.write(',');
                }

                // 换行和缩进
                if ((i + 1) % 16 == 0) {
                    fos.write('\n');
                } else {
                    fos.write(' ');
                }
            }

            // 写入数组结尾
            fos.write("\n};\n".getBytes());
        }
    }

    /**
     * 将字节字符串转换为字节数组
     *
     * @param byteString 字节字符串，格式如 "[12, 45, 67, ...]"
     * @return 字节数组
     */
    public static byte[] convertStringToByteArray(String byteString) {
        if (byteString == null || byteString.isEmpty()) {
            return new byte[0];
        }

        try {
            // 移除方括号
            String content = byteString.trim();
            if (content.startsWith("[")) {
                content = content.substring(1);
            }
            if (content.endsWith("]")) {
                content = content.substring(0, content.length() - 1);
            }

            // 按逗号分割
            String[] byteValues = content.split(",");
            byte[] result = new byte[byteValues.length];

            // 转换每个值
            for (int i = 0; i < byteValues.length; i++) {
                String value = byteValues[i].trim();
                // 处理可能的进制前缀
                if (value.startsWith("0x") || value.startsWith("0X")) {
                    // 十六进制
                    result[i] = (byte) Integer.parseInt(value.substring(2), 16);
                } else {
                    // 十进制
                    int intValue = Integer.parseInt(value);
                    result[i] = (byte) intValue;
                }
            }

            return result;
        } catch (NumberFormatException e) {
            System.err.println("解析字节字符串时出错: " + e.getMessage());
            return new byte[0];
        }
    }

    /**
     * 将字节字符串转换为混合类型的Object数组
     *
     * @param byteString 字节字符串
     * @return Object数组，包含不同类型的对象
     */
    public static Object[] convertByteStringToMixedObjectArray(String byteString) {
        if (byteString == null || byteString.isEmpty()) {
            return new Object[0];
        }

        try {
            // 移除方括号（如果存在）
            String content = byteString.trim();
            if (content.startsWith("[")) {
                content = content.substring(1);
            }
            if (content.endsWith("]")) {
                content = content.substring(0, content.length() - 1);
            }

            // 按逗号分割
            String[] byteValues = content.split(",");
            Object[] result = new Object[byteValues.length];

            // 转换每个值为适当类型的对象
            for (int i = 0; i < byteValues.length; i++) {
                String value = byteValues[i].trim();

                // 处理可能的进制前缀
                if (value.startsWith("0x") || value.startsWith("0X")) {
                    // 十六进制
                    int intValue = Integer.parseInt(value.substring(2), 16);
                    result[i] = intValue;
                } else {
                    // 尝试解析为整数
                    try {
                        int intValue = Integer.parseInt(value);
                        // 根据值的范围选择合适的类型
                        if (intValue >= Byte.MIN_VALUE && intValue <= Byte.MAX_VALUE) {
                            result[i] = (byte) intValue;
                        } else if (intValue >= Short.MIN_VALUE && intValue <= Short.MAX_VALUE) {
                            result[i] = (short) intValue;
                        } else {
                            result[i] = intValue;
                        }
                    } catch (NumberFormatException e) {
                        // 如果不是数字，保持为字符串
                        result[i] = value;
                    }
                }
            }

            return result;
        } catch (Exception e) {
            System.err.println("解析字节字符串时出错: " + e.getMessage());
            return new Object[0];
        }
    }
}