package mx.trackermap.TrackerMap.android.shared import android.content.Context import android.graphics.Color import android.util.TypedValue import android.view.Gravity import android.view.View import android.widget.Button import android.widget.GridLayout import android.widget.ImageView import android.widget.TextView import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import com.zerobranch.layout.SwipeLayout import kotlinx.serialization.json.longOrNull import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.client.models.UnitInformation import mx.trackermap.TrackerMap.utils.Formatter import mx.trackermap.TrackerMap.utils.SpeedUnit typealias ActionCallback = (unit: UnitInformation, action: UnitRenderData.Action) -> Unit class UnitRenderData { data class UnitRenderViewHolder( val unitName: TextView, val unitIcon: ImageView? = null, val statusIcon: ImageView, val engineStopIcon: ImageView, val gridLayout: GridLayout, val detailsButton: Button? = null, val reportsButton: Button? = null, val commandsButton: Button? = null, val unitCard: CardView? = null, val swipeLayout: SwipeLayout? = null ) enum class Action { CLICK, DETAILS, REPORTS, COMMANDS } companion object { fun render( viewHolder: UnitRenderViewHolder, context: Context, unit: UnitInformation, actionCallback: ActionCallback? ) { viewHolder.apply { val details: MutableList> = mutableListOf() /* Device name */ unitName.text = unit.device.name /* Device icon */ unitIcon?.setImageResource( MarkerTransformations.categoryToResourceId(unit.device.category) ) unitIcon?.contentDescription = context.getString( MarkerTransformations.categoryToStringId(unit.device.category) ) /* Contact */ unit.device.contact?.let { contact -> if (contact.isNotEmpty()) { details.add( Triple( R.drawable.device_contact, contact, context.getString(R.string.unit_driver_name) ) ) } } statusIcon.visibility = View.GONE engineStopIcon.visibility = View.GONE unit.position?.let { position -> /* Status icon */ statusIcon.visibility = View.VISIBLE position.speed?.let { speed -> if (speed >= 2) { statusIcon.setColorFilter( ContextCompat.getColor(context, R.color.colorOnline) ) } else { statusIcon.setColorFilter( ContextCompat.getColor(context, R.color.colorOffline) ) } } ?: run { statusIcon.setColorFilter(Color.GRAY) } /* Engine stop */ val attributes = position.attributes if (attributes["out1"].toString() != "null") { engineStopIcon.visibility = View.VISIBLE engineStopIcon.setImageResource( when (attributes["out1"].toString()) { "true" -> R.drawable.device_unlocked "false" -> R.drawable.device_locked else -> R.drawable.device_locked } ) engineStopIcon.contentDescription = when (attributes["out1"].toString()) { "true" -> context.getString(R.string.unit_lock_on) "false" -> context.getString(R.string.unit_lock_off) else -> context.getString(R.string.unit_lock_on) } } /* Speed */ position.speed?.let { speed -> details.add( Triple( R.drawable.position_speed, Formatter.formatSpeed(speed, SpeedUnit.KMH), context.getString(R.string.unit_speed) ) ) } /* Address */ position.address?.let { address -> details.add( Triple( R.drawable.position_address, address, context.getString(R.string.unit_last_address) ) ) } /* Hourmeter */ position.attributes["hours"]?.longOrNull?.let { if (it > 0) { details.add( Triple( R.drawable.position_hourmeter, Formatter.formatHours(it), context.getString(R.string.unit_hourmeter) ) ) } } /* Date time */ position.fixTime?.let { fixTime -> details.add( Triple( R.drawable.position_datetime, Formatter.formatDate(fixTime), context.getString(R.string.unit_last_date) ) ) } } gridLayout.removeAllViewsInLayout() val metrics = context.resources.displayMetrics details.forEachIndexed { i, detail -> /* Property icon */ val imageView = ImageView(gridLayout.context) imageView.setImageResource(detail.first) imageView.contentDescription = detail.third imageView.setColorFilter( ContextCompat.getColor( context, androidx.appcompat.R.color.secondary_text_default_material_light ) ) val imageLayout = GridLayout.LayoutParams() imageLayout.width = GridLayout.LayoutParams.WRAP_CONTENT imageLayout.height = GridLayout.LayoutParams.WRAP_CONTENT imageLayout.marginEnd = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 6f, metrics).toInt() imageLayout.rowSpec = GridLayout.spec(i) imageLayout.columnSpec = GridLayout.spec(0) imageView.layoutParams = imageLayout /* Property text */ val textView = TextView(gridLayout.context) textView.text = detail.second val textLayout = GridLayout.LayoutParams() textLayout.width = 0 textLayout.height = GridLayout.LayoutParams.MATCH_PARENT textLayout.rowSpec = GridLayout.spec(i) textLayout.columnSpec = GridLayout.spec(1, 1, 5f) textView.layoutParams = textLayout gridLayout.addView(imageView) gridLayout.addView(textView) imageLayout.setGravity(Gravity.CENTER) } actionCallback?.let { callback -> unitCard?.setOnClickListener { swipeLayout?.close() callback(unit, Action.CLICK) } detailsButton?.setOnClickListener { swipeLayout?.close() callback(unit, Action.DETAILS) } reportsButton?.setOnClickListener { swipeLayout?.close() callback(unit, Action.REPORTS) } commandsButton?.setOnClickListener { swipeLayout?.close() callback(unit, Action.COMMANDS) } } } } } }