package com.kdanmobile.reader.screen.adapter

import android.graphics.Bitmap
import android.support.v4.util.LruCache
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.RecyclerView.ViewHolder
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import com.kdanmobile.kmpdfkit.pdfcommon.Bookmark
import com.kdanmobile.reader.R
import com.kdanmobile.reader.screen.handler.ThumbnailHandler
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers

class BookmarkAdapter(private val thumbnailHandler: ThumbnailHandler, private var bookmarkItems: Array<Bookmark>): RecyclerView.Adapter<BookmarkAdapter.BookmarkViewHolder>() {

    companion object {
        val maxMemory = Runtime.getRuntime().maxMemory() / 16

        val mMemoryCache: LruCache<String, Bitmap> = object: LruCache<String, Bitmap>(maxMemory.toInt()) {
            override fun sizeOf(key: String, value: Bitmap): Int {
                return value.byteCount
            }
        }
    }

    fun setOutlineItems(bookmarkItems: Array<Bookmark>) {
        this.bookmarkItems = bookmarkItems
        notifyDataSetChanged()
    }

    override fun getItemCount(): Int {
        return bookmarkItems.size
    }

    fun getItem(position: Int): Bookmark? {
        return if (position >= 0 && position < bookmarkItems.size) bookmarkItems[position] else null
    }

    override fun onBindViewHolder(holder: BookmarkViewHolder, position: Int) {
        val bookmark = bookmarkItems[holder.adapterPosition]
        holder.msg.text = bookmark.title
        holder.page.text = (bookmark.pageNum + 1).toString()
        holder.loadThumbSync(bookmark.title + bookmark.pageNum + bookmark.createTime, bookmark.pageNum)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookmarkViewHolder {
        val view = View.inflate(parent.context, R.layout.item_bookmark, null)
        return BookmarkViewHolder(parent, view)
    }

    override fun onViewRecycled(holder: BookmarkViewHolder) {
        super.onViewRecycled(holder)
        holder.stopLoadThumbSync()
    }

    inner class BookmarkViewHolder(parent: ViewGroup, itemView: View): ViewHolder(itemView) {
        private val thumb: ImageView
        internal val page: TextView
        internal val msg: TextView
        private var disposable: Disposable? = null

        init {
            val idReaderBookmarkFl = itemView.findViewById<View>(R.id.tv_fragmentPdfReaderBookmarkLvItem_rl) as RelativeLayout
            val params = LinearLayout.LayoutParams((parent.measuredWidth - 20) / 2, (parent.measuredWidth - 20) * 9 / 14)
            params.setMargins(10, 5, 10, 5)
            idReaderBookmarkFl.layoutParams = params

            thumb = itemView.findViewById<View>(R.id.iv_fragmentPdfReaderBookmarkLvItem_) as ImageView
            page = itemView.findViewById<View>(R.id.tv_fragmentPdfReaderBookmarkLvItem_page) as TextView
            msg = itemView.findViewById<View>(R.id.tv_fragmentPdfReaderBookmarkLvItem_name) as TextView
        }

        internal fun loadThumbSync(filename: String, page: Int) {
            stopLoadThumbSync()

            disposable = Observable.create<Bitmap> { emitter ->
                val pageNameTag = filename + page
                val bitmap: Bitmap
                val value = mMemoryCache[pageNameTag]
                if (null != value) {
                    bitmap = value
                } else {
                    bitmap = thumbnailHandler.getPdfBitmap(page, 180, ThumbnailHandler.MODE_DAY, true)
                    mMemoryCache.put(pageNameTag, bitmap)
                }
                emitter.onNext(bitmap)
                emitter.onComplete()
            }
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe({
                        thumb.setImageBitmap(it)
                        thumb.invalidate()
                    }, {
                        it.printStackTrace()
                    })
        }

        internal fun stopLoadThumbSync() {
            if (null != disposable && !disposable!!.isDisposed) {
                disposable?.dispose()
                disposable = null
                thumb.setImageBitmap(null)
                thumb.invalidate()
            }
        }
    }
}
