package com.example.myimagepicker.luban

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.util.Log
import com.example.gengmei_flutter_plugin.ImagePlugin.repository.luban.Checker
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException

/**
 * Created by lsy
 * on 2019/3/29
 */
internal class Engine @Throws(IOException::class)
constructor(private val srcImg: InputStreamProvider, private val tagImgPath: String, private val focusAlpha: Boolean, val quality: Int) {
    private var srcWidth: Int = 0
    private var srcHeight: Int = 0

    init {

        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        options.inSampleSize = 1

        BitmapFactory.decodeStream(srcImg.open(), null, options)
        this.srcWidth = options.outWidth
        this.srcHeight = options.outHeight
    }

    private fun computeSize(): Int {
        srcWidth = if (srcWidth % 2 == 1) srcWidth + 1 else srcWidth
        srcHeight = if (srcHeight % 2 == 1) srcHeight + 1 else srcHeight

        val longSide = Math.max(srcWidth, srcHeight)
        val shortSide = Math.min(srcWidth, srcHeight)

        val scale = shortSide.toFloat() / longSide
        return if (scale <= 1 && scale > 0.5625) {
            if (longSide < 1664) {
                1
            } else if (longSide < 4990) {
                2
            } else if (longSide > 4990 && longSide < 10240) {
                4
            } else {
                if (longSide / 1280 == 0) 1 else longSide / 1280
            }
        } else if (scale <= 0.5625 && scale > 0.5) {
            if (longSide / 1280 == 0) 1 else longSide / 1280
        } else {
            Math.ceil(longSide / (1280.0 / scale)).toInt()
        }
    }

    private fun rotatingImage(bitmap: Bitmap?, angle: Int): Bitmap {
        val matrix = Matrix()

        matrix.postRotate(angle.toFloat())

        return Bitmap.createBitmap(bitmap!!, 0, 0, bitmap.width, bitmap.height, matrix, true)
    }

    @Throws(IOException::class)
    fun compress(): File {
        val options = BitmapFactory.Options()

        if (quality == 100) {
            options.inSampleSize = computeSize()
        } else {
            options.inSampleSize = (srcWidth / 240).toInt();
        }
//        Log.e("lsy","  SAMPLE SIZE ${options.inSampleSize}   ${srcWidth}")

        var tagBitmap = BitmapFactory.decodeStream(srcImg.open(), null, options)
        val stream = ByteArrayOutputStream()

        if (Checker.SINGLE.isJPG(srcImg.open())) {
            tagBitmap = rotatingImage(tagBitmap, Checker.SINGLE.getOrientation(srcImg.open()))
        }
//        val tagBitmap1 = imageScale(tagBitmap, 480);

        tagBitmap!!.compress(if (focusAlpha) Bitmap.CompressFormat.PNG else Bitmap.CompressFormat.JPEG, if (quality != 0) quality else 70, stream)
//        val width = tagBitmap.width
//        val height = tagBitmap.height
        tagBitmap.recycle()

//        val split = tagImgPath.split(".")
//        var before: String
//        var after: String
//        after = split[split.size - 1]
//        before = tagImgPath.replace("." + after, "")
        val file = File(tagImgPath)
        val fos = FileOutputStream(file)
        fos.write(stream.toByteArray())
        fos.flush()
        fos.close()
        stream.close()
        return file
    }

    private val matrix by lazy { Matrix() }

    private fun imageScale(bitmap: Bitmap, targetSize: Int): Bitmap {
        val scareSize = targetSize / bitmap.width.toFloat()
//        Log.e("lsy","  ${targetSize}  ${srcWidth}  ${srcWidth}")
        val width = bitmap.width * scareSize
        val height = bitmap.height * scareSize;
        matrix.reset();
        matrix.postScale(width.toFloat(), height.toFloat());
        val dstbmp = Bitmap.createBitmap(bitmap, 0, 0, width.toInt(), height.toInt(), matrix, true);
        return dstbmp
    }
}