package com.yeechart.dotMatrix.canvas;

import com.yeechart.dotMatrix.font.XZPFontLoaderUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * 绘制文字
 */
@Component
public class DotMatrixDrawtextUtil {

    @Autowired
    private XZPFontLoaderUtil xzpFontLoaderUtil;

    /**
     * 绘制文字 横向
     *
     * @param bitmapData  二进制点阵画布数组
     * @param text        文本内容
     * @param startRow    文本内容左上角的横坐标 （列）
     * @param startColumn 文本内容左上角的纵坐标  (行)
     * @param fontSize    文本的字体大小(不写，或者不合适时将自动使用字体库中该文本的最小的字体样式)
     * @return 绘制之后的二进制点阵画布数组
     */
    public  void drawingText(int[][] bitmapData, String text, int startRow, int startColumn, int fontSize) {
        int[][] fontBinaryArray = getManyFontBinaryArray(text, fontSize, fontSize, true);
        DotMatrixCanvasUtil.mergeDotMatrices(bitmapData, fontBinaryArray, startRow, startColumn);

    }

    /**
     * 绘制文字 横向
     *
     * @param bitmapData        二进制点阵画布数组
     * @param text              文本内容
     * @param startRow          文本内容左上角的横坐标 （列）
     * @param startColumn       文本内容左上角的纵坐标  (行)
     * @param fontSize          文本的字体大小(不写，或者不合适时将自动使用字体库中该文本的最小的字体样式)
     * @param noChineseFontSize 当遇到非中文字时的字体大小
     * @return 绘制之后的二进制点阵画布数组
     */

    public  void drawingText(int[][] bitmapData, String text, int startRow, int startColumn, int fontSize, int noChineseFontSize) {

        int[][] fontBinaryArray = getManyFontBinaryArray(text, fontSize, noChineseFontSize, true);


        DotMatrixCanvasUtil.mergeDotMatrices(bitmapData, fontBinaryArray, startRow, startColumn);


    }


    /**
     * 绘制文本，返回二进制点阵画布数组
     *
     * @param text
     * @param fontSize
     * @param noChineseFontSize
     * @return
     */
    public  int[][] drawingText(String text, int fontSize, int noChineseFontSize) {
        int[][] fontBinaryArray = getManyFontBinaryArray(text, fontSize, noChineseFontSize, true);

        return fontBinaryArray;
    }

    /**
     * 绘制文本，返回二进制点阵画布数组
     *
     * @param text
     * @param fontSize
     * @param noChineseFontSize
     * @param isHorizontal
     * @return
     */
    public  int[][] drawingText(String text, int fontSize, int noChineseFontSize, boolean isHorizontal) {
        int[][] fontBinaryArray = getManyFontBinaryArray(text, fontSize, noChineseFontSize, isHorizontal);

        return fontBinaryArray;
    }

    /**
     * 获取多个字体的点阵数组
     *
     * @param text
     * @param font
     * @return
     */
    public  int[][] getManyFontBinaryArray(String text, int font, int noChineseFontSize, boolean isHorizontal) {
        char[] chars = text.toCharArray();
        List<int[][]> binaryList = new ArrayList<>();
        for (char c : chars) {
            String singleChar = String.valueOf(c);
            String encoding = xzpFontLoaderUtil.getEncoding(singleChar, "GB2312");
            if (encoding == null) {
                System.out.println("没有找到对应的字 : " + encoding);
                break;
            }
            //非中文
            int font2 = font;
            if (encoding.length() <= 2) {
                font2 = noChineseFontSize;
            }
            int[][] binaryArray = xzpFontLoaderUtil.getSingleFontBinaryArray(encoding, font2);

            if (binaryArray != null) {
                //进行倍数放大
                binaryArray = DotMatrixCanvasUtil.scaleDotMatrix(binaryArray, font2);
                binaryList.add(binaryArray);
            }
        }

        int[][] binaryArray = null;

        int rowsMax = binaryList.get(0).length;
        int columnsMax = binaryList.get(0)[0].length;

        for (int i = 0; i < binaryList.size(); i++) {
            int[][] b = binaryList.get(i);
            rowsMax = Math.max(rowsMax, b.length);
            columnsMax = Math.max(columnsMax, b[0].length);
        }

        for (int[][] b : binaryList) {
            if (binaryArray == null) {
                binaryArray = b;
            } else {
                binaryArray = DotMatrixCanvasUtil.mergeDotMatricesWidth(rowsMax, columnsMax, binaryArray, b, isHorizontal);
            }
        }


        return binaryArray;

    }


    /**
     * 对于中文是竖向排列的，对于其中的英文和数字进行旋转
     *
     * @param text
     * @param fontSize
     * @param noChineseFontSize
     * @return
     */
    public  int[][] drawingChineseAndNonChinese(String text, int fontSize, int noChineseFontSize) {

        //全由数字或英文组成 将其倒转
        char[] chars = text.toCharArray();
        int fontWidth = 0;
        int fontHeight = 0;
        int maxHeight = 0;

        List<int[][]> textFontBinaryArray = new ArrayList<>();
        for (int i = 0; i < chars.length; i++) {
            String str = String.valueOf(chars[i]);

            int[][] charFontBinaryArray = drawingText(str, fontSize, noChineseFontSize, false);

            if (xzpFontLoaderUtil.isAlphanumeric(str)) {

                fontHeight += charFontBinaryArray[0].length;

                if (fontWidth < charFontBinaryArray.length) {
                    fontWidth = charFontBinaryArray.length;
                }

                if (maxHeight < charFontBinaryArray[0].length) {
                    maxHeight = charFontBinaryArray[0].length;
                }

                //需要旋转
                charFontBinaryArray = DotMatrixCanvasUtil.rotateDotMatrix(charFontBinaryArray, 90);
            } else {
                //无需旋转
                fontHeight += charFontBinaryArray.length;

                if (fontWidth < charFontBinaryArray[0].length) {
                    fontWidth = charFontBinaryArray[0].length;
                }

                if (maxHeight < charFontBinaryArray.length) {
                    maxHeight = charFontBinaryArray.length;
                }

            }

            textFontBinaryArray.add(charFontBinaryArray);
        }

        //将文字合并
        int[][] fontBinaryArray = new int[fontHeight]
                [fontWidth];

        for (int i = 0; i < textFontBinaryArray.size(); i++) {
            int[][] fontBinaryArray2 = textFontBinaryArray.get(i);

            DotMatrixCanvasUtil.mergeDotMatrices(
                    fontBinaryArray,
                    fontBinaryArray2,
                    maxHeight * i,
                    fontBinaryArray[0].length / 2 - fontBinaryArray2[0].length / 2);
        }

        return fontBinaryArray;
    }


    /**
     * 倒序且旋转90度去绘制竖向的文字
     *
     * @param text
     * @param noChineseFontSize
     * @return
     */
    public  int[][] drawingNonChinese(String text, int noChineseFontSize) {

        char[] chars = text.toCharArray();
        int fontWidth = 0;
        int fontHeight = 0;
        int maxHeight = 0;
        //将每个字生成之后旋转270度
        List<int[][]> textFontBinaryArray = new ArrayList<>();
        for (int i = chars.length - 1; i >= 0; i--) {
            String str = String.valueOf(chars[i]);
            int[][] charFontBinaryArray = drawingText(str, noChineseFontSize, noChineseFontSize, false);

            if (fontWidth < charFontBinaryArray.length) {
                fontWidth = charFontBinaryArray.length;
            }
            fontHeight += charFontBinaryArray[0].length;

            if (maxHeight < charFontBinaryArray[0].length) {
                maxHeight = charFontBinaryArray[0].length;
            }

            charFontBinaryArray = DotMatrixCanvasUtil.rotateDotMatrix(charFontBinaryArray, 90);

            textFontBinaryArray.add(charFontBinaryArray);
        }

        //将文字合并
        int[][] fontBinaryArray = new int[fontHeight]
                [fontWidth];

        for (int i = 0; i < textFontBinaryArray.size(); i++) {
            int[][] fontBinaryArray2 = textFontBinaryArray.get(i);

            DotMatrixCanvasUtil.mergeDotMatrices(
                    fontBinaryArray,
                    fontBinaryArray2,
                    maxHeight * i,
                    fontBinaryArray[0].length / 2 - fontBinaryArray2[0].length / 2);
        }

        return fontBinaryArray;
    }


    /**
     * 限制文本在单行 将文本限制在一定的范围内，超出范围的使用...代替
     *
     * @param text              文本内容
     * @param fontSize          字体大小
     * @param noChineseFontSize 非中文的字体大小
     * @param maxWidth          一行的最大长度
     * @return
     */
    public  String changeTextOneLine(String text, int fontSize, int noChineseFontSize, int maxWidth) {

        return changeTextMoreLine(text, fontSize, noChineseFontSize, maxWidth, 1).get(0);

    }

    /**
     * 限制文本在多行 将文本限制在一定的范围内，超出范围的使用...代替
     *
     * @param text              文本内容
     * @param fontSize          字体大小
     * @param noChineseFontSize 非中文的字体大小
     * @param maxWidth          一行的最大长度
     * @param maxLine           最多支持多少行
     * @return
     */
    public  List<String> changeTextMoreLine(String text, int fontSize, int noChineseFontSize, int maxWidth, int maxLine) {

        List<String> dataList = new ArrayList<>();
        //首先计算文本的长度
        try {


            char[] chars = text.toCharArray();

            List<String> textList = new ArrayList<>();//记录每个字符
            List<Integer> textLengthList = new ArrayList<>();//记录每个字符的大小

            int textSumLength = 0;

            for (char c : chars) {

                String singleChar = String.valueOf(c);

                int textLength = 0;

                byte[] bytes = singleChar.getBytes("GB2312");

                StringBuilder hex = new StringBuilder();

                for (byte b : bytes) {
                    hex.append(String.format("%02x", b));
                }

                if (hex.toString().length() <= 2) {
                    //非中文
                    textLength = noChineseFontSize;
                } else {
                    //中文
                    textLength = fontSize;
                }

                textList.add(singleChar);
                textLengthList.add(textLength);
                textSumLength = textSumLength + textLength;

            }


            //将字段进行分装
            String data = "";
            int dataSize = 0;
            int endNumber = 0;

            int line = 1;

            for (int i = 0; i < textList.size(); i++) {
                dataSize = dataSize + textLengthList.get(i);
                if (dataSize <= maxWidth) {
                    data = data + textList.get(i);
                } else {
                    if (line < maxLine) {
                        dataList.add(data);
                        data = textList.get(i);
                        dataSize = textLengthList.get(i);
                        endNumber = i;//记录换行点 该点为换行的第一个字符的下标

                        line++;
                    } else {
                        break;//无需再循环 因为已经超出了
                    }
                }
            }

            if (textSumLength <= maxWidth * maxLine) {
                //字符长度小于限制长度 无需处理 直接返回
                dataList.add(data);//将最后一项 添加至列表
                return dataList;
            }

            //需要进行省略处理
            String substituteSymbol = ".";//省略点需要三个  [・] 这个点间隔太大 且此点为中文点 [·]这个点找不到编码 所以暂时使用[.]这个点
            data = "";//重新初始化
            dataSize = 0;//重新初始化

            //此处可以优化为从后面开始计数的方式 暂时没时间优化
            for (int i = endNumber; i < textList.size(); i++) {
                dataSize = dataSize + textLengthList.get(i);
                if ((dataSize + 3 * noChineseFontSize) <= maxWidth) {

                    data = data + textList.get(i);

                    int dataSize2 = dataSize + textLengthList.get(i + 1);
                    if ((dataSize2 + 3 * noChineseFontSize) > maxWidth) {
                        //跳出循环 找到了拼接点
                        break;
                    }
                }
            }


            dataList.add(data + substituteSymbol + substituteSymbol + substituteSymbol);//将最后一项 添加至列表
            return dataList;


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

        return dataList;
    }


}
