package com.foxx.androidcast.receiver.av;

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.view.Surface;

import com.foxx.androidcast.AppPreferences;

/** Routes decoder output through GLES when an experimental video preset is active. */
public final class ReceiverVideoGlHub {
    private static final Object LOCK = new Object();
    private static ReceiverVideoGlRenderer renderer;

    private ReceiverVideoGlHub() {}

    public static boolean isGlMode(Context context) {
        ReceiverVideoPreset p = AppPreferences.getReceiverVideoPreset(context);
        return p == ReceiverVideoPreset.IMMERSIVE || p == ReceiverVideoPreset.HDR;
    }

    /** @return Surface for {@code MediaCodec} / libvpx (decoder input). */
    public static Surface bindDisplay(Context context, SurfaceTexture display, int width, int height) {
        synchronized (LOCK) {
            if (!isGlMode(context)) {
                releaseLocked();
                return new Surface(display);
            }
            if (renderer == null) {
                renderer = new ReceiverVideoGlRenderer();
            }
            renderer.setPreset(
                    AppPreferences.getReceiverVideoPreset(context),
                    AppPreferences.getReceiverAvIntensity(context));
            return renderer.bindDisplay(display, width, height);
        }
    }

    public static void refreshPreset(Context context) {
        synchronized (LOCK) {
            if (renderer != null && isGlMode(context)) {
                renderer.setPreset(
                        AppPreferences.getReceiverVideoPreset(context),
                        AppPreferences.getReceiverAvIntensity(context));
            }
        }
    }

    public static void onFrameDecoded(Context context) {
        synchronized (LOCK) {
            if (renderer != null && isGlMode(context)) {
                renderer.onDecoderFrameAvailable();
            }
        }
    }

    public static void release(Context context) {
        synchronized (LOCK) {
            releaseLocked();
        }
    }

    private static void releaseLocked() {
        if (renderer != null) {
            renderer.release();
            renderer = null;
        }
    }
}
