package com.foxx.androidcast;

/*********************************************************************
 * PlatformCastSupport.java
 * Created at: Fri 15 May 2026 16:49:02 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * class PlatformCastSupport
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (5 commits, 103 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	437f440f8e8e0b7da97a9af34bdb2977ccf1493541ca31bd33634cd45db53273
**********************************************************************/
import android.os.Build;
import android.widget.CheckBox;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

/** Platform capabilities for cast (audio requires Android 10 / API 29+). */
public final class PlatformCastSupport {
    private PlatformCastSupport() {}

    public static boolean isAudioCaptureSupported() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
    }

    /** Per-app / window picker for MediaProjection (Android 14+). */
    public static boolean isCaptureUserChoiceSupported() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
    }

    public static CastSettings.CaptureMode defaultCaptureMode() {
        return isCaptureUserChoiceSupported()
                ? CastSettings.CaptureMode.USER_CHOICE
                : CastSettings.CaptureMode.FULL_SCREEN;
    }

    /**
     * Camera2 as a video source is separate from MediaProjection (app picker cannot select camera only).
     */
    public static boolean isCameraCaptureModeSupported() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
    }

    public static boolean hasFrontCamera(android.content.Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            return false;
        }
        try {
            android.hardware.camera2.CameraManager mgr =
                    context.getSystemService(android.hardware.camera2.CameraManager.class);
            if (mgr == null) {
                return false;
            }
            for (String id : mgr.getCameraIdList()) {
                android.hardware.camera2.CameraCharacteristics chars = mgr.getCameraCharacteristics(id);
                Integer facing = chars.get(android.hardware.camera2.CameraCharacteristics.LENS_FACING);
                if (facing != null
                        && facing == android.hardware.camera2.CameraCharacteristics.LENS_FACING_FRONT) {
                    return true;
                }
            }
        } catch (Exception ignored) {
        }
        return false;
    }

    /** Applies default audio flag: on for Android 10+, off otherwise. */
    public static void applyDefaultAudioSetting(CastSettings settings) {
        settings.setAudioEnabled(isAudioCaptureSupported());
    }

    /** Disables audio UI and forces video-only when capture is unavailable. */
    public static void bindAudioCheckbox(AppCompatActivity activity, CheckBox audio, CastSettings settings) {
        applyDefaultAudioSetting(settings);
        if (isAudioCaptureSupported()) {
            audio.setEnabled(true);
            audio.setText(R.string.label_audio);
            audio.setChecked(settings.isAudioEnabled());
            audio.setOnCheckedChangeListener((btn, checked) -> settings.setAudioEnabled(checked));
        } else {
            settings.setAudioEnabled(false);
            audio.setEnabled(false);
            audio.setChecked(false);
            audio.setText(R.string.label_audio_unavailable);
        }
    }

    /**
     * If audio is unavailable, warns the user and runs {@code onContinue} only when they accept video-only.
     * On Android 10+, runs {@code onContinue} immediately.
     */
    public static void runWithAudioPolicy(AppCompatActivity activity, CastSettings settings, Runnable onContinue) {
        if (isAudioCaptureSupported()) {
            onContinue.run();
            return;
        }
        settings.setAudioEnabled(false);
        new AlertDialog.Builder(activity)
                .setTitle(R.string.audio_unavailable_title)
                .setMessage(R.string.audio_unavailable_message)
                .setPositiveButton(R.string.continue_video_only, (d, w) -> onContinue.run())
                .setNegativeButton(android.R.string.cancel, null)
                .show();
    }
}
