package com.app.wave.keyboard.utils

import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.StateListDrawable
import android.util.Xml
import androidx.core.content.ContextCompat
import com.app.wave.keyboard.App
import com.app.wave.keyboard.R
import com.app.wave.keyboard.kbhelper.RespConfig
import org.xmlpull.v1.XmlPullParser
import java.io.File
import java.io.StringReader
import kotlin.collections.iterator

class KBManager(var context: Context) {


    private var textSize = 13f

    var functionDraw: Drawable =
        getDefaultDrawList(R.drawable.item_key_outline, R.drawable.item_key_pressed)
    var generalDraw: Drawable =
        getDefaultDrawList(R.drawable.item_key_outline, R.drawable.item_key_pressed)

    var toDraw: Drawable = getDefaultDrawList(R.drawable.item_key_outline, R.drawable.item_key_pressed)
    var spaceDraw: Drawable = getDefaultDrawList(R.drawable.item_key_outline, R.drawable.item_key_pressed)

    var switchDraw: Drawable? = null
    var deleteDraw: Drawable? = null
    var backDraw: Drawable? = null
    var searchDraw: Drawable? = null

    var shiftDraw: Drawable? = null
    var shiftLockDraw: Drawable? = null

    var keyTextColor: Int = ContextCompat.getColor(context, R.color.black)
    var keyTextColorFunction: Int = ContextCompat.getColor(context, R.color.black)




    fun getConfig(): RespConfig? {
        val skinPath = SavePresentKB.getSkinPath()
        val configFilePath = skinPath + "assets/keyboard.conf"
        val file = File(configFilePath)
        return if (file.exists()) {
            ConfigFile.initConfig(configFilePath)
        } else {
            null
        }
    }

    fun getConfigBg(name: String): Drawable? {
        SavePresentKB.getSkinPath()?.let { resPath ->
            val pPath = "${resPath}res/drawable-xhdpi-v4/"

            return getDrawList(
                pPath + name,
                pPath + name
            )
        }
        return null
    }

    fun updateSkinConfig() {
        SavePresentKB.getSkinPath()?.let { resPath ->
            val pPath = "${resPath}res/drawable-xhdpi-v4/"
            pPath.let {
                readColors(resPath) {
                    for ((name, value) in it) {
                        if (name == MyKeyName.keyTextColorName) {
                            keyTextColor = value
                        }
                        if (name == MyKeyName.keyTextColorFunctionName) {
                            keyTextColorFunction = value
                        }
                    }

                }
                functionDraw = getDrawList(
                    it + MyKeyName.functionNormalName,
                    it + MyKeyName.functionPressName
                )
                generalDraw = getDrawList(it + MyKeyName.normalName, it + MyKeyName.pressName)
                toDraw = getDrawList(it + MyKeyName.toNormalName, it + MyKeyName.toPressName)
                spaceDraw =
                    getDrawList(it + MyKeyName.spaceNormalName, it + MyKeyName.spacePressName)
                switchDraw =
                    getDrawList(it + MyKeyName.imeSwitchName, it + MyKeyName.imeSwitchName)
                deleteDraw = getDrawList(
                    it + MyKeyName.deleteNormalName,
                    it + MyKeyName.deletePressName
                )
                backDraw = getDrawList(it + MyKeyName.backName, it + MyKeyName.backName)
                searchDraw = getDrawList(it + MyKeyName.searchName, it + MyKeyName.searchName)
                shiftDraw = getDrawList(
                    it + MyKeyName.shiftNormalName,
                    it + MyKeyName.shiftNormalName
                )
                shiftLockDraw =
                    getDrawList(it + MyKeyName.shiftLockName, it + MyKeyName.shiftLockName)
            }

        }
    }


    private fun getDefaultDrawList(normalDrawId: Int, pressDrawId: Int): StateListDrawable {
        val normalDraw = ContextCompat.getDrawable(App.Companion.appInstance, normalDrawId)
        val pressDraw = ContextCompat.getDrawable(App.Companion.appInstance, pressDrawId)
        val stateListDrawable = StateListDrawable().apply {
            addState(
                intArrayOf(android.R.attr.state_pressed),
                pressDraw
            )
            addState(intArrayOf(), normalDraw)
        }

        return stateListDrawable


    }


    private fun getDrawList(normalPath: String, pressPath: String): StateListDrawable {
        val pressDraw = BitmapFactory.decodeFile(pressPath)
        val normalDraw = BitmapFactory.decodeFile(normalPath)
        val stateListDrawable = StateListDrawable().apply {
            addState(
                intArrayOf(android.R.attr.state_pressed),
                BitmapDrawable(context.resources, pressDraw)
            )
            addState(intArrayOf(), BitmapDrawable(context.resources, normalDraw))
        }

        return stateListDrawable


    }

    private fun readColors(resPath: String, callBack: (Map<String, Int>) -> Unit) {
        val resMaps = mutableMapOf<String, Int>()

        val pPath = "${resPath}res/colors.xml"
        val file = File(pPath)
        if (file.exists()) {
            val xmlPullParser = Xml.newPullParser().apply {
                setInput(StringReader(file.readText()))
                setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)

            }
            var curType = xmlPullParser.eventType
            while (curType != XmlPullParser.END_DOCUMENT) {
                val b = curType == XmlPullParser.START_TAG
                val b1 = xmlPullParser.name == "color"
                val b2 = xmlPullParser.name == "item"
                if (b && (b1 || b2)) {
                    val attributeName = xmlPullParser.getAttributeValue(null, "name")
                    val nextTextValue = xmlPullParser.nextText()
                    val b3 = attributeName == MyKeyName.keyTextColorName
                    val b4 = attributeName == MyKeyName.keyTextColorFunctionName
                    if (b3 || b4) {
                        resMaps[attributeName] = Color.parseColor(nextTextValue)
                    }
                }
                curType = xmlPullParser.next()
            }

        }

        callBack.invoke(resMaps)


    }


}