package com.kdanmobile.reader

import android.annotation.SuppressLint
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.support.constraint.ConstraintLayout
import android.support.constraint.ConstraintSet
import android.support.v4.content.ContextCompat
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import android.util.DisplayMetrics
import android.view.Menu
import android.view.MenuItem
import android.view.MotionEvent
import android.view.View
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import com.kdanmobile.kmpdfkit.globaldata.KMPDFAnnotEditMode
import com.kdanmobile.kmpdfkit.pdfcommon.KMPDFReaderView
import com.kdanmobile.reader.Utils.applyConstraintSet
import com.kdanmobile.reader.annotationattribute.AnnotationAttribute
import com.kdanmobile.reader.annotationattribute.AnnotationColor
import com.kdanmobile.reader.annotationattribute.InkAttribute
import com.kdanmobile.reader.screen.ViewerSettingActivity
import com.kdanmobile.reader.screen.reader.mediabox.MediaBoxView
import com.kdanmobile.reader.screen.reader.mediabox.shape.ShapeTabView
import com.kdanmobile.reader.screen.reader.mediabox.signature.SignatureTabView
import com.kdanmobile.reader.screen.reader.mediabox.stamp.StampTabView
import com.kdanmobile.reader.screen.reader.mediabox.textbox.TextBoxTabView
import com.kdanmobile.reader.screen.view.BookmarkView
import com.kdanmobile.reader.screen.view.OutlineView
import com.kdanmobile.reader.screen.view.SearchView
import com.kdanmobile.reader.screen.view.ThumbnailView
import com.kdanmobile.reader.utils.AnimationUtil
import com.kdanmobile.reader.utils.DensityUtil
import com.kdanmobile.reader.view.AnnotationAttributeView
import com.kdanmobile.reader.view.AnnotationAttributeWindow
import kotlinx.android.synthetic.main.activity_reader.*

abstract class ReaderActivity : AppCompatActivity() {

    abstract fun onClickShare()
    abstract fun onClickTextReflow()
    abstract fun onClickFileInfo()
    abstract fun onClickPrint()
    abstract fun onClickUserGuide()

    companion object {
        const val KEY_FILE_ABSOLUTE = "file_absolutepath"
    }

    private lateinit var viewModel: ReaderViewModel

    // For hide/show toolbars
    private var isHideToolbar = false
    private lateinit var originConstraintSet: ConstraintSet

    private var menuItemBookmark: MenuItem? = null

    private val UI_ANIMATION_DURATION = 300L

    private var w_318: Int = 0
    private var w_240: Int = 0
    private var w_left: Int = 0

    private var isLeftToolbarOpen = false

    enum class LeftToolbarType {
        NONE, THUMBNAIL, BOOKMARK, OUTLINE, SEARCH
    }
    private var leftToolbarType = LeftToolbarType.NONE

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_reader)
        setSupportActionBar(toolbar_readerActivity)

        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        val width = Math.min(DensityUtil.getScreenWidthPx(baseContext), DensityUtil.getScreenHeightPx(baseContext))
        w_318 = 318 * width / 800
        w_240 = 240 * width / 800
        w_left = resources.getDimension(R.dimen.reader_left_right_toolbar_icon_width).toInt()

        cloneOriginConstraintSet()
        setupToolbar()
        setupLeftToolbar()
        setupRightSideToolbar()
        setupBottomToolbar()
        setupViewerEditView()

        val factory = ReaderViewModelFactory()
        viewModel = ViewModelProviders.of(this, factory).get(ReaderViewModel::class.java)
        viewModel.isOpenedFileLiveData.observe(this, Observer(this::onIsOpenedFileUpdate))
        viewModel.fileNameLiveData.observe(this, Observer { tv_readerActivity_title.text = it })
        viewModel.annotationModeLiveData.observe(this, Observer(this::onAnnotationModeUpdate))
        viewModel.annotationEitModeLiveData.observe(this, Observer(this::onAnnotationEditModeUpdate))
        viewModel.isCopyModeLiveData.observe(this, Observer (this::onIsCopyModeUpdate))
        viewModel.highLightAttributeLiveData.observe(this, Observer(this::onHighlightAttributeUpdate))
        viewModel.strikeAttributeLiveData.observe(this, Observer(this::onStrikeAttributeUpdate))
        viewModel.underLineAttributeLiveData.observe(this, Observer(this::onUnderlineAttributeUpdate))
        viewModel.inkAttributeLiveData.observe(this, Observer(this::onInkAttributeUpdate))
        viewModel.isOpenedFileLiveData.value?.also { isOpened ->
            if (isOpened) return@also
            val filePath = intent.getStringExtra(KEY_FILE_ABSOLUTE)
            val uri = Uri.parse(filePath)
            viewModel.openPdfFile(this, uri, intent.type)
        }
        setupRightToolbar()
        viewModel.pageIndexLiveData.observe(this, Observer(this::onPageIndexChanged))
        viewModel.isPageInBookmarksLiveData.observe(this, Observer(this::onIsPageInBookmarksChanged))
    }

    override fun onBackPressed() {
        when {
            viewerEditView.isShown -> viewerEditView.dismiss()
            else -> super.onBackPressed()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.reader_more, menu)
        menuItemBookmark = menu?.findItem(R.id.item_reader_bookmark)
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            menu?.findItem(R.id.item_reader_more_print)?.isVisible = false
        }
        // TODO: Check is pdf file or epub file, these action support only pdf file
        val isPdf = true
        if (!isPdf) {
            menu?.apply {
                findItem(R.id.item_reader_more_text_reflow)?.isVisible = false
                findItem(R.id.item_reader_more_file_info)?.isVisible = false
                findItem(R.id.item_reader_more_print)?.isVisible = false
            }
        }
        return true
    }

    @SuppressLint("RestrictedApi")
    override fun onPrepareOptionsPanel(view: View?, menu: Menu?): Boolean {
        /** Force show action menu item icon **/
        menu?.also {
            if ("MenuBuilder" != it::javaClass.get().simpleName) return@also
            try {
                val method = it.javaClass.getDeclaredMethod("setOptionalIconsVisible", java.lang.Boolean.TYPE)
                method.isAccessible = true
                method.invoke(it, true)
            } catch (e: Exception) {
                // Do nothing
            }
        }
        return super.onPrepareOptionsPanel(view, menu)
    }

    private fun cloneOriginConstraintSet() {
        if (!isBelowKitkat()) {
            originConstraintSet = ConstraintSet().apply {
                clone(constrainLayout_readerActivity_root)
            }
        }
    }

    private fun onIsCopyModeUpdate(isCopyMode: Boolean?) {
        if (isCopyMode == null) return
        when (isCopyMode) {
            true -> hideTopLeftBottomToolbars()
            false -> showAllToolbars()
        }
    }

    private fun onHighlightAttributeUpdate(annotationAttribute: AnnotationAttribute?) {
        if (annotationAttribute == null) return
        view_readerActivity_highLightStroke.setBackgroundColor(annotationAttribute.color)
    }

    private fun onStrikeAttributeUpdate(annotationAttribute: AnnotationAttribute?) {
        if (annotationAttribute == null) return
        view_readerActivity_strikeStroke.setBackgroundColor(annotationAttribute.color)
    }

    private fun onUnderlineAttributeUpdate(annotationAttribute: AnnotationAttribute?) {
        if (annotationAttribute == null) return
        view_readerActivity_underlineStroke.setBackgroundColor(annotationAttribute.color)
    }

    private fun onInkAttributeUpdate(inkAttribute: InkAttribute?) {
        if (inkAttribute == null) return
        val color = inkAttribute.color
        AnnotationColor.values().forEach {
            if (resources.getColor(it.colorResId) == color) {
                val drawableResId = when (it) {
                    AnnotationColor.Color1 -> R.drawable.ic_reader_right_toolbar_ink_color1
                    AnnotationColor.Color2 -> R.drawable.ic_reader_right_toolbar_ink_color2
                    AnnotationColor.Color3 -> R.drawable.ic_reader_right_toolbar_ink_color3
                    AnnotationColor.Color4 -> R.drawable.ic_reader_right_toolbar_ink_color4
                    AnnotationColor.Color5 -> R.drawable.ic_reader_right_toolbar_ink_color5
                    AnnotationColor.Color6 -> R.drawable.ic_reader_right_toolbar_ink_color6
                    AnnotationColor.Color7 -> R.drawable.ic_reader_right_toolbar_ink_color7
                    AnnotationColor.Color8 -> R.drawable.ic_reader_right_toolbar_ink_color8
                    AnnotationColor.Color9 -> R.drawable.ic_reader_right_toolbar_ink_color9
                    AnnotationColor.Color10 -> R.drawable.ic_reader_right_toolbar_ink_color10
                }
                iv_readerActivity_ink.setImageResource(drawableResId)
                return
            }
        }
    }

    private fun onAnnotationModeUpdate(annotationMode: ReaderViewModel.AnnotationMode?) {
        if (annotationMode == null) return
        val map = HashMap<ReaderViewModel.AnnotationMode, View>().apply {
            put(ReaderViewModel.AnnotationMode.Highlight, iv_readerActivity_highLight)
            put(ReaderViewModel.AnnotationMode.Strike, iv_readerActivity_strike)
            put(ReaderViewModel.AnnotationMode.Underline, iv_readerActivity_underline)
            put(ReaderViewModel.AnnotationMode.Ink, iv_readerActivity_ink)
        }
        map.forEach {
            if (it.key == annotationMode) {
                val color = resources.getColor(R.color.reader_right_toolbar_selected_bg)
                it.value.setBackgroundColor(color)
            } else {
                it.value.setBackgroundDrawable(null)
            }
        }
        when (annotationMode == ReaderViewModel.AnnotationMode.None) {
            true -> showAllToolbars()
            false -> hideTopLeftBottomToolbars()
        }
    }

    private fun onAnnotationEditModeUpdate(mode: KMPDFAnnotEditMode.Mode?) {
        println("onAnnotationEditModeUpdate KMPDFAnnotEditMode.Mode.$mode")
        when (mode) {
            KMPDFAnnotEditMode.Mode.NULL -> showAllToolbars()
            KMPDFAnnotEditMode.Mode.FREETEXT_MODIFY, KMPDFAnnotEditMode.Mode.STAMP_MODIFY, KMPDFAnnotEditMode.Mode.SIGN_MODIFY, KMPDFAnnotEditMode.Mode.SHAPE_MODIFY -> hideAllToolbars()
            else -> {}
        }
    }

    private fun onIsOpenedFileUpdate(isOpened: Boolean?) {
        if (isOpened == null) return
        val container = viewGroup_readerActivity_container
        container.removeAllViews()
        if (!isOpened) return
        val context = this
        val readerView = object : KMPDFReaderView(context) {
            @SuppressLint("ClickableViewAccessibility")
            override fun onTouchEvent(motionEvent: MotionEvent): Boolean {
                if (motionEvent.action == MotionEvent.ACTION_UP) {
                    if (viewModel.isCopyModeLiveData.value == true) {
                        if (viewModel.copySelection()) {
                            val context = this@ReaderActivity
                            Toast.makeText(context, R.string.reader_copy_text_success, Toast.LENGTH_SHORT).show()
                        }
                    }
                }
                return super.onTouchEvent(motionEvent)
            }

            override fun onTapMainDocArea() {
                super.onTapMainDocArea()
                when (isHideToolbar) {
                    true -> showAllToolbars()
                    false -> hideAllToolbars()
                }
                isHideToolbar = !isHideToolbar
            }

            override fun onMoveToChild(pageIndex: Int) {
                super.onMoveToChild(pageIndex)
                viewModel.setPageIndex(pageIndex)
                updateThumbnailViewSelectedPage()
            }

            override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean {
                val isEditMode = viewModel.annotationModeLiveData.value != ReaderViewModel.AnnotationMode.None
                val isCopyMode = viewModel.isCopyModeLiveData.value != false

                if (!isEditMode && !isCopyMode && !isHideToolbar) {
                    hideAllToolbars()
                    isHideToolbar = true
                }
                return super.onScroll(e1, e2, distanceX, distanceY)
            }
        }
        viewModel.setReaderView(readerView)
        viewModel.pdfInfoHandler.setCurrentPage(viewModel.pageIndexLiveData.value ?: 0)
        container.addView(readerView)
    }

    override fun onDestroy() {
        viewModel.saveModifyingAnnotationBeforeDestroy()
        super.onDestroy()
    }

    private fun onPageIndexChanged(pageIndex: Int?) {
        pageIndex?.let {
            viewModel.setBookmarkDisplay(pageIndex)
        }
    }

    private fun onIsPageInBookmarksChanged(isPageInBookmarks: Boolean?) {
        isPageInBookmarks?.let {
            if (it) {
                menuItemBookmark?.icon = ContextCompat.getDrawable(this, R.drawable.ic_bookmark_fill)
            } else {
                menuItemBookmark?.icon = ContextCompat.getDrawable(this, R.drawable.ic_bookmark_border)
            }
        }
    }

    private fun isBelowKitkat(): Boolean {
        return true
//        return Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT
    }

    private fun showAllToolbars() {
        if (isBelowKitkat()) {
            val duration = ((1 - toolbar_readerActivity.alpha) * UI_ANIMATION_DURATION).toLong()
            AnimationUtil.showViewFromTopToBottom(toolbar_readerActivity, duration)
            AnimationUtil.showViewFromBottomToTop(viewGroup_readerActivity_bottomToolbar, duration)
            AnimationUtil.showViewFromLeftToRight(viewGroup_readerActivity_leftToolbar, duration)
            AnimationUtil.showViewFromRightToLeft(viewGroup_readerActivity_rightToolbar, duration)
        } else {
            constrainLayout_readerActivity_root.applyConstraintSet(originConstraintSet, UI_ANIMATION_DURATION)
        }
    }

    private fun hideAllToolbars() {
        if (isBelowKitkat()) {
            val duration = (toolbar_readerActivity.alpha * UI_ANIMATION_DURATION).toLong()
            AnimationUtil.hideViewFromBottomToTop(toolbar_readerActivity, duration)
            AnimationUtil.hideViewFromTopToBottom(viewGroup_readerActivity_bottomToolbar, duration)
            AnimationUtil.hideViewFromRightToLeft(viewGroup_readerActivity_leftToolbar, duration)
            AnimationUtil.hideViewFromLeftToRight(viewGroup_readerActivity_rightToolbar, duration)
            hideSearchViewSoftKeyboard()
        } else {
            constrainLayout_readerActivity_root.applyConstraintSet(this, R.layout.activity_reader_hide_all, UI_ANIMATION_DURATION)
        }
    }

    private fun hideTopLeftBottomToolbars() {
        if (isBelowKitkat()) {
            val duration = (toolbar_readerActivity.alpha * UI_ANIMATION_DURATION).toLong()
            AnimationUtil.hideViewFromBottomToTop(toolbar_readerActivity, duration)
            AnimationUtil.hideViewFromTopToBottom(viewGroup_readerActivity_bottomToolbar, duration)
            AnimationUtil.hideViewFromRightToLeft(viewGroup_readerActivity_leftToolbar, duration)
            hideSearchViewSoftKeyboard()
        } else {
            constrainLayout_readerActivity_root.applyConstraintSet(this, R.layout.activity_reader_hide_top_left_bottom, UI_ANIMATION_DURATION)
        }
    }

    private fun updateThumbnailViewSelectedPage() {
        val view = linearLayout_readerActivity_leftToolbarContainer.getChildAt(0)
        if (view is ThumbnailView) {
            val currentPage = viewModel.pdfInfoHandler.getCurrentPage()
            view.onScrollToPosition(currentPage, true)
        }
    }

    private fun updateBookmarkView() {
        val view = linearLayout_readerActivity_leftToolbarContainer.getChildAt(0)
        if (view is BookmarkView) {
            view.updateBookmark()
        }
    }

    private fun setupToolbar() {
        toolbar_readerActivity.setOnMenuItemClickListener {
            when (it.itemId) {
                R.id.item_reader_bookmark -> onClickBookmark()
                R.id.item_reader_more_text_reflow -> onClickTextReflow()
                R.id.item_reader_more_file_info -> onClickFileInfo()
                R.id.item_reader_more_print -> onClickPrint()
                R.id.item_reader_more_user_guide -> onClickUserGuide()
            }
            return@setOnMenuItemClickListener true
        }
    }

    private fun onClickBookmark() {
        viewModel.isPageInBookmarksLiveData.value?.let {
            if (!it) {
                showAddBookmarkDialog()
            } else {
                showDeleteBookmarkDialog()
            }
        }
    }

    private fun showAddBookmarkDialog() {
        val alertDialogBuilder = AlertDialog.Builder(this)
        val editText = EditText(this)
        val layoutParams =
                LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)

        editText.layoutParams = layoutParams
        val defaultTitle = getString(R.string.dialogAddBookmark_page) + " " + (viewModel.pdfInfoHandler.getCurrentPage() + 1)
        editText.setText(defaultTitle, TextView.BufferType.EDITABLE)
        editText.setSelection(0, defaultTitle.length)

        alertDialogBuilder.setTitle(getString(R.string.reader_alert_dialog_title_add_bookmark))
        alertDialogBuilder.setView(editText)
        alertDialogBuilder.setPositiveButton(getString(R.string.reader_alert_dialog_button_confirm)) { dialog, which ->
            viewModel.addBookmark(editText.text.toString())
            updateBookmarkView()
        }
        alertDialogBuilder.setNegativeButton(getString(R.string.reader_alert_dialog_button_cancel)) { dialog, which ->
        }
        alertDialogBuilder.create().show()
        editText.requestFocus()
    }

    private fun getBookmarkTitle(page: Int): String {
        val bookmarks = viewModel.bookmarkHandler.getBookmarks()
        for (bookmark in bookmarks) {
            if (bookmark.pageNum == page) {
                return bookmark.title
            }
        }
        return ""
    }

    private fun showDeleteBookmarkDialog() {
        val alertDialogBuilder = AlertDialog.Builder(this)
        alertDialogBuilder.setTitle(getString(R.string.reader_alert_dialog_title_delete_bookmark))
        val bookmarkTitle = getBookmarkTitle(viewModel.pdfInfoHandler.getCurrentPage())
        val message = String.format(getString(R.string.reader_alert_dialog_message_delete_bookmark), bookmarkTitle)
        alertDialogBuilder.setMessage(message)
        alertDialogBuilder.setPositiveButton(getString(R.string.reader_alert_dialog_button_confirm)) { dialog, which ->
            viewModel.deleteBookmark()
            updateBookmarkView()
        }
        alertDialogBuilder.setNegativeButton(getString(R.string.reader_alert_dialog_button_cancel)) { dialog, which ->
        }
        alertDialogBuilder.create().show()
    }

    private fun hideSearchViewSoftKeyboard() {
        val view = linearLayout_readerActivity_leftToolbarContainer.getChildAt(0)
        if (view is SearchView) {
            view.hideSoftKeyboard()
        }
    }

    private fun setupLeftToolbar() {
        viewGroup_readerActivity_leftToolbar.setScroll(false)
        setLeftToolbarWidth(w_240)
        viewGroup_readerActivity_leftToolbar.smoothScrollTo(w_240, 0, 0)
        val child = layoutInflater.inflate(R.layout.view_thumbnail, null)
        linearLayout_readerActivity_leftToolbarContainer.addView(child)
        cloneOriginConstraintSet()
    }

    private fun setupRightSideToolbar() {
        iv_readerActivity_setting.setOnClickListener {
            startActivity(Intent(this, ViewerSettingActivity::class.java))
        }
    }

    private fun setupBottomToolbar() {
        ib_readerActivity_bottomToolbarMediaBox.setOnClickListener { viewerEditView.show() }
    }

    private fun setupViewerEditView() {
        viewerEditView.apply {
            onShowListener = Runnable { onMediaBoxShown() }
            onDismissListener = Runnable { onMediaBoxDismissed() }
            onClickAddButtonListener = object : MediaBoxView.OnClickAddButtonListener {
                override fun onClickTextBoxAddButton(textBoxTabView: TextBoxTabView) {
                    dismiss(false)
                    viewModel.setTextBoxAttribute(textBoxTabView.getTextBoxAttribute())
                }

                override fun onClickSignatureAddButton(signatureTabView: SignatureTabView) {
                    dismiss(false)
                    viewModel.setSignatureAttribute(signatureTabView.getSignatureAttribute())
                }

                override fun onClickStampAddButton(stampTabView: StampTabView) {
                    dismiss(false)
                    viewModel.setStampAttribute(stampTabView.getStampAttribute())
                }

                override fun onClickShapeAddButton(shapeTabView: ShapeTabView) {
                    dismiss(false)
                    viewModel.setShapeAttribute(shapeTabView.getShapeAttribute())
                }
            }
        }
    }

    private fun setupRightToolbar() {
        iv_readerActivity_highLight.apply {
            setOnClickListener { viewModel.onClickHighlightBtn() }
            setOnLongClickListener { btn ->
                viewModel.onLongClickHighlightBtn()
                val context = this@ReaderActivity
                AnnotationAttributeWindow(context, true).also { window ->
                    viewModel.highLightAttributeLiveData.value?.let { attr ->
                        window.annotationAttributeView.annotationAttribute = attr
                    }
                    window.annotationAttributeView.onChangeListener = object : AnnotationAttributeView.OnChangeListener {
                        override fun onChange(annotationAttributeView: AnnotationAttributeView) {
                            viewModel.setHighLightAttributes(annotationAttributeView.annotationAttribute)
                        }
                    }
                    val contentView = window.contentView.apply {
                        val w = Utils.makeDropDownMeasureSpec(window.width)
                        val y = Utils.makeDropDownMeasureSpec(window.height)
                        measure(w, y)
                    }
                    val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
                    val xOff = (-contentView.measuredWidth - space).toInt()
                    val yOff = -btn.height
                    window.showAsDropDown(btn, xOff, yOff)
                }
                return@setOnLongClickListener true
            }
        }
        iv_readerActivity_strike.apply {
            setOnClickListener { viewModel.onClickStrikeBtn() }
            setOnLongClickListener { btn ->
                viewModel.onLongClickStrikeBtn()
                val context = this@ReaderActivity
                AnnotationAttributeWindow(context, true).also { window ->
                    viewModel.strikeAttributeLiveData.value?.let { attr ->
                        window.annotationAttributeView.annotationAttribute = attr
                    }
                    window.annotationAttributeView.onChangeListener = object : AnnotationAttributeView.OnChangeListener {
                        override fun onChange(annotationAttributeView: AnnotationAttributeView) {
                            viewModel.setStrikeOutAttributes(annotationAttributeView.annotationAttribute)
                        }
                    }
                    val contentView = window.contentView.apply {
                        val w = Utils.makeDropDownMeasureSpec(window.width)
                        val y = Utils.makeDropDownMeasureSpec(window.height)
                        measure(w, y)
                    }
                    val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
                    val xOff = (-contentView.measuredWidth - space).toInt()
                    val yOff = -btn.height
                    window.showAsDropDown(btn, xOff, yOff)
                }
                return@setOnLongClickListener true
            }
        }
        iv_readerActivity_underline.apply {
            setOnClickListener { viewModel.onClickUnderlineBtn() }
            setOnLongClickListener { btn ->
                viewModel.onLongClickUnderlineBtn()
                val context = this@ReaderActivity
                AnnotationAttributeWindow(context, true).also { window ->
                    viewModel.underLineAttributeLiveData.value?.let { attr ->
                        window.annotationAttributeView.annotationAttribute = attr
                    }
                    window.annotationAttributeView.onChangeListener = object : AnnotationAttributeView.OnChangeListener {
                        override fun onChange(annotationAttributeView: AnnotationAttributeView) {
                            viewModel.setUnderLineAttributes(annotationAttributeView.annotationAttribute)
                        }
                    }
                    val contentView = window.contentView.apply {
                        val w = Utils.makeDropDownMeasureSpec(window.width)
                        val y = Utils.makeDropDownMeasureSpec(window.height)
                        measure(w, y)
                    }
                    val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
                    val xOff = (-contentView.measuredWidth - space).toInt()
                    val yOff = -btn.height
                    window.showAsDropDown(btn, xOff, yOff)
                }
                return@setOnLongClickListener true
            }
        }
        iv_readerActivity_ink.apply {
            setOnClickListener { viewModel.onClickInkBtn() }
            setOnLongClickListener { btn ->
                viewModel.onLongClickInkBtn()
                val context = this@ReaderActivity
                AnnotationAttributeWindow(context, false).also { window ->
                    viewModel.inkAttributeLiveData.value?.let { attr ->
                        window.annotationAttributeView.inkAttribute = attr
                    }
                    window.annotationAttributeView.onChangeListener = object : AnnotationAttributeView.OnChangeListener {
                        override fun onChange(annotationAttributeView: AnnotationAttributeView) {
                            viewModel.setInkAttributes(annotationAttributeView.inkAttribute)
                        }
                    }
                    val contentView = window.contentView.apply {
                        val w = Utils.makeDropDownMeasureSpec(window.width)
                        val y = Utils.makeDropDownMeasureSpec(window.height)
                        measure(w, y)
                    }
                    val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
                    val xOff = (-contentView.measuredWidth - space).toInt()
                    val yOff = -contentView.measuredHeight
                    window.showAsDropDown(btn, xOff, yOff)
                }
                return@setOnLongClickListener true
            }
        }
    }


    private fun setLeftToolbarWidth(width: Int) {
        var params = viewGroup_readerActivity_leftToolbar.layoutParams as ConstraintLayout.LayoutParams
        params.width = width + w_left
        params.height = 0
        viewGroup_readerActivity_leftToolbar.layoutParams = params

        params = linearLayout_readerActivity_leftToolbarContainer.layoutParams as ConstraintLayout.LayoutParams
        params.width = width
        linearLayout_readerActivity_leftToolbarContainer.layoutParams = params
    }

    private fun changeLeftToolbarType(type: LeftToolbarType) {
        iv_readerActivity_thumbnail.setImageResource(R.drawable.ic_left_toolbar_thumbnails)
        iv_readerActivity_bookmark.setImageResource(R.drawable.ic_left_toolbar_bookmarks)
        iv_readerActivity_outline.setImageResource(R.drawable.ic_left_toolbar_outline)
        iv_readerActivity_search.setImageResource(R.drawable.ic_left_toolbar_search)

        val width = when (type) {
            LeftToolbarType.THUMBNAIL -> w_240
            else -> w_318
        }
        setLeftToolbarWidth(width)

        isLeftToolbarOpen = (!isLeftToolbarOpen || leftToolbarType != type)
        if (isLeftToolbarOpen)
            viewGroup_readerActivity_leftToolbar.smoothScrollTo(0, 0, UI_ANIMATION_DURATION.toInt())
        else
            viewGroup_readerActivity_leftToolbar.smoothScrollTo(width, 0, UI_ANIMATION_DURATION.toInt())
        cloneOriginConstraintSet()
    }

    private fun onMediaBoxShown() {
        hideAllToolbars()
    }

    private fun onMediaBoxDismissed() {
        showAllToolbars()
    }

    private fun onThumbnailClick() {
        val type = LeftToolbarType.THUMBNAIL
        changeLeftToolbarType(type)
        if (isLeftToolbarOpen) {
            if (leftToolbarType != type) {
                linearLayout_readerActivity_leftToolbarContainer.removeAllViews()
                val thumbnailView = ThumbnailView(this)
                thumbnailView.setHandlers(viewModel.pdfInfoHandler, viewModel.thumbnailHandler)
                linearLayout_readerActivity_leftToolbarContainer.addView(thumbnailView)
            }
            iv_readerActivity_thumbnail.setImageResource(R.drawable.ic_left_toolbar_thumbnails_selected)
        } else {
            iv_readerActivity_thumbnail.setImageResource(R.drawable.ic_left_toolbar_thumbnails)
        }
        leftToolbarType = type
    }

    private fun onBookmarkClick() {
        val type = LeftToolbarType.BOOKMARK
        changeLeftToolbarType(type)
        if (isLeftToolbarOpen) {
            if (leftToolbarType != type) {
                linearLayout_readerActivity_leftToolbarContainer.removeAllViews()
                val bookmarkView = BookmarkView(this)
                bookmarkView.setHandlers(viewModel.pdfInfoHandler, viewModel.thumbnailHandler, viewModel.bookmarkHandler)
                linearLayout_readerActivity_leftToolbarContainer.addView(bookmarkView)
            }
            iv_readerActivity_bookmark.setImageResource(R.drawable.ic_left_toolbar_bookmarks_selected)
        } else {
            iv_readerActivity_bookmark.setImageResource(R.drawable.ic_left_toolbar_bookmarks)
        }
        leftToolbarType = type
    }

    private fun onOutlineClick() {
        val type = LeftToolbarType.OUTLINE
        changeLeftToolbarType(type)
        if (isLeftToolbarOpen) {
            if (leftToolbarType != type) {
                linearLayout_readerActivity_leftToolbarContainer.removeAllViews()
                val outlineView = OutlineView(this)
                outlineView.setHandlers(viewModel.pdfInfoHandler, viewModel.outlineHandler)
                linearLayout_readerActivity_leftToolbarContainer.addView(outlineView)
            }
            iv_readerActivity_outline.setImageResource(R.drawable.ic_left_toolbar_outline_selected)
        } else {
            iv_readerActivity_outline.setImageResource(R.drawable.ic_left_toolbar_outline)
        }
        leftToolbarType = type
    }

    private fun onSearchClick() {
        val type = LeftToolbarType.SEARCH
        changeLeftToolbarType(type)
        if (isLeftToolbarOpen) {
            if (leftToolbarType != type) {
                linearLayout_readerActivity_leftToolbarContainer.removeAllViews()
                val searchView = SearchView(this)
                searchView.setHandlers(viewModel.pdfInfoHandler, viewModel.searchHandler)
                linearLayout_readerActivity_leftToolbarContainer.addView(searchView)
            }
            iv_readerActivity_search.setImageResource(R.drawable.ic_left_toolbar_search_selected)
        } else {
            iv_readerActivity_search.setImageResource(R.drawable.ic_left_toolbar_search)
            hideSearchViewSoftKeyboard()
        }
        leftToolbarType = type
    }

    fun onClick(view: View) {
        when (view.id) {
            R.id.iv_readerActivity_thumbnail -> {
                onThumbnailClick()
            }
            R.id.iv_readerActivity_bookmark -> {
                onBookmarkClick()
            }
            R.id.iv_readerActivity_outline -> {
                onOutlineClick()
            }
            R.id.iv_readerActivity_search -> {
                onSearchClick()
            }
            else -> {

            }
        }
    }
}
