package com.sensetime.demo.util;

import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;

import com.blankj.utilcode.util.LogUtils;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class BitmapUtils {

    public static byte[] convertNv21ToJpeg(byte[] nv21, int w, int h, Rect rect) {
        if (rect == null) rect = new Rect(0, 0, w, h);
        YuvImage image = new YuvImage(nv21, ImageFormat.NV21, w, h, null);
        ByteArrayOutputStream outputSteam = new ByteArrayOutputStream();
        image.compressToJpeg(rect, 70, outputSteam);
        return outputSteam.toByteArray();
    }

    public static byte[] btmToBytes(Bitmap btm, int quality){
        if(btm == null || btm.isRecycled()) return null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        btm.compress(Bitmap.CompressFormat.JPEG, quality, baos);
        return baos.toByteArray();
    }

    public static Bitmap getCropBitmap(Bitmap sourceBitmap, Rect originRect, int scale) {
        return getCropBitmap(sourceBitmap, originRect, scale, scale);
    }

    public static Bitmap getCropBitmap(Bitmap sourceBitmap, Rect orginRect, float scaleX, float scaleY) {
        if (sourceBitmap == null || sourceBitmap.isRecycled()) {
            return null;
        }
        Rect rect = getScaleRect(orginRect, scaleX, scaleY, sourceBitmap.getWidth(), sourceBitmap.getHeight());
        if (rect.width() <= 0 || rect.height() <= 0) return null;
        return sourceBitmap.createBitmap(sourceBitmap, rect.left, rect.top, rect.width(), rect.height());
    }

    public static Rect getScaleRect(Rect rect, float scaleX, float scaleY, int maxW, int maxH) {
        Rect resultRect = new Rect();
        int left = (int) (rect.left - rect.width() * (scaleX - 1) / 2);
        int right = (int) (rect.right + rect.width() * (scaleX - 1) / 2);
        int bottom = (int) (rect.bottom + rect.height() * (scaleY - 1) / 2);
        int top = (int) (rect.top - rect.height() * (scaleY - 1) / 2);
        resultRect.left = left > 0 ? left : 0;
        resultRect.right = right > maxW ? maxW : right;
        resultRect.bottom = bottom > maxH ? maxH : bottom;
        resultRect.top = top > 0 ? top : 0;
        return resultRect;
    }

    public static byte[] rotateYUV420Degree90(byte[] data, byte [] yuv,int imageWidth, int imageHeight) {

        int i = 0;
        for (int x = 0; x < imageWidth; x++) {
            for (int y = imageHeight - 1; y >= 0; y--) {
                yuv[i] = data[y * imageWidth + x];
                i++;
            }
        }
        i = imageWidth * imageHeight * 3 / 2 - 1;
        for (int x = imageWidth - 1; x > 0; x = x - 2) {
            for (int y = 0; y < imageHeight / 2; y++) {
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
                i--;
                yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth)
                        + (x - 1)];
                i--;
            }
        }
        return yuv;
    }

    public static void  yuy2toNv21(byte[] yuy2, byte nv21[] , int width, int height) {
        int ySize = width * height;
        int originUVSize = ySize / 2;

        int yIndex = 0;
        int uvIndex = ySize;
        for (int i = 0; i < originUVSize; i++) {

            int index = i * 4;
            nv21[yIndex] = yuy2[index];
            nv21[yIndex + 1] = yuy2[index + 2];
            yIndex += 2;

            if (Math.floor(yIndex / width + 1) % 2 == 1) {
                nv21[uvIndex] = yuy2[index + 3];
                nv21[uvIndex + 1] = yuy2[index +1];
                uvIndex += 2;
            }
        }
    }

    public static void writeImageToDisk(byte[] img, String fileName) {
        long begin = System.currentTimeMillis();
        FileOutputStream fops = null;
        BufferedOutputStream bos = null;
        try {
            File file = new File(fileName);
            if(!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
            }
            fops = new FileOutputStream(file);
            bos = new BufferedOutputStream(fops);
            bos.write(img);
            LogUtils.d("IO","time:"+(System.currentTimeMillis()-begin));
        } catch (Exception e) {
            LogUtils.e(e.getMessage());
        } finally {
            if(fops != null) {
                try {
                    fops.close();
                } catch (IOException e) {
                    LogUtils.e(e.getMessage());
                }
            }

            if(bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    LogUtils.e(e.getMessage());
                }
            }
        }
    }
}
