/*
 * DSBDirect
 * Copyright (C) 2020 Fynn Godau
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * This software is not affiliated with heinekingmedia GmbH, the
 * developer of the DSB platform.
 */
package godau.fynn.dsbdirect.table

import android.app.Activity
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ListView
import android.widget.TextView
import androidx.cardview.widget.CardView
import godau.fynn.dsbdirect.R
import godau.fynn.dsbdirect.Utility
import godau.fynn.dsbdirect.table.entry.Entry
import org.sufficientlysecure.htmltextview.HtmlTextView
import java.util.*

class Adapter(activity: Activity, private val values: ArrayList<Entry>) :
        ArrayAdapter<Entry?>(activity, R.layout.row_list, values as List<Entry?>) {

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {

        val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

        val entry = values[position]

        val u = Utility(context)

        // Which layout should be loaded?
        val layout = u.sharedPreferences.getString("layout", LAYOUT_CARDS)

        // Recycle convertView or inflate new layout
        val rowView = convertView
                ?: when (layout) {
                    LAYOUT_LIST -> inflater.inflate(R.layout.row_list, parent, false)
                    LAYOUT_CARDS_REVERSED -> inflater.inflate(R.layout.row_card_reversed, parent, false)
                    LAYOUT_CARDS -> inflater.inflate(R.layout.row_card, parent, false)
                    else -> inflater.inflate(R.layout.row_card, parent, false)
                }

        // Populate fields
        val concatenatedEntry = entry.compatEntry
        fillField(concatenatedEntry.affectedClass, rowView.findViewById(R.id.affectedClass))
        fillField(concatenatedEntry.lesson, rowView.findViewById(R.id.lesson))
        fillField(concatenatedEntry.replacementTeacher, rowView.findViewById(R.id.replacementTeacher))
        fillField(concatenatedEntry.info, rowView.findViewById(R.id.info))

        // Layout-specific code
        if (layout == LAYOUT_CARDS || layout == LAYOUT_CARDS_REVERSED) {

            // Remove divider from parent view
            (parent as ListView).apply {
                divider = null
                dividerHeight = 0
            }

            // Highlight or un-highlight card
            val backgroundColor = if (entry.isHighlighted) u.colorAccent else u.colorPrimary

            rowView.findViewById<CardView>(R.id.card).setCardBackgroundColor(backgroundColor)

        } else {
            // Highlighting code for list
            val color = if (entry.isHighlighted) u.colorAccent else context.resources.getColor(R.color.textOverWhite)
            rowView.findViewById<HtmlTextView>(R.id.affectedClass).setTextColor(color)
            rowView.findViewById<HtmlTextView>(R.id.lesson).setTextColor(color)
            rowView.findViewById<HtmlTextView>(R.id.replacementTeacher).setTextColor(color)
            rowView.findViewById<HtmlTextView>(R.id.info).setTextColor(color)
        }

        val dateView = rowView.findViewById<TextView>(R.id.date)
        try {
            if (position != 0 && values[position - 1].date != entry.date) {
                val date = u.formatDate(entry.date)
                dateView.apply {
                    text = date
                    visibility = View.VISIBLE
                }
            } else
                dateView.visibility = View.GONE

        } catch (e: NullPointerException) {
            e.printStackTrace() // Bad parser
        }
        return rowView
    }

    private fun fillField(s: String?, v: HtmlTextView) {
        if (s != null && !s.isEmpty()) {
            v.visibility = View.VISIBLE
            v.setHtml(s)
        } else {
            v.visibility = View.GONE
        }
    }

    fun addAll(collection: ArrayList<Entry>) {
        values.addAll(collection)
        notifyDataSetChanged()
    }

    fun size(): Int {
        return values.size
    }

    operator fun get(index: Int): Entry {
        return values[index]
    }

    companion object {
        const val LAYOUT_LIST = "list"
        const val LAYOUT_CARDS = "cards"
        const val LAYOUT_CARDS_REVERSED = "cards reversed"
    }

}