# JournalTableCellView.kt

    /*
     * The MIT License
     *
     * Original work sponsored and donated by The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
     *
     * Copyright (C) 2021 The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
     *
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of
     * this software and associated documentation files (the "Software"), to deal in
     * the Software without restriction, including without limitation the rights to
     * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
     * of the Software, and to permit persons to whom the Software is furnished to do
     * so, subject to the following conditions:
     *
     *
     * The above copyright notice and this permission notice shall be included in all
     * copies or substantial portions of the Software.
     *
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     * SOFTWARE.
     */

    package dk.nsp.mingraviditet.ui.main.journal.sections.measurements.table.ui

    import android.content.Context
    import android.graphics.Typeface
    import android.util.AttributeSet
    import android.util.TypedValue
    import android.view.Gravity
    import androidx.appcompat.widget.AppCompatTextView
    import dk.nsp.mingraviditet.R
    import dk.nsp.mingraviditet.ui.main.journal.sections.measurements.table.models.common.DataTableCellType
    import dk.nsp.mingraviditet.ui.main.journal.sections.measurements.table.models.common.JournalTableCellData
    import dk.nsp.mingraviditet.util.extensions.bindingadapters.setTextModel
    import dk.nsp.mingraviditet.util.extensions.getColorFromAttr

    class JournalTableCellView @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
    ) : AppCompatTextView(context, attrs, defStyleAttr) {

        private var updatedHeightFromParent: Int? = null
            set(value) {
                field = value
                value?.let {
                    layoutParams.height = it
                }
            }

        //region Cell background colors
        private val cellColor by lazy {
            context.getColorFromAttr(R.attr.journalTableCellColor)
        }

        private val cellColorAlternate by lazy {
            context.getColorFromAttr(R.attr.journalTableCellColorAlternate)
        }

        //region Cell text colors
        private val normalTextColor by lazy {
            context.getColorFromAttr(R.attr.mgTextColor)
        }
        private val dictionaryColor by lazy {
            context.getColorFromAttr(R.attr.colorSecondary)
        }
        private val clickableTextColor by lazy {
            context.getColorFromAttr(R.attr.textButtonColor)
        }
        //endregion

        private var cellVerticalIndex = -1

        init {
            minHeight = resources.getDimensionPixelSize(R.dimen.journal_table_cell_min_height)

            setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.body_text_size))

            gravity = Gravity.START + Gravity.CENTER

            val padding = resources.getDimensionPixelSize(R.dimen.large_spacing)
            setPadding(padding, padding, padding, padding)
        }

        fun setData(
            cellIndex: Int,
            data: JournalTableCellData,
            registerForSizeChanges: (Int, JournalTableCellView) -> Unit
        ) {
            this.cellVerticalIndex = cellIndex
            setTextModel(data.value)

            val cellType = data.type

            updateTextPropertiesFor(cellType)
            updateOnClickFor(cellType)
            updateBackgroundColorFor(cellVerticalIndex)
            updateOnClickFor(cellType)

            post {
                registerForSizeChanges(this.cellVerticalIndex, this)
            }
        }

        fun updateHeight(newHeight: Int) {
            if (updatedHeightFromParent != null && newHeight <= height) {
                return
            }
            updatedHeightFromParent = newHeight
            requestLayout()
        }

        //region Property udpates
        private fun updateTextPropertiesFor(type: DataTableCellType) {
            val textColor = when (type) {
                is DataTableCellType.Text,
                is DataTableCellType.BoldText -> normalTextColor
                is DataTableCellType.Dictionary -> dictionaryColor
                is DataTableCellType.PrimaryButton -> clickableTextColor
            }

            setTextColor(textColor)

            if (type != DataTableCellType.Text) {
                setTypeface(typeface, Typeface.BOLD)
            }
        }

        private fun updateOnClickFor(type: DataTableCellType) {
            val onClick = when (type) {
                is DataTableCellType.Dictionary -> type.callback
                is DataTableCellType.PrimaryButton -> type.callback
                DataTableCellType.BoldText,
                DataTableCellType.Text -> null
            }

            setOnClickListener { onClick?.invoke() }
        }

        private fun updateBackgroundColorFor(index: Int) {
            // Different color for every other cell
            when (index % 2) {
                0 -> cellColor
                1 -> cellColorAlternate
                else -> null
            }?.let {
                setBackgroundColor(it)
            }
        }
        //endregion
    }