package com.duben.microtribe.utils;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;


import com.duben.microtribe.common.Constant;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;

/**
 * 图片util
 *
 * @author renjl
 * @time Apr 30, 2015 5:20:37 PM
 * @explain
 */
public class ImageUtil {

    /**
     * Android10 保存图片到缓存
     */
    public static String saveBitmap2Cache(Context context, Bitmap bitmap, String bitName) {
        File file;

        String pathDir = context.getExternalCacheDir() + "/photos/";
        File fileDir = new File(pathDir);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }

        String fileName = pathDir + bitName;

        file = new File(fileName);

        FileOutputStream out;

        try {
            out = new FileOutputStream(file);
            bitmap.compress(CompressFormat.JPEG, 95, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            // 如果图片还没有回收，强制回收
            if (!bitmap.isRecycled()) {
                bitmap.recycle();
                System.gc();
            }
        }

        return fileName;
    }

    /**
     * Android10 保存图片到相册
     */
    public static String saveBitmap(Context context, Bitmap bitmap, String bitName) {
        File file;

        String pathDir = Environment.getExternalStorageDirectory().getPath() + "/DCIM/" + Constant.MINTS_PKG_NAME + "/";
        File fileDir = new File(pathDir);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }

        String fileName = pathDir + bitName;

        if (Build.VERSION.SDK_INT >= 29) {
            saveSignImage(context, bitName, bitmap);
            return fileName;
        } else {
            file = new File(fileName);
        }

        FileOutputStream out;
        try {
            out = new FileOutputStream(file);
            // 格式为 JPEG，照相机拍出的图片为JPEG格式的，PNG格式的不能显示在相册中
            if (bitmap.compress(CompressFormat.JPEG, 100, out)) {
                out.flush();
                out.close();
                // 插入图库
//                MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), bitName, null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        // 发送广播，通知刷新图库的显示
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + fileName)));
        return fileName;
    }

    //将文件保存到公共的媒体文件夹
    //这里的filepath不是绝对路径，而是某个媒体文件夹下的子路径，和沙盒子文件夹类似
    //这里的filename单纯的指文件名，不包含路径
    public static void saveSignImage(Context context, String fileName, Bitmap bitmap) {
        try {
            //设置保存参数到ContentValues中
            ContentValues contentValues = new ContentValues();
            //设置文件名
            contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
            //兼容Android Q和以下版本
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                //android Q中不再使用DATA字段，而用RELATIVE_PATH代替
                //RELATIVE_PATH是相对路径不是绝对路径
                //DCIM是系统文件夹，关于系统文件夹可以到系统自带的文件管理器中查看，不可以写没存在的名字
                contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "DCIM/" + Constant.MINTS_PKG_NAME);
            } else {
                contentValues.put(MediaStore.Images.Media.DATA, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath());
            }
            //设置文件类型
//            contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/JPEG");
            //执行insert操作，向系统文件夹中添加文件
            //EXTERNAL_CONTENT_URI代表外部存储器，该值不变
            Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            if (uri != null) {
                //若生成了uri，则表示该文件添加成功
                //使用流将内容写入该uri中即可
                OutputStream outputStream = context.getContentResolver().openOutputStream(uri);
                if (outputStream != null) {
                    bitmap.compress(CompressFormat.JPEG, 100, outputStream);
                    outputStream.flush();
                    outputStream.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static Bitmap getBitmapFromUri(Context context, Uri uri) {
        try {
            ParcelFileDescriptor parcelFileDescriptor =
                    context.getContentResolver().openFileDescriptor(uri, "r");
            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
            Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
            parcelFileDescriptor.close();
            return image;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 读取图片的旋转的角度
     *
     * @param path 图片绝对路径
     * @return 图片的旋转角度
     */
    public static int getBitmapDegree(String path) {
        int degree = 0;
        try {
            // 从指定路径下读取图片，并获取其EXIF信息
            ExifInterface exifInterface = new ExifInterface(path);
            // 获取图片的旋转信息
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 复制原图Exif信息到压缩后图片的Exif信息
     *
     * @param sourcePath 原图路径
     * @param targetPath 目标图片路径
     */
    public static void copyExif(String sourcePath, String targetPath) {
        try {
            ExifInterface source = new ExifInterface(sourcePath);
            ExifInterface target = new ExifInterface(targetPath);

            for (Field declaredField : source.getClass().getDeclaredFields()) {

                //获取ExifInterface类的属性并遍历
                declaredField.setAccessible(true);
                Object tag = declaredField.get(source); //获取原图EXIF实例种的成员变量

                if (declaredField.getName().startsWith("TAG_") && tag instanceof String) {//判断变量是否以TAG开头，并且是String类型
                    target.setAttribute((String) tag, source.getAttribute((String) tag));//设置压缩图的EXIF信息
                    target.saveAttributes();//保存属性更改
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 复制原图Exif信息到压缩后图片的Exif信息
     *
     * @param sourcePath 原图路径
     */
    public static void editTagOrientation(String sourcePath) {
        try {
            ExifInterface source = new ExifInterface(sourcePath);
            for (Field declaredField : source.getClass().getDeclaredFields()) {
                //获取ExifInterface类的属性并遍历
                declaredField.setAccessible(true);
                Object tag = declaredField.get(source); //获取原图EXIF实例种的成员变量

                //(String) tag->Orientation source.getAttribute((String) tag)_>6
                if (declaredField.getName().equals("TAG_ORIENTATION") && tag instanceof String) {//判断变量是否以TAG开头，并且是String类型
                    source.setAttribute((String) tag, String.valueOf(0));//设置压缩图的EXIF信息
                    source.saveAttributes();//保存属性更改
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static int getExifOrientation(String filepath) {
        int degree = 0;
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(filepath);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        if (exif != null) {
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
            if (orientation != -1) {
                switch (orientation) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        degree = 90;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        degree = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        degree = 270;
                        break;
                }
            }
        }
        return degree;
    }

    /**
     * 将图片按照某个角度进行旋转
     *
     * @param bm     需要旋转的图片
     * @param degree 旋转角度
     * @return 旋转后的图片
     */
    public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
        Bitmap returnBm = null;
        //根据旋转角度，生成旋转矩阵
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        try {
            //将原始图片按照旋转矩阵进行旋转，并得到新的图片
            returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }
        if (returnBm == null) {
            returnBm = bm;
        }
        if (bm != returnBm) {
            bm.recycle();
        }
        return returnBm;
    }

    /**
     * 缩小图片
     *
     * @param bitmap
     * @param w
     * @param h
     * @return
     */
    public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        /**
         *
         */
        Matrix matrix = new Matrix();
        float scaleWidth = (float) w / width;
        float scaleHeight = (float) h / height;
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
                matrix, true);
        return newbmp;
    }

    /**
     * drawableToBitmap
     *
     * @param drawable
     * @return
     */
    public static Bitmap drawableToBitmap(Drawable drawable) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
                .getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888
                : Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);
        return bitmap;
    }

    /*
     * 得到一个圆角图片
     */
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {

        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectf = new RectF(rect);

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectf, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

    //
    public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
        final int reflectionGap = 4;
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        Matrix matrix = new Matrix();
        matrix.preScale(1, -1);

        Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2,
                width, height / 2, matrix, false);

        Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
                (height + height / 2), Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmapWithReflection);
        canvas.drawBitmap(bitmap, 0, 0, null);
        Paint deafalutPaint = new Paint();
        canvas.drawRect(0, height, width, height + reflectionGap, deafalutPaint);

        canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);

        Paint paint = new Paint();
        LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
                bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,
                0x00ffffff, TileMode.CLAMP);
        paint.setShader(shader);
        // Set the Transfer mode to be porter duff and destination in
        paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
        // Draw a rectangle using the paint with our linear gradient
        canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
                + reflectionGap, paint);

        return bitmapWithReflection;
    }

    /**
     * 将bitmap转ByteArray
     *
     * @param bmp
     * @param needRecycle
     * @return
     */
    public static byte[] bmpToByteArray(final Bitmap bmp,
                                        final boolean needRecycle) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bmp.compress(CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bmp.recycle();
        }
        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    //    /**
//     * 保存图片到SD卡上
//     *
//     * @param dw
//     * @param fileNa .png结尾
//     */
//    public static void saveDrawable(Drawable dw, String fileNa) {
//        try {
//            BitmapDrawable bd = (BitmapDrawable) dw;
//            Bitmap bm = bd.getBitmap();
//
//            File file = new File(Constant.ICASH_PATH + fileNa);
//            // 创建图片缓存文件夹
//            boolean sdCardExist = Environment.getExternalStorageState().equals(
//                    Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
//            if (sdCardExist) {
//                File maiduo = new File(Constant.ICASH_PATH);
//                // 如果文件夹不存在
//                if (!maiduo.exists()) {
//                    // 按照指定的路径创建文件夹
//                    maiduo.mkdir();
//                    // 如果文件夹不存在
//                }
//                // 检查图片是否存在
//                if (!file.exists()) {
//                    file.createNewFile();
//                }
//            }
//
//            BufferedOutputStream bos = new BufferedOutputStream(
//                    new FileOutputStream(file));
//            bm.compress(CompressFormat.JPEG, 100, bos);
//            bos.flush();
//            bos.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }

    /**
     * 获取缓存图片的文件夹
     *
     * @param context
     * @return
     */
    public static String getImageCacheDir(Context context) {
        File file = null;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            if (VersionUtils.INSTANCE.isAndroidQ()) {
                file = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            } else {
                file = context.getExternalCacheDir();
            }
        }

        if (file == null) {
            file = context.getCacheDir();
        }
        return file.getPath() + File.separator + "image_select";
    }
    /**
     * 是否是剪切返回的图片
     *
     * @param dir
     * @param path
     * @return
     */
    public static boolean isCutImage(String dir, String path) {
        if (!path.isEmpty()) {
            return path.startsWith(dir);
        }
        return false;
    }

}
