package com.simplemobiletools.commons.views

import android.content.Context
import android.graphics.Point
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.LinearLayout
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.extensions.baseConfig
import com.simplemobiletools.commons.extensions.getBasePath
import com.simplemobiletools.commons.extensions.humanizePath
import com.simplemobiletools.commons.models.FileDirItem
import kotlinx.android.synthetic.main.breadcrumb_item.view.*

class Breadcrumbs(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs), View.OnClickListener {
    private var mDeviceWidth: Int = 0

    private var mInflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
    private var mListener: BreadcrumbsListener? = null
    private var mTextColor = 0

    init {
        mDeviceWidth = getDeviceWidth()
        mTextColor = context.baseConfig.textColor
    }

    fun setListener(listener: BreadcrumbsListener) {
        mListener = listener
    }

    fun setTextColor(color: Int) {
        mTextColor = color
    }

    fun getDeviceWidth(): Int {
        val display = (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
        val deviceDisplay = Point()
        display.getSize(deviceDisplay)
        return deviceDisplay.x
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        val childRight = measuredWidth - paddingRight
        val childBottom = measuredHeight - paddingBottom
        val childHeight = childBottom - paddingTop

        val usableWidth = mDeviceWidth - paddingLeft - paddingRight
        var maxHeight = 0
        var curWidth: Int
        var curHeight: Int
        var curLeft = paddingLeft
        var curTop = paddingTop

        val cnt = childCount
        for (i in 0..cnt - 1) {
            val child = getChildAt(i)

            child.measure(MeasureSpec.makeMeasureSpec(usableWidth, MeasureSpec.AT_MOST),
                    MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST))
            curWidth = child.measuredWidth
            curHeight = child.measuredHeight

            if (curLeft + curWidth >= childRight) {
                curLeft = paddingLeft
                curTop += maxHeight
                maxHeight = 0
            }

            child.layout(curLeft, curTop, curLeft + curWidth, curTop + curHeight)
            if (maxHeight < curHeight)
                maxHeight = curHeight

            curLeft += curWidth
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val usableWidth = mDeviceWidth - paddingLeft - paddingRight
        var width = 0
        var rowHeight = 0
        var lines = 1

        val cnt = childCount
        for (i in 0..cnt - 1) {
            val child = getChildAt(i)
            measureChild(child, widthMeasureSpec, heightMeasureSpec)
            width += child.measuredWidth
            rowHeight = child.measuredHeight

            if (width / usableWidth > 0) {
                lines++
                width = child.measuredWidth
            }
        }

        val parentWidth = MeasureSpec.getSize(widthMeasureSpec)
        val calculatedHeight = paddingTop + paddingBottom + rowHeight * lines
        setMeasuredDimension(parentWidth, calculatedHeight)
    }

    fun setBreadcrumb(fullPath: String) {
        val basePath = fullPath.getBasePath(context)
        var currPath = basePath
        val tempPath = context.humanizePath(fullPath)

        removeAllViewsInLayout()
        val dirs = tempPath.split("/".toRegex()).dropLastWhile(String::isEmpty).toTypedArray()
        for (i in dirs.indices) {
            val dir = dirs[i]
            if (i > 0) {
                currPath += dir + "/"
            }

            if (dir.isEmpty())
                continue

            if (!currPath.endsWith('/'))
                currPath += "/"

            val item = FileDirItem(currPath, dir, true, 0, 0)
            addBreadcrumb(item, i > 0)
        }
    }

    private fun addBreadcrumb(item: FileDirItem, addPrefix: Boolean) {
        mInflater.inflate(R.layout.breadcrumb_item, null, false).apply {
            var textToAdd = item.name
            if (addPrefix)
                textToAdd = "/ $textToAdd"

            if (childCount == 0) {
                resources.apply {
                    background = getDrawable(R.drawable.breadcrumb_gradient)
                    background.colorFilter = PorterDuffColorFilter(mTextColor, PorterDuff.Mode.SRC_IN)
                    val medium = getDimension(R.dimen.medium_margin).toInt()
                    setPadding(medium, medium, medium, medium)
                }
            }

            breadcrumb_text.text = textToAdd
            breadcrumb_text.setTextColor(mTextColor)
            addView(this)
            setOnClickListener(this@Breadcrumbs)

            tag = item
        }
    }

    fun removeBreadcrumb() {
        removeView(getChildAt(childCount - 1))
    }

    val lastItem: FileDirItem get() = getChildAt(childCount - 1).tag as FileDirItem

    override fun onClick(v: View) {
        val cnt = childCount
        for (i in 0..cnt - 1) {
            if (getChildAt(i) != null && getChildAt(i) == v) {
                mListener?.breadcrumbClicked(i)
            }
        }
    }

    interface BreadcrumbsListener {
        fun breadcrumbClicked(id: Int)
    }
}
