package com.yeechart.dotMatrix.minilzo;

import com.yeechart.dotMatrix.crc.CustomCRC32Util;
import com.yeechart.dotMatrix.minilzo.bean.MInt;
import com.yeechart.dotMatrix.signage.bean.mizilzo.MiniLZOVo;

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

public class MiniLZOUtil {


    private static int maxByteSize = 10 * 1000;
    private static MiniLZOUtil miniLZOUtil;

    public static MiniLZOUtil getInstance() {
        if (miniLZOUtil == null) {
            synchronized (MiniLZOUtil.class) {
                if (miniLZOUtil == null) {
                    miniLZOUtil = new MiniLZOUtil();
                }
            }
        }
        return miniLZOUtil;
    }

    public static void initConfig(int maxByteSize2) {
        maxByteSize = maxByteSize2;
    }
    /************************************** 压缩和解压缩  **************************************/


    /**
     * 分段压缩
     *
     * @param data
     * @return
     */
    public List<MiniLZOVo> subMiniLZO(byte[] data) {
        int multiple = data.length / maxByteSize;
        if (data.length % maxByteSize > 0) {
            multiple++;
        }

        List<MiniLZOVo> miniLZOVoList = new ArrayList<>();
        byte[] dataByte = new byte[data.length];
        for (int i = 0; i < multiple; i++) {
            int trueSize = Math.min(maxByteSize, data.length - i * maxByteSize);
            dataByte = new byte[trueSize];
            System.arraycopy(data, i * maxByteSize, dataByte, 0,
                    trueSize);

            miniLZOVoList.add(MiniLZO(dataByte));
        }

        return miniLZOVoList;
    }


    /**
     * 将数据进行压缩
     *
     * @param data
     * @return
     */
    private MiniLZOVo MiniLZO(byte[] data) {
        byte[] outByte = new byte[data.length];
        MInt outL = new MInt();
        int[] dict = new int[128 * 1024];

        MiniLZO.lzo1x_1_compress(data, data.length, outByte, outL, dict);

//        logger.info("压缩后的长度 outLen  len:" + outL.v);

        //实际数据为
        byte[] outByteTrue = new byte[outL.v];

        System.arraycopy(outByte, 0, outByteTrue, 0, outL.v);

//        logger.info("真实的数组长度:" + outByteTrue.length);

        MiniLZOVo miniLZOVo = new MiniLZOVo();
        miniLZOVo.setOgSize(data.length);
        miniLZOVo.setData(outByteTrue);

        //进行CRC32算法
        long crc = CustomCRC32Util.calculateCRC32(outByteTrue);
        miniLZOVo.setCrc32(crc);

        return miniLZOVo;
    }

}
