package oppen.filters.ui.filter_picker

/*

    Lätt - fast image filtering app for Android
    Copyright (C) 2020  Öppenlab

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

 */

import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.collection.LruCache
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.filter_thumbnail.view.*
import oppen.filters.R
import oppen.filters.io.ImageIO
import oppen.filters.io.PhotoProcessor

class LazyLUTAdapter (
    context: Context,
    sourceUri: Uri,
    private val luts: MutableList<Pair<String, Int>>,
    private val onLongClick: (lut: Pair<String, Int>) -> Unit,
    private val onClick: (lut: Pair<String, Int>, direction: Int, count: Int) -> Unit): RecyclerView.Adapter<LazyLUTAdapter.FilterViewHolder>() {

    class FilterViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

    private val cacheSize = 6 * 1024 * 1024//6MiB
    private val bitmapCache = LruCache<String, Bitmap>(cacheSize)

    private val lutProcessor: PhotoProcessor =
        PhotoProcessor(context)

    private val handler = Handler(Looper.getMainLooper())

    private var sourceThumbnail: Bitmap? = null
    private var lastSelected = 0

    init {
        val imageIO = ImageIO(context)
        imageIO.get(sourceUri){
            sourceThumbnail = it
        }
    }

    fun removeLut(lut: Int){
        val removed = luts.find { it.second == lut }
        luts.remove(removed)
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FilterViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.filter_thumbnail, null)
        return FilterViewHolder(view)
    }

    override fun getItemCount(): Int = luts.size

    override fun onBindViewHolder(holder: FilterViewHolder, position: Int) {
        val lut = luts[position]


        val cachedBitmap = bitmapCache.get(lut.first)
        if(cachedBitmap != null){
            holder.itemView.thumbnail_image.setImageBitmap(cachedBitmap)
        }else{
            createThumbnail(lut){
                handler.post {
                    holder.itemView.thumbnail_image.setImageBitmap(bitmapCache.get(lut.first))
                }
            }
        }

        holder.itemView.thumbnail_label.text = lut.first

        holder.itemView.thumbnail_image.setOnLongClickListener {
            onLongClick.invoke(luts[holder.adapterPosition])
            true
        }

        holder.itemView.thumbnail_image.setOnClickListener {
            val holderPosition = holder.adapterPosition
            var direction = 0
            when (holderPosition) {
                lastSelected + 1 -> {
                    direction = 1
                }
                lastSelected -1 -> {
                    direction = -1
                }
            }
            lastSelected = holderPosition
            onClick.invoke(luts[holderPosition], direction, itemCount)
        }
    }

    private fun createThumbnail(lut: Pair<String, Int>, onCreated: () -> Unit){
        val resId = lut.second

        if(sourceThumbnail != null) {
            lutProcessor.filter(sourceThumbnail!!, resId, PhotoProcessor.LUT_ONLY) {
                bitmapCache.put(lut.first, it!!)
                onCreated.invoke()
            }
        }else{
            Log.e("LazyLUTAdapter", "createThumbnail() sourceThumbnail is NULL ")
            onCreated.invoke()
        }
    }
}