package com.quillstudios.pokegoalshelper import android.content.Context import android.graphics.* import android.util.Log import android.view.* import android.widget.TextView import kotlin.math.min class DetectionOverlay(private val context: Context) { companion object { private const val TAG = "DetectionOverlay" } private var windowManager: WindowManager? = null private var overlayView: View? = null private var isShowing = false init { windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager } fun showOverlay(regions: Map) { try { Log.i(TAG, "🎨 showOverlay called with ${regions.size} regions") // Check overlay permission first if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { if (!android.provider.Settings.canDrawOverlays(context)) { Log.e(TAG, "❌ OVERLAY PERMISSION NOT GRANTED! Cannot show overlay.") return } else { Log.i(TAG, "✅ Overlay permission granted") } } if (isShowing) { Log.i(TAG, "🔄 Hiding existing overlay first") hideOverlay() } Log.i(TAG, "🎨 Creating overlay view...") val overlayLayout = OverlayView(context, regions) val layoutParams = WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, PixelFormat.TRANSLUCENT ) layoutParams.gravity = Gravity.TOP or Gravity.START layoutParams.x = 0 layoutParams.y = 0 Log.i(TAG, "🎨 Adding view to WindowManager...") windowManager?.addView(overlayLayout, layoutParams) overlayView = overlayLayout isShowing = true Log.i(TAG, "✅ Detection overlay shown successfully with ${regions.size} regions") // No auto-hide - overlay stays until manually hidden or new detections } catch (e: Exception) { Log.e(TAG, "❌ Error showing overlay", e) } } fun hideOverlay() { try { if (isShowing && overlayView != null) { windowManager?.removeView(overlayView) overlayView = null isShowing = false Log.d(TAG, "Detection overlay hidden") } } catch (e: Exception) { Log.e(TAG, "Error hiding overlay", e) } } private class OverlayView(context: Context, private val regions: Map) : View(context) { private val rectPaint = Paint().apply { color = Color.RED style = Paint.Style.STROKE strokeWidth = 4f alpha = 200 } private val fillPaint = Paint().apply { color = Color.RED style = Paint.Style.FILL alpha = 50 } private val textPaint = Paint().apply { color = Color.WHITE textSize = 32f isAntiAlias = true style = Paint.Style.FILL setShadowLayer(4f, 2f, 2f, Color.BLACK) } private val backgroundPaint = Paint().apply { color = Color.BLACK style = Paint.Style.FILL alpha = 150 } private val colors = listOf( Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.MAGENTA, Color.CYAN, Color.parseColor("#FFA500"), Color.parseColor("#FF6B35"), Color.parseColor("#7209B7"), Color.parseColor("#2F9599"), Color.parseColor("#F18F01"), Color.parseColor("#C73E1D") ) override fun onDraw(canvas: Canvas) { super.onDraw(canvas) val displayMetrics = context.resources.displayMetrics val screenWidth = displayMetrics.widthPixels val screenHeight = displayMetrics.heightPixels Log.i(TAG, "🎨 Drawing overlay on ${screenWidth}x${screenHeight} screen with ${regions.size} regions") var colorIndex = 0 for ((name, region) in regions) { try { // Use different colors for each region val color = colors[colorIndex % colors.size] colorIndex++ rectPaint.color = color fillPaint.color = color fillPaint.alpha = 30 // Draw filled rectangle canvas.drawRect( region.x.toFloat(), region.y.toFloat(), (region.x + region.width).toFloat(), (region.y + region.height).toFloat(), fillPaint ) // Draw border canvas.drawRect( region.x.toFloat(), region.y.toFloat(), (region.x + region.width).toFloat(), (region.y + region.height).toFloat(), rectPaint ) // Draw label above the box val labelText = formatRegionLabel(name, region) val textX = region.x.toFloat() + 8f // Calculate text background size val textBounds = Rect() textPaint.getTextBounds(labelText, 0, labelText.length, textBounds) val textWidth = textBounds.width() + 16f val textHeight = textBounds.height() + 16f // Position text above the region box val textY = region.y.toFloat() - 8f val backgroundTop = textY - textHeight + 8f val backgroundBottom = textY + 8f // Draw text background above the box canvas.drawRect( textX - 8f, backgroundTop, textX + textWidth, backgroundBottom, backgroundPaint ) // Draw text above the box canvas.drawText(labelText, textX, textY, textPaint) } catch (e: Exception) { Log.e(TAG, "Error drawing region $name", e) } } // Draw title at top /* val titleText = "Pokemon Detection Zones (${regions.size} regions)" val titleX = 20f val titleY = 80f val titleBounds = Rect() val titlePaint = Paint().apply { color = Color.WHITE textSize = 48f isAntiAlias = true style = Paint.Style.FILL setShadowLayer(4f, 2f, 2f, Color.BLACK) } titlePaint.getTextBounds(titleText, 0, titleText.length, titleBounds) // Draw title background canvas.drawRect( titleX - 16f, titleY - titleBounds.height() - 16f, titleX + titleBounds.width() + 32f, titleY + 16f, backgroundPaint ) // Draw title canvas.drawText(titleText, titleX, titleY, titlePaint) */ } fun formatRegionLabel(name: String, region: ScreenRegion): String { val shortName = when (name) { "nickname" -> "NICKNAME" "level" -> "LEVEL" "species" -> "SPECIES" "types" -> "TYPES" "stats" -> "STATS" "moves" -> "MOVES" "nature" -> "NATURE" "ability" -> "ABILITY" "ot_name" -> "OT NAME" "ot_id" -> "OT ID" "gender" -> "GENDER" "pokeball" -> "POKEBALL" "favorite" -> "FAVORITE" "stamps" -> "STAMPS" "labels" -> "LABELS" "marks" -> "MARKS" "game_source" -> "GAME SOURCE" else -> name.uppercase() } return "$shortName\n${region.width}x${region.height}" } } }