package com.sybotan.android.demo.tree

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ListView


abstract class BaseTreeAdapter<T : Any>(
    data: List<T>,
    context: Context,
    listView: ListView,
    private var nodes: List<Node<T>> = TreeHelper.getTreeNodes(data),
    private var visibleNodes: List<Node<T>> = TreeHelper.filterVisibleNodes(nodes)
) : BaseAdapter() {
    protected val mInflater: LayoutInflater = LayoutInflater.from(context)
    private var onTreeNodeClickListener: OnTreeNodeClickListener<T>? = null

    init {
        listView.setOnItemClickListener { parent, view, position, id ->
            expandOrCollapse(position)
            onTreeNodeClickListener?.onClick(visibleNodes[position], position);
        }
    }

    interface OnTreeNodeClickListener<T> {
        fun onClick(node: Node<T>, position: Int)
    }

    fun setOnTreeNodeClickListener(onTreeNodeClickListener: OnTreeNodeClickListener<T>) {
        this.onTreeNodeClickListener = onTreeNodeClickListener
    }

    open fun expandOrCollapse(position: Int) {
        val n = visibleNodes[position]
        if (n.isLeaf) return
        n.isExpand = !n.isExpand
        visibleNodes = TreeHelper.filterVisibleNodes(nodes)
        notifyDataSetChanged()
    }

    override fun getCount(): Int {
        return visibleNodes.size
    }

    override fun getItem(position: Int): Any {
        return visibleNodes[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val node = visibleNodes[position]
        val holder =
            getConvertView(
                node,
                position,
                convertView,
                parent
            )
        holder.setPadding(node.level * 48, 3, 3, 3)
        return holder
    }

    abstract fun getConvertView(
        node: Node<T>,
        position: Int,
        convertView: View?,
        parent: ViewGroup?
    ): View
}


