package com.foxx.androidcast.sender.calibration;

/*********************************************************************
 * CalibrationSourceDimensions.java
 * Created at: Sun 17 May 2026 15:45:19 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * class CalibrationSourceDimensions
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (2 commits, 68 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	57257f30c63b96dc5078835ccd9c7cc6992e70ca6181fdfb872fdd17f53f0750
**********************************************************************/
import android.content.Context;
import android.graphics.BitmapFactory;

import com.foxx.androidcast.CastConfig;
import com.foxx.androidcast.CastResolution;
import com.foxx.androidcast.R;

/**
 * Encoder size for calibration mode — derived from the chart asset (or procedural fallback),
 * not a fixed resolution.
 */
public final class CalibrationSourceDimensions {
    private static final int PROCEDURAL_FALLBACK_W = 500;
    private static final int PROCEDURAL_FALLBACK_H = 400;

    private CalibrationSourceDimensions() {}

    public static CastResolution.Size resolve(Context context) {
        int w = PROCEDURAL_FALLBACK_W;
        int h = PROCEDURAL_FALLBACK_H;
        if (context != null) {
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true;
            BitmapFactory.decodeResource(
                    context.getApplicationContext().getResources(),
                    R.drawable.calibration_chart_reference,
                    opts);
            if (opts.outWidth > 0 && opts.outHeight > 0) {
                w = opts.outWidth;
                h = opts.outHeight;
            }
        }
        int[] capped = capLongEdge(even(w), even(h), CastConfig.CALIBRATION_MAX_LONG_EDGE);
        return new CastResolution.Size(capped[0], capped[1], 240);
    }

    /** Visible for unit tests without Android resources. */
    public static CastResolution.Size fromIntrinsic(int width, int height, int maxLongEdge) {
        int[] capped = capLongEdge(even(width), even(height), maxLongEdge);
        return new CastResolution.Size(capped[0], capped[1], 240);
    }

    private static int[] capLongEdge(int width, int height, int maxLong) {
        if (maxLong <= 0) {
            return new int[] {width, height};
        }
        int longEdge = Math.max(width, height);
        if (longEdge <= maxLong) {
            return new int[] {width, height};
        }
        float ratio = (float) maxLong / longEdge;
        return new int[] {even(Math.max(2, (int) (width * ratio))),
                even(Math.max(2, (int) (height * ratio)))};
    }

    private static int even(int v) {
        return Math.max(2, v & ~1);
    }
}
