package com.za.common.util

import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.VectorDrawable
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.text.format.DateUtils
import android.view.View
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.core.graphics.createBitmap
import com.amap.api.maps.model.BitmapDescriptor
import com.amap.api.maps.model.BitmapDescriptorFactory
import com.za.common.log.LogUtil
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

/**
 * 图片工具类
 *
 * @author
 */
object ImageUtil {
	/**
	 * 设置水印图片在左上角
	 *
	 * @param context
	 * @param src
	 * @param watermark
	 * @param paddingLeft
	 * @param paddingTop
	 * @return
	 */
	fun createWaterMaskLeftTop(context : Context,
		src : Bitmap?,
		watermark : Bitmap,
		paddingLeft : Int,
		paddingTop : Int) : Bitmap? {
		return createWaterMaskBitmap(src,
			watermark,
			paddingLeft,
			dp2px(context, paddingTop.toFloat()))
	}

	private fun createWaterMaskBitmap(src : Bitmap?,
		watermark : Bitmap,
		paddingLeft : Int,
		paddingTop : Int) : Bitmap? {
		if (src == null) {
			return null
		}
		val width = src.width
		val height = src.height //创建一个bitmap
		val newb = Bitmap.createBitmap(width,
			height,
			Bitmap.Config.ARGB_8888) // 创建一个新的和SRC长度宽度一样的位图 //将该图片作为画布
		val canvas = Canvas(newb) //在画布 0，0坐标上开始绘制原始图片
		canvas.drawBitmap(src, 0f, 0f, null) //在画布上绘制水印图片
		canvas.drawBitmap(watermark, paddingLeft.toFloat(), paddingTop.toFloat(), null) // 保存
		canvas.save() // 存储
		canvas.restore()
		return newb
	}

	/**
	 * 设置水印图片在右下角
	 *
	 * @param context
	 * @param src
	 * @param watermark
	 * @param paddingRight
	 * @param paddingBottom
	 * @return
	 */
	fun createWaterMaskRightBottom(context : Context?,
		src : Bitmap,
		watermark : Bitmap,
		paddingRight : Int,
		paddingBottom : Int) : Bitmap? {
		return createWaterMaskBitmap(src,
			watermark,
			src.width - watermark.width - paddingRight,
			src.height - watermark.height - paddingBottom)
	}

	/**
	 * 设置水印图片到右上角
	 *
	 * @param context
	 * @param src
	 * @param watermark
	 * @param paddingRight
	 * @param paddingTop
	 * @return
	 */
	fun createWaterMaskRightTop(context : Context?,
		src : Bitmap,
		watermark : Bitmap,
		paddingRight : Int,
		paddingTop : Int) : Bitmap? {
		return createWaterMaskBitmap(src,
			watermark,
			src.width - watermark.width - paddingRight,
			paddingTop)
	}

	/**
	 * 设置水印图片到左下角
	 *
	 * @param context
	 * @param src
	 * @param watermark
	 * @param paddingLeft
	 * @param paddingBottom
	 * @return
	 */
	fun createWaterMaskLeftBottom(context : Context?,
		src : Bitmap,
		watermark : Bitmap,
		paddingLeft : Int,
		paddingBottom : Int) : Bitmap? {
		return createWaterMaskBitmap(src,
			watermark,
			paddingLeft,
			src.height - watermark.height - paddingBottom)
	}

	/**
	 * 设置水印图片到中间
	 *
	 * @param src
	 * @param watermark
	 * @return
	 */
	fun createWaterMaskCenter(src : Bitmap, watermark : Bitmap) : Bitmap? {
		return createWaterMaskBitmap(src,
			watermark,
			(src.width - watermark.width) / 2,
			(src.height - watermark.height) / 2)
	}

	/**
	 * 给图片添加文字到左上角
	 *
	 * @param context
	 * @param bitmap
	 * @param text
	 * @return
	 */
	fun drawTextToLeftTop(context : Context,
		bitmap : Bitmap,
		text : String,
		size : Int,
		color : Int,
		paddingLeft : Int,
		paddingTop : Int) : Bitmap {
		val paint = Paint(Paint.ANTI_ALIAS_FLAG)
		paint.color = color
		paint.textSize = size.toFloat()
		paint.setTypeface(Typeface.createFromAsset(context.assets, "fonts/song.ttf"))
		paint.isFakeBoldText = true
		val bounds = Rect()
		paint.getTextBounds(text, 0, text.length, bounds)
		return drawTextToBitmap(context,
			bitmap,
			text,
			paint,
			bounds,
			paddingLeft,
			paddingTop + bounds.height())
	}

	/**
	 * 绘制文字到右下角
	 *
	 * @param context
	 * @param bitmap
	 * @param text
	 * @param size
	 * @param color
	 * @return
	 */
	fun drawTextToRightBottom(context : Context,
		bitmap : Bitmap,
		text : String,
		size : Int,
		color : Int,
		paddingRight : Int,
		paddingBottom : Int) : Bitmap {
		val paint = Paint(Paint.ANTI_ALIAS_FLAG)
		paint.color = color
		paint.textSize = size.toFloat()
		paint.setTypeface(Typeface.createFromAsset(context.assets, "fonts/song.ttf"))
		paint.isFakeBoldText = true
		val bounds = Rect()
		paint.getTextBounds(text, 0, text.length, bounds)
		return drawTextToBitmap(context,
			bitmap,
			text,
			paint,
			bounds,
			bitmap.width - bounds.width() - paddingRight,
			bitmap.height - paddingBottom)
	}

	/**
	 * 绘制文字到右上方
	 *
	 * @param context
	 * @param bitmap
	 * @param text
	 * @param size
	 * @param color
	 * @param paddingRight
	 * @param paddingTop
	 * @return
	 */
	fun drawTextToRightTop(context : Context,
		bitmap : Bitmap,
		text : String,
		size : Int,
		color : Int,
		paddingRight : Int,
		paddingTop : Int) : Bitmap {
		val paint = Paint(Paint.ANTI_ALIAS_FLAG)
		paint.color = color
		paint.textSize = size.toFloat()
		paint.setTypeface(Typeface.createFromAsset(context.assets, "fonts/song.ttf"))
		paint.isFakeBoldText = true
		val bounds = Rect()
		paint.getTextBounds(text, 0, text.length, bounds)
		return drawTextToBitmap(context,
			bitmap,
			text,
			paint,
			bounds,
			bitmap.width - bounds.width() - paddingRight,
			paddingTop + bounds.height())
	}

	/**
	 * 绘制文字到左下方
	 *
	 * @param context
	 * @param bitmap
	 * @param text
	 * @param size
	 * @param color
	 * @param paddingLeft
	 * @param paddingBottom
	 * @return
	 */
	fun drawTextToLeftBottom(context : Context,
		bitmap : Bitmap,
		text : String,
		size : Int,
		color : Int,
		paddingLeft : Int,
		paddingBottom : Int) : Bitmap {
		val paint = Paint(Paint.ANTI_ALIAS_FLAG)
		paint.color = color
		paint.textSize = size.toFloat()
		paint.setTypeface(Typeface.createFromAsset(context.assets, "fonts/song.ttf"))
		paint.isFakeBoldText = true
		val bounds = Rect()
		paint.getTextBounds(text, 0, text.length, bounds)
		return drawTextToBitmap(context,
			bitmap,
			text,
			paint,
			bounds,
			paddingLeft,
			bitmap.height - paddingBottom)
	}

	/**
	 * 绘制文字到中间
	 *
	 * @param context
	 * @param bitmap
	 * @param text
	 * @param size
	 * @param color
	 * @return
	 */
	fun drawTextToCenter(context : Context,
		bitmap : Bitmap,
		text : String,
		size : Int,
		color : Int) : Bitmap {
		val paint = Paint(Paint.ANTI_ALIAS_FLAG)
		paint.color = color
		paint.textSize = size.toFloat()
		paint.setTypeface(Typeface.createFromAsset(context.assets, "fonts/song.ttf"))
		paint.isFakeBoldText = true
		val bounds = Rect()
		paint.getTextBounds(text, 0, text.length, bounds)
		return drawTextToBitmap(context,
			bitmap,
			text,
			paint,
			bounds,
			(bitmap.width - bounds.width()) / 2,
			(bitmap.height + bounds.height()) / 2)
	}

	//图片上绘制文字
	private fun drawTextToBitmap(context : Context,
		myBitmap : Bitmap,
		text : String,
		paint : Paint,
		bounds : Rect,
		paddingLeft : Int,
		paddingTop : Int) : Bitmap {

		val bitmapConfig = myBitmap.config
		paint.isDither = true // 获取跟清晰的图像采样
		paint.isFilterBitmap = true // 过滤一些
		val bitmap = myBitmap.copy(bitmapConfig !!, true)
		val canvas = Canvas(bitmap)
		canvas.drawText(text, paddingLeft.toFloat(), paddingTop.toFloat(), paint)
		return bitmap
	}

	/**
	 * 缩放图片
	 *
	 * @param src
	 * @param w
	 * @param h
	 * @return
	 */
	fun scaleWithWH(src : Bitmap?, w : Double, h : Double) : Bitmap? {
		if (w == 0.0 || h == 0.0 || src == null) {
			return src
		} else { // 记录src的宽高
			val width = src.width
			val height = src.height // 创建一个matrix容器
			val matrix = Matrix() // 计算缩放比例
			val scaleWidth = (w / width).toFloat()
			val scaleHeight = (h / height).toFloat() // 开始缩放
			matrix.postScale(scaleWidth, scaleHeight) // 创建缩放后的图片
			return Bitmap.createBitmap(src, 0, 0, width, height, matrix, true)
		}
	}

	/**
	 * dip转pix
	 *
	 * @param context
	 * @param dp
	 * @return
	 */
	private fun dp2px(context : Context, dp : Float) : Int {
		val scale = context.resources.displayMetrics.density
		return (dp * scale + 0.5f).toInt()
	}


	// view转bitmap
	fun createBitmapFromView(view : View) : Bitmap? { //是ImageView直接获取
		if (view is ImageView) {
			val drawable = view.drawable
			if (drawable is BitmapDrawable) {
				return drawable.bitmap
			}
		}
		view.clearFocus()
		val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
		val canvas = Canvas(bitmap)
		view.draw(canvas)
		canvas.setBitmap(null)
		return bitmap
	}

	// 保存图片到相册
	fun saveImage(context : Context, bitmap : Bitmap?) {
		if (bitmap == null) {
			return
		}
		val isSaveSuccess = if (Build.VERSION.SDK_INT < 29) {
			saveImageToGallery(context, bitmap)
		} else {
			saveImageToGallery1(context, bitmap)
		}
		if (isSaveSuccess) {
			LogUtil.print("照片保存到相册成功", "success")
		} else {
			LogUtil.print("照片保存到相册失败", "failed")
		}
	}

	/**
	 * android 10 以下版本
	 */
	private fun saveImageToGallery(context : Context, image : Bitmap) : Boolean { // 首先保存图片
		val storePath =
			Environment.getExternalStorageDirectory().absolutePath + File.separator + "中道救援"

		val appDir = File(storePath)
		if (! appDir.exists()) {
			appDir.mkdir()
		}
		val fileName = System.currentTimeMillis().toString() + ".jpg"
		val file = File(appDir, fileName)
		try {
			val fos = FileOutputStream(file) // 通过io流的方式来压缩保存图片
			val isSuccess = image.compress(Bitmap.CompressFormat.JPEG, 60, fos)
			fos.flush()
			fos.close()

			// 保存图片后发送广播通知更新数据库
			val uri = Uri.fromFile(file)
			context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri))
			return isSuccess
		} catch (e : IOException) {
			e.printStackTrace()
		}
		return false
	}

	/**
	 * android 10 以上版本
	 */
	private fun saveImageToGallery1(context : Context, image : Bitmap) : Boolean {
		val mImageTime = System.currentTimeMillis()
		val imageDate =
			SimpleDateFormat("yyyyMMdd-HHmmss", Locale.getDefault()).format(Date(mImageTime))
		val SCREENSHOT_FILE_NAME_TEMPLATE = "zd_%s.png" //图片名称，以"zd"+时间戳命名
		val mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate)

		val values = ContentValues()
		values.put(MediaStore.MediaColumns.RELATIVE_PATH,
			Environment.DIRECTORY_PICTURES + File.separator + "中道救援") //Environment.DIRECTORY_SCREENSHOTS:截图,图库中显示的文件夹名
		values.put(MediaStore.MediaColumns.DISPLAY_NAME, mImageFileName)
		values.put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
		values.put(MediaStore.MediaColumns.DATE_ADDED, mImageTime / 1000)
		values.put(MediaStore.MediaColumns.DATE_MODIFIED, mImageTime / 1000)
		values.put(MediaStore.MediaColumns.DATE_EXPIRES,
			(mImageTime + DateUtils.DAY_IN_MILLIS) / 1000)
		values.put(MediaStore.MediaColumns.IS_PENDING, 1)

		val resolver = context.contentResolver
		val uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
		try { // First, write the actual data for our screenshot
			resolver.openOutputStream(uri !!).use { out ->
				if (! image.compress(Bitmap.CompressFormat.PNG, 100, out !!)) {
					return false
				}
			} // Everything went well above, publish it!
			values.clear()
			values.put(MediaStore.MediaColumns.IS_PENDING, 0)
			values.putNull(MediaStore.MediaColumns.DATE_EXPIRES)
			resolver.update(uri, values, null, null)
		} catch (e : IOException) {
			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
				resolver.delete(uri !!, null)
			}
			return false
		}
		return true
	}


	fun vectorToBitmap(context : Context, vectorResId : Int) : BitmapDescriptor {
		val vectorDrawable = ContextCompat.getDrawable(context, vectorResId) as VectorDrawable
		val bitmap = createBitmap(vectorDrawable.intrinsicWidth, vectorDrawable.intrinsicHeight)
		val canvas = Canvas(bitmap)
		vectorDrawable.setBounds(0, 0, canvas.width, canvas.height)
		vectorDrawable.draw(canvas)
		return BitmapDescriptorFactory.fromBitmap(bitmap)
	}
}

