package com.kdanmobile.reader.thumb

import android.app.AlertDialog
import android.arch.lifecycle.ViewModel
import android.graphics.Bitmap
import com.kdanmobile.kmpdfkit.manager.KMPDFFactory
import com.kdanmobile.kmpdfkit.manager.controller.KMPDFDocumentController
import com.kdanmobile.kmpdfkit.pdfcommon.Bookmark
import com.kdanmobile.kmpdfkit.pdfcommon.TextWord
import com.kdanmobile.reader.R
import com.kdanmobile.reader.ReaderActivity
import com.kdanmobile.reader.screen.handler.*
import com.kdanmobile.reader.thumb.mode.Mode
import com.kdanmobile.reader.thumb.mode.NormalMode
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.io.File
import java.util.HashMap

class PdfThumbViewModel: ViewModel() {
    companion object {
        var tempKmpdfFactory: KMPDFFactory? = null
        var tempkmpdfDocumentController: KMPDFDocumentController? = null
    }

    private var pageCount = 0
    private var normalMode = NormalMode()
    private var disposable: Disposable? = null
    var kmpdfFactory: KMPDFFactory? = null
    var kmpdfDocumentController: KMPDFDocumentController? = null
    val mapSelect: MutableMap<Int, Boolean> = HashMap()
    var mode: Mode
    var isEditMode = false
    var isPdf = true

    init {
        kmpdfFactory = tempKmpdfFactory
        kmpdfDocumentController = tempkmpdfDocumentController
        tempKmpdfFactory = null
        tempkmpdfDocumentController = null
        pageCount = kmpdfDocumentController?.getDocumentPageCount(false) ?: 0
        for (i in 0 until pageCount){
            mapSelect[i] = false
        }
        mode = normalMode
    }

    val pdfInfoHandler = object : PdfInfoHandler {
        override fun getOpenPdfFilename(): String {
            return kmpdfFactory?.fileName ?: ""
        }

        override fun getPdfPageCount(): Int {
            return kmpdfDocumentController?.getDocumentPageCount(false) ?: 0
        }

        override fun getCurrentPage(): Int {
            return kmpdfDocumentController?.currentPageNum ?: 0
        }

        override fun setCurrentPage(page: Int): Boolean {
            return kmpdfDocumentController?.gotoPage(page) ?: false
        }

        override fun textLines(page: Int): Array<Array<TextWord>> {
            return kmpdfDocumentController?.textLines(page) ?: arrayOf()
        }
    }

    private val thumbnailHandler = object : ThumbnailHandler {
        override fun getPdfBitmap(position: Int, picWidth: Int, mode: Int, isDrawAnnot: Boolean): Bitmap {
            return kmpdfDocumentController?.covertPDFToBitmap(position, picWidth, mode, isDrawAnnot) ?: Bitmap.createBitmap(0, 0, Bitmap.Config.ARGB_4444)
        }
    }

    private val bookmarkHandler = object : BookmarkHandler {
        override fun getBookmarks(): Array<Bookmark> {
            return kmpdfDocumentController?.bookmarks ?: arrayOf()
        }
    }

    val operateHandler = object : OperateHandler {
        override fun deletePages(pages: IntArray): Boolean {
            return kmpdfDocumentController?.deletePages(pages) ?: false
        }
        override fun save(): Boolean {
            return kmpdfDocumentController?.save() ?: false
        }

        override fun reorderPage(fromPage: Int, toPage: Int): Boolean {
            return kmpdfDocumentController?.reorderPages(fromPage,toPage) ?: false
        }

        override fun splitPDFWithPages(path: String, selectPage: IntArray): Boolean {
            return kmpdfDocumentController?.splitPDFWithPages(path, selectPage) ?: false
        }
    }

    val passwordHandler = object : PasswordHandler {
        override fun isNeedPassword(): Boolean {
            return tempKmpdfFactory?.needPassWord() ?: false
        }
    }

    fun getAllPdfBitmap(): ArrayList<Bitmap>{
        var pdfBitmaps = ArrayList<Bitmap>()
        var pageCount: Int = kmpdfDocumentController?.getDocumentPageCount(true) ?: 0
        for(i in 0 until pageCount) {
            pdfBitmaps.add(thumbnailHandler.getPdfBitmap(i, 180, ThumbnailHandler.MODE_DAY, true))
        }
        return pdfBitmaps
    }

    fun isAllItemSelect(): Boolean{
        var count = 0
        for (i in 0 until pageCount){
            mapSelect[i]?.let {
                if(it) count ++
            }
        }
        return (count == pageCount)
    }

    fun setAllSelect(){
        for (i in 0 until pageCount) {
            mapSelect.let {
                it[i] = true
            }
        }
    }

    fun setAllUnSelect(){
        for (i in 0 until pageCount) {
            mapSelect.let {
                it[i] = false
            }
        }
    }

    fun getSelectPage(): ArrayList<Int>{
        var list = ArrayList<Int>()
        for (i in 0 until pageCount){
            mapSelect[i]?.let {
                if(it) list.add(i)
            }
        }
        return list
    }

    fun hasSelectItem(): Boolean{
        var count = 0
        for (i in 0 until pageCount){
            mapSelect[i]?.let {
                if(it) count ++
            }
        }
        return (count > 0)
    }

    fun hasBookMark() : Array<Boolean>{
        var hasBookMark = Array(pageCount) { false }
        for (bookmark in bookmarkHandler.getBookmarks()){
            hasBookMark[bookmark.pageNum] = true
        }
        return hasBookMark
    }

    fun pageRotate(runnable: Runnable){
        val isRotate = kmpdfDocumentController?.rotatePages(getSelectPage().toIntArray(), KMPDFDocumentController.RotationalDirection.CLOCK_WISE)
        when(isRotate){
            true -> {
                runnable.run()
            }
        }
    }

    fun pageDelete(runnable: Runnable){
        disposable = Observable.create<Boolean> { emitter ->
            val flag = operateHandler.deletePages(getSelectPage().toIntArray())
            emitter.onNext(flag)
            emitter.onComplete()
        }
                .subscribeOn(Schedulers.computation())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    when(it){
                        true -> {
                            runnable.run()
                        }
                    }
                }, {
                    it.printStackTrace()
                })
    }

    fun pageExtract(dst: File, runnableForSuc: Runnable, runnableForFail: Runnable) {
        disposable = Observable.create<Boolean> { emitter ->
            val b = operateHandler.splitPDFWithPages(dst.absolutePath, getSelectPage().toIntArray())
            emitter.onNext(b)
            emitter.onComplete()
            }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    when (it) {
                        true -> {
                            runnableForSuc.run()
                        }
                        false -> {
                            runnableForFail.run()
                        }
                    }
                }, {
                    it.printStackTrace()
                })
    }

    fun reorderPage(fromPage: Int, toPage: Int, runnable: Runnable){
        disposable = Observable.create<Boolean> { emitter ->
            val flag = operateHandler.reorderPage(fromPage, toPage)
            emitter.onNext(flag)
            emitter.onComplete()
        }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    when(it){
                        true -> {
                            runnable.run()
                        }
                    }
                }, {
                    it.printStackTrace()
                })
    }

    override fun onCleared() {
        if (null != disposable && !disposable!!.isDisposed) {
            disposable?.dispose()
            disposable = null
        }
        super.onCleared()
    }
}